LSST Applications g0b6bd0c080+a72a5dd7e6,g1182afd7b4+2a019aa3bb,g17e5ecfddb+2b8207f7de,g1d67935e3f+06cf436103,g38293774b4+ac198e9f13,g396055baef+6a2097e274,g3b44f30a73+6611e0205b,g480783c3b1+98f8679e14,g48ccf36440+89c08d0516,g4b93dc025c+98f8679e14,g5c4744a4d9+a302e8c7f0,g613e996a0d+e1c447f2e0,g6c8d09e9e7+25247a063c,g7271f0639c+98f8679e14,g7a9cd813b8+124095ede6,g9d27549199+a302e8c7f0,ga1cf026fa3+ac198e9f13,ga32aa97882+7403ac30ac,ga786bb30fb+7a139211af,gaa63f70f4e+9994eb9896,gabf319e997+ade567573c,gba47b54d5d+94dc90c3ea,gbec6a3398f+06cf436103,gc6308e37c7+07dd123edb,gc655b1545f+ade567573c,gcc9029db3c+ab229f5caf,gd01420fc67+06cf436103,gd877ba84e5+06cf436103,gdb4cecd868+6f279b5b48,ge2d134c3d5+cc4dbb2e3f,ge448b5faa6+86d1ceac1d,gecc7e12556+98f8679e14,gf3ee170dca+25247a063c,gf4ac96e456+ade567573c,gf9f5ea5b4d+ac198e9f13,gff490e6085+8c2580be5c,w.2022.27
LSST Data Management Base Package
DipoleAlgorithms.cc
Go to the documentation of this file.
1/*
2 * LSST Data Management System
3 * Copyright 2008-2015 AURA/LSST
4 *
5 * This product includes software developed by the
6 * LSST Project (http://www.lsst.org/).
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the LSST License Statement and
19 * the GNU General Public License along with this program. If not,
20 * see <http://www.lsstcorp.org/LegalNotices/>.
21 */
22
26#include <iostream> // std::cout
27#include <algorithm> // std::sort
28#include <limits> // std::numeric_limits
29#include <cmath> // std::sqrt
30
31#if !defined(DOXYGEN)
32# include "Minuit2/FCNBase.h"
33# include "Minuit2/FunctionMinimum.h"
34# include "Minuit2/MnMigrad.h"
35# include "Minuit2/MnMinos.h"
36# include "Minuit2/MnPrint.h"
37#endif
38
39#include <memory>
40#include "lsst/pex/exceptions.h"
41#include "lsst/afw/image.h"
42#include "lsst/afw/detection.h"
43#include "lsst/afw/table.h"
44#include "lsst/afw/math.h"
45#include "lsst/geom.h"
47#include "ndarray/eigen.h"
48
51namespace afwImage = lsst::afw::image;
52namespace afwMath = lsst::afw::math;
53namespace geom = lsst::geom;
54
55namespace lsst { namespace ip { namespace diffim {
56
57namespace {
58meas::base::FlagDefinitionList dipoleFluxFlagDefinitions;
59}
60
61meas::base::FlagDefinition const DipoleFluxAlgorithm::FAILURE = dipoleFluxFlagDefinitions.addFailureFlag("general failure flag, set if anything went wrong");
62meas::base::FlagDefinition const DipoleFluxAlgorithm::POS_FLAG = dipoleFluxFlagDefinitions.add("pos_flag", "failure flag for positive, set if anything went wrong");
63meas::base::FlagDefinition const DipoleFluxAlgorithm::NEG_FLAG = dipoleFluxFlagDefinitions.add("neg_flag", "failure flag for negative, set if anything went wrong");
64
66 return dipoleFluxFlagDefinitions;
67}
68
69namespace {
70meas::base::FlagDefinitionList dipoleCentroidFlagDefinitions;
71}
72
73meas::base::FlagDefinition const DipoleCentroidAlgorithm::FAILURE = dipoleCentroidFlagDefinitions.addFailureFlag("general failure flag, set if anything went wrong");
74meas::base::FlagDefinition const DipoleCentroidAlgorithm::POS_FLAG = dipoleCentroidFlagDefinitions.add("pos_flag", "failure flag for positive, set if anything went wrong");
75meas::base::FlagDefinition const DipoleCentroidAlgorithm::NEG_FLAG = dipoleCentroidFlagDefinitions.add("neg_flag", "failure flag for negative, set if anything went wrong");
76
78 return dipoleCentroidFlagDefinitions;
79}
80
81 int const NEGCENTXPAR(0); // Parameter for the x-component of the negative lobe centroid
82 int const NEGCENTYPAR(1); // Parameter for the y-component of the negative lobe centroid
83 int const NEGFLUXPAR(2); // Parameter for the flux of the negative lobe
84 int const POSCENTXPAR(3); // Parameter for the x-component of the positive lobe centroid
85 int const POSCENTYPAR(4); // Parameter for the y-component of the positive lobe centroid
86 int const POSFLUXPAR(5); // Parameter for the flux of the positive lobe
87
88
89namespace {
90
91void naiveCentroid(
93 afw::image::Exposure<float> const& exposure,
94 geom::Point2I const & center,
96 )
97{
98 typedef afw::image::Image<float> ImageT;
99 ImageT const& image = *exposure.getMaskedImage().getImage();
100 // set to the input centroid, just in case all else fails
101 source.set(keys.getX(), center.getX());
102 source.set(keys.getY(), center.getY());
103
104 int x = center.getX() - image.getX0();
105 int y = center.getY() - image.getY0();
106
107 if (x < 1 || x >= image.getWidth() - 1 || y < 1 || y >= image.getHeight() - 1) {
109 (boost::format("Object at (%d, %d) is too close to the edge")
110 % x % y).str());
111 }
112
113 ImageT::xy_locator im = image.xy_at(x, y);
114
115 double const sum =
116 (im(-1, 1) + im( 0, 1) + im( 1, 1) +
117 im(-1, 0) + im( 0, 0) + im( 1, 0) +
118 im(-1, -1) + im( 0, -1) + im( 1, -1));
119
120
121 if (sum == 0.0) {
123 (boost::format("Object at (%d, %d) has no counts") %
124 x % y).str());
125 }
126
127 double const sum_x =
128 -im(-1, 1) + im( 1, 1) +
129 -im(-1, 0) + im( 1, 0) +
130 -im(-1, -1) + im( 1, -1);
131 double const sum_y =
132 (im(-1, 1) + im( 0, 1) + im( 1, 1)) -
133 (im(-1, -1) + im( 0, -1) + im( 1, -1));
134
135 float xx = afw::image::indexToPosition(x + image.getX0()) + sum_x / sum;
136 float yy = afw::image::indexToPosition(y + image.getY0()) + sum_y / sum;
137 source.set(keys.getX(), xx);
138 source.set(keys.getY(), yy);
139}
140
141} // anonymous namespace
142
143
145 Control const & ctrl,
146 std::string const & name,
148) : DipoleCentroidAlgorithm(ctrl, name, schema, "unweighted first moment centroid"),
149 _ctrl(ctrl)
150{ }
151
157 afw::image::Exposure<float> const & exposure
158) const {
159 afw::detection::PeakCatalog const& peaks = source.getFootprint()->getPeaks();
160
161 int posInd = 0;
162 double posValue = peaks[posInd].getPeakValue(), negValue = 0;
163 if (posValue < 0.) { /* All peaks are negative so use the *most* negative value */
164 posInd = peaks.size() - 1;
165 posValue = peaks[posInd].getPeakValue();
166 }
167 naiveCentroid(source, exposure, peaks[posInd].getI(),
168 (posValue >= 0 ? getPositiveKeys() : getNegativeKeys()));
169
170 if (posValue > 0. && posInd == 0 && peaks.size() > 1) { /* See if there's also a negative peak */
171 int negInd = peaks.size() - 1;
172 negValue = peaks[negInd].getPeakValue();
173 if (posValue > 0. && negValue < 0.) {
174 naiveCentroid(source, exposure, peaks[negInd].getI(),
175 (negValue >= 0 ? getPositiveKeys() : getNegativeKeys()));
176 }
177 }
178
179 mergeCentroids(source, posValue, negValue);
180
181}
182
184 double posValue, double negValue) const {
185
186 double pos_x, pos_y, pos_f;
187 double neg_x, neg_y, neg_f;
188
189 pos_x = source.get(getPositiveKeys().getX());
190 pos_y = source.get(getPositiveKeys().getY());
191 pos_f = posValue;
192
193 neg_x = source.get(getNegativeKeys().getX());
194 neg_y = source.get(getNegativeKeys().getY());
195 neg_f = -negValue;
196
197 if(std::isfinite(pos_x) && std::isfinite(pos_y) &&
198 std::isfinite(neg_x) && std::isfinite(neg_y)) {
199 source.set(getCenterKeys().getX(), (pos_x * pos_f + neg_x * neg_f) / (pos_f + neg_f));
200 source.set(getCenterKeys().getY(), (pos_y * pos_f + neg_y * neg_f) / (pos_f + neg_f));
201 } else if (std::isfinite(pos_x) && std::isfinite(pos_y)) {
202 source.set(getCenterKeys().getX(), pos_x);
203 source.set(getCenterKeys().getY(), pos_y);
204 } else {
205 source.set(getCenterKeys().getX(), neg_x);
206 source.set(getCenterKeys().getY(), neg_y);
207 }
208}
209
212 _flagHandler.handleFailure(measRecord, error);
213}
214
215
216namespace {
217
218class NaiveDipoleFootprinter {
219public:
220 explicit NaiveDipoleFootprinter() : _sumPositive(0.0), _sumNegative(0.0), _numPositive(0),
221 _numNegative(0) {}
222
224 void reset() {
225 _sumPositive = _sumNegative = 0.0;
226 _numPositive = _numNegative = 0;
227 }
228 void reset(afwDet::Footprint const&) {}
229
231 void operator() (geom::Point2I const & pos,
234 if (ival >= 0.0) {
235 _sumPositive += ival;
236 _varPositive += vval;
237 ++_numPositive;
238 } else {
239 _sumNegative += ival;
240 _varPositive += vval;
241 ++_numNegative;
242 }
243 }
244
245 double getSumPositive() const { return _sumPositive; }
246 double getSumNegative() const { return _sumNegative; }
247 double getVarPositive() const { return _sumPositive; }
248 double getVarNegative() const { return _sumNegative; }
249 int getNumPositive() const { return _numPositive; }
250 int getNumNegative() const { return _numNegative; }
251
252private:
253 double _sumPositive;
254 double _sumNegative;
255 double _varPositive;
256 double _varNegative;
257 int _numPositive;
258 int _numNegative;
259};
260
261} // anonymous namespace
262
263
269 afw::image::Exposure<float> const & exposure
270) const {
272
273 NaiveDipoleFootprinter functor;
274 source.getFootprint()->getSpans()->applyFunctor(functor, *(exposure.getMaskedImage().getImage()),
275 *(exposure.getMaskedImage().getVariance()));
276
277 source.set(getPositiveKeys().getInstFlux(), functor.getSumPositive());
278 source.set(getPositiveKeys().getInstFluxErr(), ::sqrt(functor.getVarPositive()));
279 source.set(_numPositiveKey, functor.getNumPositive());
280
281 source.set(getNegativeKeys().getInstFlux(), functor.getSumNegative());
282 source.set(getNegativeKeys().getInstFluxErr(), ::sqrt(functor.getVarNegative()));
283 source.set(_numNegativeKey, functor.getNumNegative());
284 functor.reset();
285}
286
288 _flagHandler.handleFailure(measRecord, error);
289}
290
291
295class MinimizeDipoleChi2 : public ROOT::Minuit2::FCNBase {
296public:
297 explicit MinimizeDipoleChi2(PsfDipoleFlux const& psfDipoleFlux,
299 afw::image::Exposure<float> const& exposure
300 ) : _errorDef(1.0),
301 _nPar(6),
302 _maxPix(1e4),
303 _bigChi2(1e10),
304 _psfDipoleFlux(psfDipoleFlux),
305 _source(source),
306 _exposure(exposure)
307 {}
308 double Up() const { return _errorDef; }
309 void setErrorDef(double def) { _errorDef = def; }
310 int getNpar() const { return _nPar; }
311 int getMaxPix() const { return _maxPix; }
312 void setMaxPix(int maxPix) { _maxPix = maxPix; }
313
314 // Evaluate our cost function (in this case chi^2)
315 virtual double operator()(std::vector<double> const & params) const {
316 double negCenterX = params[NEGCENTXPAR];
317 double negCenterY = params[NEGCENTYPAR];
318 double negFlux = params[NEGFLUXPAR];
319 double posCenterX = params[POSCENTXPAR];
320 double posCenterY = params[POSCENTYPAR];
321 double posFlux = params[POSFLUXPAR];
322
323 /* Restrict negative dipole to be negative; positive to be positive */
324 if ((negFlux > 0.0) || (posFlux < 0.0)) {
325 return _bigChi2;
326 }
327
328 std::pair<double,int> fit = _psfDipoleFlux.chi2(_source, _exposure, negCenterX, negCenterY, negFlux,
329 posCenterX, posCenterY, posFlux);
330 double chi2 = fit.first;
331 int nPix = fit.second;
332 if (nPix > _maxPix) {
333 return _bigChi2;
334 }
335
336 return chi2;
337 }
338
339private:
340 double _errorDef; // how much cost function has changed at the +- 1 error points
341 int _nPar; // number of parameters in the fit; hard coded for MinimizeDipoleChi2
342 int _maxPix; // maximum number of pixels that shoud be in the footprint;
343 // prevents too much centroid wander
344 double _bigChi2; // large value to tell fitter when it has gone into bad region of parameter space
345
346 PsfDipoleFlux const& _psfDipoleFlux;
347 afw::table::SourceRecord & _source;
348 afw::image::Exposure<float> const& _exposure;
349};
350
353 afw::image::Exposure<float> const& exposure,
354 double negCenterX, double negCenterY, double negFlux,
355 double posCenterX, double posCenterY, double posFlux
356) const {
357
358 geom::Point2D negCenter(negCenterX, negCenterY);
359 geom::Point2D posCenter(posCenterX, posCenterY);
360
362
363 /*
364 * Fit for the superposition of Psfs at the two centroids.
365 */
367 std::shared_ptr<afwImage::Image<afwMath::Kernel::Pixel>> negPsf = psf->computeImage(negCenter);
368 std::shared_ptr<afwImage::Image<afwMath::Kernel::Pixel>> posPsf = psf->computeImage(posCenter);
369
370 afwImage::Image<double> negModel(footprint->getBBox());
371 afwImage::Image<double> posModel(footprint->getBBox());
372 afwImage::Image<float> data(*(exposure.getMaskedImage().getImage()),footprint->getBBox());
374 footprint->getBBox());
375
376 geom::Box2I negPsfBBox = negPsf->getBBox();
377 geom::Box2I posPsfBBox = posPsf->getBBox();
378 geom::Box2I negModelBBox = negModel.getBBox();
379 geom::Box2I posModelBBox = posModel.getBBox();
380
381 // Portion of the negative Psf that overlaps the model
382 int negXmin = std::max(negPsfBBox.getMinX(), negModelBBox.getMinX());
383 int negYmin = std::max(negPsfBBox.getMinY(), negModelBBox.getMinY());
384 int negXmax = std::min(negPsfBBox.getMaxX(), negModelBBox.getMaxX());
385 int negYmax = std::min(negPsfBBox.getMaxY(), negModelBBox.getMaxY());
386 geom::Box2I negBBox = geom::Box2I(geom::Point2I(negXmin, negYmin),
387 geom::Point2I(negXmax, negYmax));
388 afwImage::Image<afwMath::Kernel::Pixel> negSubim(*negPsf, negBBox);
389 afwImage::Image<double> negModelSubim(negModel, negBBox);
390 negModelSubim += negSubim;
391
392 // Portion of the positive Psf that overlaps the model
393 int posXmin = std::max(posPsfBBox.getMinX(), posModelBBox.getMinX());
394 int posYmin = std::max(posPsfBBox.getMinY(), posModelBBox.getMinY());
395 int posXmax = std::min(posPsfBBox.getMaxX(), posModelBBox.getMaxX());
396 int posYmax = std::min(posPsfBBox.getMaxY(), posModelBBox.getMaxY());
397 geom::Box2I posBBox = geom::Box2I(geom::Point2I(posXmin, posYmin),
398 geom::Point2I(posXmax, posYmax));
399 afwImage::Image<afwMath::Kernel::Pixel> posSubim(*posPsf, posBBox);
400 afwImage::Image<double> posModelSubim(posModel, posBBox);
401 posModelSubim += posSubim;
402
403 negModel *= negFlux; // scale negative model to image
404 posModel *= posFlux; // scale positive model to image
405 afwImage::Image<double> residuals(negModel, true); // full model contains negative lobe...
406 residuals += posModel; // plus positive lobe...
407 residuals -= data; // minus the data...
408 residuals *= residuals; // squared...
409 residuals /= var; // divided by the variance : [(model-data)/sigma]**2
411 double chi2 = stats.getValue(afwMath::SUM);
412 int nPix = stats.getValue(afwMath::NPOINT);
413 return std::pair<double,int>(chi2, nPix);
414}
415
418 afw::image::Exposure<float> const & exposure
419) const {
420
422
424 if (!footprint) {
426 (boost::format("No footprint for source %d") % source.getId()).str());
427 }
428
429 afw::detection::PeakCatalog peakCatalog = afw::detection::PeakCatalog(footprint->getPeaks());
430
431 if (peakCatalog.size() == 0) {
433 (boost::format("No peak for source %d") % source.getId()).str());
434 }
435 else if (peakCatalog.size() == 1) {
436 // No deblending to do
437 return;
438 }
439
440 // For N>=2, just measure the brightest-positive and brightest-negative
441 // peaks. peakCatalog is automatically ordered by peak flux, with the most
442 // positive one (brightest) being first
443 afw::detection::PeakRecord const& positivePeak = peakCatalog.front();
444 afw::detection::PeakRecord const& negativePeak = peakCatalog.back();
445
446 // Set up fit parameters and param names
447 ROOT::Minuit2::MnUserParameters fitPar;
448
449 fitPar.Add((boost::format("P%d")%NEGCENTXPAR).str(), negativePeak.getFx(), _ctrl.stepSizeCoord);
450 fitPar.Add((boost::format("P%d")%NEGCENTYPAR).str(), negativePeak.getFy(), _ctrl.stepSizeCoord);
451 fitPar.Add((boost::format("P%d")%NEGFLUXPAR).str(), negativePeak.getPeakValue(), _ctrl.stepSizeFlux);
452 fitPar.Add((boost::format("P%d")%POSCENTXPAR).str(), positivePeak.getFx(), _ctrl.stepSizeCoord);
453 fitPar.Add((boost::format("P%d")%POSCENTYPAR).str(), positivePeak.getFy(), _ctrl.stepSizeCoord);
454 fitPar.Add((boost::format("P%d")%POSFLUXPAR).str(), positivePeak.getPeakValue(), _ctrl.stepSizeFlux);
455
456 // Create the minuit object that knows how to minimise our functor
457 //
458 MinimizeDipoleChi2 minimizerFunc(*this, source, exposure);
459 minimizerFunc.setErrorDef(_ctrl.errorDef);
460
461 //
462 // tell minuit about it
463 //
464 ROOT::Minuit2::MnMigrad migrad(minimizerFunc, fitPar);
465
466 //
467 // And let it loose
468 //
469 ROOT::Minuit2::FunctionMinimum min = migrad(_ctrl.maxFnCalls);
470
471 float minChi2 = min.Fval();
472 bool const isValid = min.IsValid() && std::isfinite(minChi2);
473
474 if (true || isValid) { // calculate coeffs even in minuit is unhappy
475
476 /* I need to call chi2 one more time to grab nPix to calculate chi2/dof.
477 Turns out that the Minuit operator method has to be const, and the
478 measurement _apply method has to be const, so I can't store nPix as a
479 private member variable anywhere. Consted into a corner.
480 */
481 std::pair<double,int> fit = chi2(source, exposure,
482 min.UserState().Value(NEGCENTXPAR),
483 min.UserState().Value(NEGCENTYPAR),
484 min.UserState().Value(NEGFLUXPAR),
485 min.UserState().Value(POSCENTXPAR),
486 min.UserState().Value(POSCENTYPAR),
487 min.UserState().Value(POSFLUXPAR));
488 double evalChi2 = fit.first;
489 int nPix = fit.second;
490
491 std::shared_ptr<geom::Point2D> minNegCentroid(new geom::Point2D(min.UserState().Value(NEGCENTXPAR),
492 min.UserState().Value(NEGCENTYPAR)));
493 source.set(getNegativeKeys().getInstFlux(), min.UserState().Value(NEGFLUXPAR));
494 source.set(getNegativeKeys().getInstFluxErr(), min.UserState().Error(NEGFLUXPAR));
495
496 std::shared_ptr<geom::Point2D> minPosCentroid(new geom::Point2D(min.UserState().Value(POSCENTXPAR),
497 min.UserState().Value(POSCENTYPAR)));
498 source.set(getPositiveKeys().getInstFlux(), min.UserState().Value(POSFLUXPAR));
499 source.set(getPositiveKeys().getInstFluxErr(), min.UserState().Error(POSFLUXPAR));
500
501 source.set(_chi2dofKey, evalChi2 / (nPix - minimizerFunc.getNpar()));
502 source.set(_negCentroid.getX(), minNegCentroid->getX());
503 source.set(_negCentroid.getY(), minNegCentroid->getY());
504 source.set(_posCentroid.getX(), minPosCentroid->getX());
505 source.set(_posCentroid.getY(), minPosCentroid->getY());
506 source.set(_avgCentroid.getX(), 0.5*(minNegCentroid->getX() + minPosCentroid->getX()));
507 source.set(_avgCentroid.getY(), 0.5*(minNegCentroid->getY() + minPosCentroid->getY()));
508
509 }
510}
511
513 _flagHandler.handleFailure(measRecord, error);
514}
515}}} // namespace lsst::ip::diffim
table::Key< std::string > name
Definition: Amplifier.cc:116
char * data
Definition: BaseRecord.cc:61
int min
double x
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
afw::table::Key< afw::table::Array< ImagePixelT > > image
int y
Definition: SpanSet.cc:48
table::Schema schema
Definition: python.h:134
Class to describe the properties of a detected object from an image.
Definition: Footprint.h:63
Record class that represents a peak in a Footprint.
Definition: Peak.h:42
float getPeakValue() const
Definition: Peak.h:240
A class to contain the data, WCS, and other information needed to describe an image of the sky.
Definition: Exposure.h:72
MaskedImageT getMaskedImage()
Return the MaskedImage.
Definition: Exposure.h:228
std::shared_ptr< lsst::afw::detection::Psf const > getPsf() const
Return the Exposure's Psf object.
Definition: Exposure.h:319
PixelT Pixel
A pixel in this ImageBase.
Definition: ImageBase.h:115
lsst::geom::Box2I getBBox(ImageOrigin origin=PARENT) const
Definition: ImageBase.h:445
A class to represent a 2-dimensional array of pixels.
Definition: Image.h:51
A class to manipulate images, masks, and variance as a single object.
Definition: MaskedImage.h:73
VariancePtr getVariance() const
Return a (shared_ptr to) the MaskedImage's variance.
Definition: MaskedImage.h:1051
ImagePtr getImage() const
Return a (shared_ptr to) the MaskedImage's image.
Definition: MaskedImage.h:1018
A class to evaluate image statistics.
Definition: Statistics.h:220
double getValue(Property const prop=NOTHING) const
Return the value of the desired property (if specified in the constructor)
Definition: Statistics.cc:1047
size_type size() const
Return the number of elements in the catalog.
Definition: Catalog.h:413
reference back() const
Return the last record.
Definition: Catalog.h:461
reference front() const
Return the first record.
Definition: Catalog.h:458
Defines the fields and offsets for a table.
Definition: Schema.h:51
Record class that contains measurements made on a single exposure.
Definition: Source.h:78
An integer coordinate rectangle.
Definition: Box.h:55
int getMinY() const noexcept
Definition: Box.h:158
int getMinX() const noexcept
Definition: Box.h:157
int getMaxX() const noexcept
Definition: Box.h:161
int getMaxY() const noexcept
Definition: Box.h:162
Intermediate base class for algorithms that compute a centroid.
static meas::base::FlagDefinition const FAILURE
static meas::base::FlagDefinition const POS_FLAG
static meas::base::FlagDefinition const NEG_FLAG
static meas::base::FlagDefinitionList const & getFlagDefinitions()
static meas::base::FlagDefinitionList const & getFlagDefinitions()
ResultKey const & getPositiveKeys() const
Return the standard flux keys registered by this algorithm.
static meas::base::FlagDefinition const POS_FLAG
static meas::base::FlagDefinition const NEG_FLAG
ResultKey const & getNegativeKeys() const
static meas::base::FlagDefinition const FAILURE
Class to minimize PsfDipoleFlux; this is the object that Minuit minimizes.
virtual double operator()(std::vector< double > const &params) const
MinimizeDipoleChi2(PsfDipoleFlux const &psfDipoleFlux, afw::table::SourceRecord &source, afw::image::Exposure< float > const &exposure)
ResultKey const & getPositiveKeys() const
ResultKey const & getNegativeKeys() const
NaiveDipoleCentroid(Control const &ctrl, std::string const &name, afw::table::Schema &schema)
void measure(afw::table::SourceRecord &measRecord, afw::image::Exposure< float > const &exposure) const
Given an image and a pixel position, return a Centroid using a naive 3x3 weighted moment.
void mergeCentroids(afw::table::SourceRecord &source, double posValue, double negValue) const
void fail(afw::table::SourceRecord &measRecord, meas::base::MeasurementError *error=NULL) const
Handle an exception thrown by the current algorithm by setting flags in the given record.
ResultKey const & getCenterKeys() const
Return the standard centroid keys registered by this algorithm.
void measure(afw::table::SourceRecord &measRecord, afw::image::Exposure< float > const &exposure) const
Given an image and a pixel position, return a Centroid using a naive 3x3 weighted moment.
void fail(afw::table::SourceRecord &measRecord, meas::base::MeasurementError *error=NULL) const
Handle an exception thrown by the current algorithm by setting flags in the given record.
float stepSizeCoord
"Default initial step size for coordinates in non-linear fitter" ;
double errorDef
"How many sigma the error bars of the non-linear fitter represent" ;
float stepSizeFlux
"Default initial step size for flux in non-linear fitter" ;
int maxFnCalls
"Maximum function calls for non-linear fitter; 0 = unlimited" ;
Implementation of Psf dipole flux.
std::pair< double, int > chi2(afw::table::SourceRecord &source, afw::image::Exposure< float > const &exposure, double negCenterX, double negCenterY, double negFlux, double posCenterX, double poCenterY, double posFlux) const
void measure(afw::table::SourceRecord &measRecord, afw::image::Exposure< float > const &exposure) const
Called to measure a single child source in an image.
void fail(afw::table::SourceRecord &measRecord, meas::base::MeasurementError *error=NULL) const
Handle an exception thrown by the current algorithm by setting flags in the given record.
A FunctorKey for CentroidResult.
afw::table::Key< CentroidElement > getX() const
Return a Key for the x coordinate.
afw::table::Key< CentroidElement > getY() const
Return a Key for the y coordinate.
vector-type utility class to build a collection of FlagDefinitions
Definition: FlagHandler.h:60
void handleFailure(afw::table::BaseRecord &record, MeasurementError const *error=nullptr) const
Handle an expected or unexpected Exception thrown by a measurement algorithm.
Definition: FlagHandler.cc:76
Exception to be thrown when a measurement algorithm experiences a known failure mode.
Definition: exceptions.h:48
Reports attempts to exceed implementation-defined length limits for some classes.
Definition: Runtime.h:76
Reports errors that are due to events beyond the control of the program.
Definition: Runtime.h:104
bool isValid
Definition: fits.cc:399
T isfinite(T... args)
T max(T... args)
T min(T... args)
const char * source()
Source function that allows astChannel to source from a Stream.
Definition: Stream.h:224
afw::table::CatalogT< PeakRecord > PeakCatalog
Definition: Peak.h:244
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
double indexToPosition(double ind)
Convert image index to image position.
Definition: ImageUtils.h:55
Statistics makeStatistics(lsst::afw::image::Image< Pixel > const &img, lsst::afw::image::Mask< image::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl=StatisticsControl())
Handle a watered-down front-end to the constructor (no variance)
Definition: Statistics.h:359
@ SUM
find sum of pixels in the image
Definition: Statistics.h:77
@ NPOINT
number of sample points
Definition: Statistics.h:65
int const NEGFLUXPAR(2)
int const NEGCENTXPAR(0)
int const NEGCENTYPAR(1)
int const POSFLUXPAR(5)
int const POSCENTXPAR(3)
int const POSCENTYPAR(4)
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:174
A base class for image defects.
Simple class used to define and document flags The name and doc constitute the identity of the FlagDe...
Definition: FlagHandler.h:40
Key< int > psf
Definition: Exposure.cc:65