6 #include "Eigen/Sparse" 8 #include "lsst/log/Log.h" 9 #include "lsst/pex/exceptions.h" 17 static double sqr(
double x) {
return x * x; }
20 LOG_LOGGER _log = LOG_GET(
"jointcal.PhotometryFit");
33 void PhotometryFit::leastSquareDerivativesMeasurement(CcdImage
const &
ccdImage, TripletList &tripletList,
34 Eigen::VectorXd &grad,
35 MeasuredStarList
const *measuredStarList)
const {
44 if (measuredStarList) assert(&(measuredStarList->front()->getCcdImage()) == &ccdImage);
46 auto const &mapping = _photometryModel->getMapping(ccdImage);
48 unsigned nparModel = (_fittingModel) ? mapping.getNpar() : 0;
49 unsigned nparFlux = (_fittingFluxes) ? 1 : 0;
50 unsigned nparTotal = nparModel + nparFlux;
51 std::vector<unsigned> indices(nparModel, -1);
53 Eigen::VectorXd H(nparTotal);
55 unsigned kTriplets = tripletList.getNextFreeIndex();
56 const MeasuredStarList &catalog = (measuredStarList) ? *measuredStarList : ccdImage.getCatalogForFit();
58 for (
auto const &measuredStar : catalog) {
59 if (!measuredStar->
isValid())
continue;
63 TweakPhotomMeasurementErrors(inPos, *measuredStar, _fluxError);
66 double photomFactor = _photometryModel->photomFactor(ccdImage, *measuredStar);
69 double residual = computeMeasurementResidual(photomFactor, *measuredStar);
71 double inverseSigma = 1.0 / (photomFactor * fluxErr);
72 double W = sqr(inverseSigma);
75 _photometryModel->getMappingIndices(ccdImage, indices);
76 _photometryModel->computeParameterDerivatives(*measuredStar, ccdImage, H);
77 for (
unsigned k = 0; k < indices.size(); k++) {
78 unsigned l = indices[k];
79 tripletList.addTriplet(l, kTriplets, H[k] * inverseSigma);
80 grad[l] += H[k] * W * residual;
84 unsigned index = measuredStar->
getFittedStar()->getIndexInMatrix();
86 tripletList.addTriplet(index, kTriplets, -1.0 * inverseSigma);
87 grad[index] += -1.0 * W * residual;
92 tripletList.setNextFreeIndex(kTriplets);
95 void PhotometryFit::leastSquareDerivativesReference(FittedStarList
const &fittedStarList,
96 TripletList &tripletList, Eigen::VectorXd &grad)
const {
103 if (!_fittingFluxes)
return;
107 unsigned kTriplets = tripletList.getNextFreeIndex();
109 for (
auto const &fittedStar : fittedStarList) {
110 auto refStar = fittedStar->getRefStar();
111 if (refStar ==
nullptr)
continue;
118 double inverseSigma = 1.0 / refStar->getFluxErr();
120 double residual = fittedStar->getFlux() - refStar->getFlux();
122 unsigned index = fittedStar->getIndexInMatrix();
124 tripletList.addTriplet(index, kTriplets, 1.0 * inverseSigma);
125 grad(index) += 1.0 * sqr(inverseSigma) * residual;
128 tripletList.setNextFreeIndex(kTriplets);
131 void PhotometryFit::accumulateStatImageList(
CcdImageList const &ccdImageList, Chi2Accumulator &accum)
const {
136 for (
auto const &ccdImage : ccdImageList) {
137 auto &catalog = ccdImage->getCatalogForFit();
139 for (
auto const &measuredStar : catalog) {
140 if (!measuredStar->
isValid())
continue;
141 double photomFactor = _photometryModel->photomFactor(*ccdImage, *measuredStar);
143 double sigma = (measuredStar->
getFluxErr() * photomFactor);
145 TweakPhotomMeasurementErrors(inPos, measuredStar, _fluxError);
147 double residual = computeMeasurementResidual(photomFactor, *measuredStar);
149 double chi2Val = sqr(residual / sigma);
150 accum.addEntry(chi2Val, 1, measuredStar);
155 void PhotometryFit::accumulateStatRefStars(Chi2Accumulator &accum)
const {
161 FittedStarList &fittedStarList =
_associations->fittedStarList;
162 for (
auto const &fittedStar : fittedStarList) {
163 auto refStar = fittedStar->getRefStar();
164 if (refStar ==
nullptr)
continue;
165 double chi2 = sqr(((fittedStar->getFlux() - refStar->getFlux()) / refStar->getFluxErr()));
166 accum.addEntry(chi2, 1, fittedStar);
173 void PhotometryFit::getIndicesOfMeasuredStar(MeasuredStar
const &measuredStar,
174 std::vector<unsigned> &indices)
const {
177 _photometryModel->getMappingIndices(measuredStar.getCcdImage(), indices);
179 if (_fittingFluxes) {
180 auto fs = measuredStar.getFittedStar();
181 unsigned fsIndex = fs->getIndexInMatrix();
182 indices.push_back(fsIndex);
188 LOGLS_INFO(_log,
"assignIndices: now fitting: " << whatToFit);
189 _fittingModel = (
_whatToFit.find(
"Model") != std::string::npos);
190 _fittingFluxes = (
_whatToFit.find(
"Fluxes") != std::string::npos);
193 _nParModel = (_fittingModel) ? _photometryModel->assignIndices(whatToFit, 0) : 0;
194 unsigned ipar = _nParModel;
196 if (_fittingFluxes) {
202 fittedStar->setIndexInMatrix(ipar);
206 _nParFluxes = ipar - _nParModel;
209 "nParameters total: " <<
_nParTot <<
" model: " << _nParModel <<
" fluxes: " << _nParFluxes);
214 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
215 "PhotometryFit::offsetParams : the provided vector length is not compatible with " 216 "the current whatToFit setting");
217 if (_fittingModel) _photometryModel->offsetParams(delta);
219 if (_fittingFluxes) {
224 unsigned index = fittedStar->getIndexInMatrix();
225 fittedStar->getFlux() -= delta(index);
231 std::ofstream tuple(tupleName.c_str());
236 tuple <<
"#xccd: coordinate in CCD" << std::endl
237 <<
"#yccd: " << std::endl
238 <<
"#mag: rough mag" << std::endl
239 <<
"#flux : measured flux" << std::endl
240 <<
"#fluxError : measured flux error" << std::endl
241 <<
"#fflux : fitted flux" << std::endl
242 <<
"#phot_factor:" << std::endl
243 <<
"#jd: Julian date of the measurement" << std::endl
244 <<
"#color : " << std::endl
245 <<
"#fsindex: some unique index of the object" << std::endl
246 <<
"#ra: pos of fitted star" << std::endl
247 <<
"#dec: pos of fitted star" << std::endl
248 <<
"#chi2: contribution to Chi2 (1 dof)" << std::endl
249 <<
"#nm: number of measurements of this FittedStar" << std::endl
250 <<
"#chip: chip number" << std::endl
251 <<
"#visit: visit id" << std::endl
252 <<
"#end" << std::endl;
254 for (
auto const &i : ccdImageList) {
257 for (
auto const &is : cat) {
262 tweakPhotomMeasurementErrors(inPos, ms, _fluxError);
264 double photomFactor = _photometryModel->photomFactor(im, ms);
267 double residual = ms.
getFlux() - photomFactor * fs->getFlux();
268 double chi2Val = sqr(residual / sigma);
269 tuple << ms.
x <<
' ' << ms.
y <<
' ' << fs->getMag() <<
' ' << ms.
getFlux() <<
' ' 270 << ms.
getFluxErr() <<
' ' << fs->getFlux() <<
' ' << photomFactor <<
' ' << jd <<
' ' 271 << fs->color <<
' ' << fs->getIndexInMatrix() <<
' ' << fs->x <<
' ' << fs->y <<
' ' 272 << chi2Val <<
' ' << fs->getMeasurementCount() <<
' ' << im.
getCcdId() <<
' ' int getCcdId() const
returns ccd ID
VisitIdType getVisit() const
returns visit ID
double getMjd() const
Julian Date.
double getFluxErr() const
A list of MeasuredStar. They are usually filled in Associations::AddImage.
void offsetParams(Eigen::VectorXd const &delta) override
Offset the parameters by the requested quantities.
Class for a simple mapping implementing a generic Gtransfo.
void saveResultTuples(std::string const &tupleName) const override
Save the full chi2 term per star that was used in the minimization, for debugging.
objects measured on actual images.
std::shared_ptr< Associations > _associations
void assignIndices(std::string const &whatToFit) override
Set parameters to fit and assign indices in the big matrix.
std::shared_ptr< const FittedStar > getFittedStar() const
MeasuredStarList const & getCatalogForFit() const
Gets the catalog to be used for fitting, which may have been cleaned-up.
std::list< std::shared_ptr< CcdImage > > CcdImageList
Handler of an actual image from a single CCD.
bool isValid() const
Fits may use that to discard outliers.