LSSTApplications  1.1.2+25,10.0+13,10.0+132,10.0+133,10.0+224,10.0+41,10.0+8,10.0-1-g0f53050+14,10.0-1-g4b7b172+19,10.0-1-g61a5bae+98,10.0-1-g7408a83+3,10.0-1-gc1e0f5a+19,10.0-1-gdb4482e+14,10.0-11-g3947115+2,10.0-12-g8719d8b+2,10.0-15-ga3f480f+1,10.0-2-g4f67435,10.0-2-gcb4bc6c+26,10.0-28-gf7f57a9+1,10.0-3-g1bbe32c+14,10.0-3-g5b46d21,10.0-4-g027f45f+5,10.0-4-g86f66b5+2,10.0-4-gc4fccf3+24,10.0-40-g4349866+2,10.0-5-g766159b,10.0-5-gca2295e+25,10.0-6-g462a451+1
LSSTDataManagementBasePackage
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 <functional> // std::binary_function
29 #include <limits> // std::numeric_limits
30 #include <cmath> // std::sqrt
31 
32 #if !defined(DOXYGEN)
33 # include "Minuit2/FCNBase.h"
34 # include "Minuit2/FunctionMinimum.h"
35 # include "Minuit2/MnMigrad.h"
36 # include "Minuit2/MnMinos.h"
37 # include "Minuit2/MnPrint.h"
38 #endif
39 
40 #include "boost/shared_ptr.hpp"
41 #include "lsst/pex/exceptions.h"
42 #include "lsst/pex/logging/Trace.h"
43 #include "lsst/afw/image.h"
44 #include "lsst/afw/detection.h"
45 #include "lsst/afw/detection/FootprintArray.cc"
46 #include "lsst/afw/table.h"
47 #include "lsst/afw/math.h"
48 #include "lsst/afw/geom.h"
50 #include "ndarray/eigen.h"
51 
52 namespace pexExceptions = lsst::pex::exceptions;
53 namespace pexLogging = lsst::pex::logging;
54 namespace afwDet = lsst::afw::detection;
55 namespace afwImage = lsst::afw::image;
56 namespace afwTable = lsst::afw::table;
57 namespace afwMath = lsst::afw::math;
58 namespace afwGeom = lsst::afw::geom;
59 namespace measBase = lsst::meas::base;
60 
61 namespace lsst {
62 namespace ip {
63 namespace diffim {
64 
65  int const NEGCENTXPAR(0); // Parameter for the x-component of the negative lobe centroid
66  int const NEGCENTYPAR(1); // Parameter for the y-component of the negative lobe centroid
67  int const NEGFLUXPAR(2); // Parameter for the flux of the negative lobe
68  int const POSCENTXPAR(3); // Parameter for the x-component of the positive lobe centroid
69  int const POSCENTYPAR(4); // Parameter for the y-component of the positive lobe centroid
70  int const POSFLUXPAR(5); // Parameter for the flux of the positive lobe
71 
72 
73 namespace {
74 
75 void naiveCentroid(
76  afw::table::SourceRecord & source,
77  afw::image::Exposure<float> const& exposure,
78  afw::geom::Point2I const & center,
79  meas::base::CentroidResultKey const & keys
80  )
81 {
82  typedef afw::image::Image<float> ImageT;
83  ImageT const& image = *exposure.getMaskedImage().getImage();
84  // set to the input centroid, just in case all else fails
85  source.set(keys.getX(), center.getX());
86  source.set(keys.getY(), center.getY());
87 
88  int x = center.getX() - image.getX0();
89  int y = center.getY() - image.getY0();
90 
91  if (x < 1 || x >= image.getWidth() - 1 || y < 1 || y >= image.getHeight() - 1) {
92  throw LSST_EXCEPT(pex::exceptions::LengthError,
93  (boost::format("Object at (%d, %d) is too close to the edge")
94  % x % y).str());
95  }
96 
97  ImageT::xy_locator im = image.xy_at(x, y);
98 
99  double const sum =
100  (im(-1, 1) + im( 0, 1) + im( 1, 1) +
101  im(-1, 0) + im( 0, 0) + im( 1, 0) +
102  im(-1, -1) + im( 0, -1) + im( 1, -1));
103 
104 
105  if (sum == 0.0) {
106  throw LSST_EXCEPT(pexExceptions::RuntimeError,
107  (boost::format("Object at (%d, %d) has no counts") %
108  x % y).str());
109  }
110 
111  double const sum_x =
112  -im(-1, 1) + im( 1, 1) +
113  -im(-1, 0) + im( 1, 0) +
114  -im(-1, -1) + im( 1, -1);
115  double const sum_y =
116  (im(-1, 1) + im( 0, 1) + im( 1, 1)) -
117  (im(-1, -1) + im( 0, -1) + im( 1, -1));
118 
119  float xx = afw::image::indexToPosition(x + image.getX0()) + sum_x / sum;
120  float yy = afw::image::indexToPosition(y + image.getY0()) + sum_y / sum;
121  source.set(keys.getX(), xx);
122  source.set(keys.getY(), yy);
123 }
124 
125 } // anonymous namespace
126 
127 
129  Control const & ctrl,
130  std::string const & name,
131  afw::table::Schema & schema
132 ) : DipoleCentroidAlgorithm(ctrl, name, schema, "unweighted first moment centroid"),
133  _ctrl(ctrl),
134  _centroidExtractor(schema, name)
135 {
136 }
137 
142  afw::table::SourceRecord & source,
143  afw::image::Exposure<float> const & exposure
144 ) const {
145  afw::detection::Footprint::PeakList const& peaks = source.getFootprint()->getPeaks();
146 
147  naiveCentroid(source, exposure, peaks[0]->getI(), (peaks[0]->getPeakValue() >= 0 ?
148  getPositiveKeys() :
149  getNegativeKeys()));
150  if (peaks.size() > 1) {
151  naiveCentroid(source, exposure, peaks[1]->getI(), (peaks[1]->getPeakValue() >= 0 ?
152  getPositiveKeys() :
153  getNegativeKeys()));
154  }
155 }
156 
158  _flagHandler.handleFailure(measRecord, error);
159 }
160 
161 
162 namespace {
163 
164 class NaiveDipoleFootprinter : public afw::detection::FootprintFunctor< afw::image::MaskedImage<float> > {
165 public:
166  explicit NaiveDipoleFootprinter(afw::image::MaskedImage<float> const& mimage
167  ) : afw::detection::FootprintFunctor< afw::image::MaskedImage<float> >(mimage),
168  _sumPositive(0.0), _sumNegative(0.0), _numPositive(0), _numNegative(0) {}
169 
171  void reset() {
172  _sumPositive = _sumNegative = 0.0;
174  }
175  void reset(afwDet::Footprint const&) {}
176 
178  void operator()( afw::image::MaskedImage<float>::xy_locator loc,
179  int,
180  int
181  ) {
182  afw::image::MaskedImage<float>::Image::Pixel ival = loc.image(0, 0);
183  afw::image::MaskedImage<float>::Image::Pixel vval = loc.variance(0, 0);
184  if (ival >= 0.0) {
185  _sumPositive += ival;
186  _varPositive += vval;
187  ++_numPositive;
188  } else {
189  _sumNegative += ival;
190  _varPositive += vval;
191  ++_numNegative;
192  }
193  }
194 
195  double getSumPositive() const { return _sumPositive; }
196  double getSumNegative() const { return _sumNegative; }
197  double getVarPositive() const { return _sumPositive; }
198  double getVarNegative() const { return _sumNegative; }
199  int getNumPositive() const { return _numPositive; }
200  int getNumNegative() const { return _numNegative; }
201 
202 private:
203  double _sumPositive;
204  double _sumNegative;
205  double _varPositive;
206  double _varNegative;
209 };
210 
211 } // anonymous namespace
212 
213 
218  afw::table::SourceRecord & source,
219  afw::image::Exposure<float> const & exposure
220 ) const {
221  typedef afw::image::Exposure<float>::MaskedImageT MaskedImageT;
222 
223  NaiveDipoleFootprinter functor(exposure.getMaskedImage());
224  functor.apply(*source.getFootprint());
225 
226  source.set(getPositiveKeys().getFlux(), functor.getSumPositive());
227  source.set(getPositiveKeys().getFluxSigma(), ::sqrt(functor.getVarPositive()));
228  source.set(_numPositiveKey, functor.getNumPositive());
229 
230  source.set(getNegativeKeys().getFlux(), functor.getSumNegative());
231  source.set(getNegativeKeys().getFluxSigma(), ::sqrt(functor.getVarNegative()));
232  source.set(_numNegativeKey, functor.getNumNegative());
233 }
234 
236  _flagHandler.handleFailure(measRecord, error);
237 }
238 
239 
243 class MinimizeDipoleChi2 : public ROOT::Minuit2::FCNBase {
244 public:
245  explicit MinimizeDipoleChi2(PsfDipoleFlux const& psfDipoleFlux,
246  afw::table::SourceRecord & source,
247  afw::image::Exposure<float> const& exposure
248  ) : _errorDef(1.0),
249  _nPar(6),
250  _maxPix(1e4),
251  _bigChi2(1e10),
252  _psfDipoleFlux(psfDipoleFlux),
253  _source(source),
254  _exposure(exposure)
255  {}
256  double Up() const { return _errorDef; }
257  void setErrorDef(double def) { _errorDef = def; }
258  int getNpar() const { return _nPar; }
259  int getMaxPix() const { return _maxPix; }
260  void setMaxPix(int maxPix) { _maxPix = maxPix; }
261 
262  // Evaluate our cost function (in this case chi^2)
263  virtual double operator()(std::vector<double> const & params) const {
264  double negCenterX = params[NEGCENTXPAR];
265  double negCenterY = params[NEGCENTYPAR];
266  double negFlux = params[NEGFLUXPAR];
267  double posCenterX = params[POSCENTXPAR];
268  double posCenterY = params[POSCENTYPAR];
269  double posFlux = params[POSFLUXPAR];
270 
271  /* Restrict negative dipole to be negative; positive to be positive */
272  if ((negFlux > 0.0) || (posFlux < 0.0)) {
273  return _bigChi2;
274  }
275 
276  std::pair<double,int> fit = _psfDipoleFlux.chi2(_source, _exposure, negCenterX, negCenterY, negFlux, posCenterX, posCenterY, posFlux);
277  double chi2 = fit.first;
278  int nPix = fit.second;
279  if (nPix > _maxPix) {
280  return _bigChi2;
281  }
282 
283  return chi2;
284  }
285 
286 private:
287  double _errorDef; // how much cost function has changed at the +- 1 error points
288  int _nPar; // number of parameters in the fit; hard coded for MinimizeDipoleChi2
289  int _maxPix; // maximum number of pixels that shoud be in the footprint; prevents too much centroid wander
290  double _bigChi2; // large value to tell fitter when it has gone into bad region of parameter space
291 
295 };
296 
297 std::pair<double,int> PsfDipoleFlux::chi2(
298  afw::table::SourceRecord & source,
299  afw::image::Exposure<float> const& exposure,
300  double negCenterX, double negCenterY, double negFlux,
301  double posCenterX, double posCenterY, double posFlux
302 ) const {
303 
304  afw::geom::Point2D negCenter(negCenterX, negCenterY);
305  afw::geom::Point2D posCenter(posCenterX, posCenterY);
306 
307  CONST_PTR(afw::detection::Footprint) footprint = source.getFootprint();
308 
309  /* Fit for the superposition of Psfs at the two centroids.
310  *
311  */
312  CONST_PTR(afwDet::Psf) psf = exposure.getPsf();
313  PTR(afwImage::Image<afwMath::Kernel::Pixel>) negPsf = psf->computeImage(negCenter);
314  PTR(afwImage::Image<afwMath::Kernel::Pixel>) posPsf = psf->computeImage(posCenter);
315 
316  afwImage::Image<double> negModel(footprint->getBBox());
317  afwImage::Image<double> posModel(footprint->getBBox());
318  afwImage::Image<float> data(*(exposure.getMaskedImage().getImage()),
319  footprint->getBBox());
321  footprint->getBBox());
322 
323  afwGeom::Box2I negPsfBBox = negPsf->getBBox();
324  afwGeom::Box2I posPsfBBox = posPsf->getBBox();
325  afwGeom::Box2I negModelBBox = negModel.getBBox();
326  afwGeom::Box2I posModelBBox = posModel.getBBox();
327 
328  // Portion of the negative Psf that overlaps the model
329  int negXmin = std::max(negPsfBBox.getMinX(), negModelBBox.getMinX());
330  int negYmin = std::max(negPsfBBox.getMinY(), negModelBBox.getMinY());
331  int negXmax = std::min(negPsfBBox.getMaxX(), negModelBBox.getMaxX());
332  int negYmax = std::min(negPsfBBox.getMaxY(), negModelBBox.getMaxY());
333  afwGeom::Box2I negBBox = afwGeom::Box2I(afwGeom::Point2I(negXmin, negYmin),
334  afwGeom::Point2I(negXmax, negYmax));
335  afwImage::Image<afwMath::Kernel::Pixel> negSubim(*negPsf, negBBox);
336  afwImage::Image<double> negModelSubim(negModel, negBBox);
337  negModelSubim += negSubim;
338 
339  // Portion of the positive Psf that overlaps the model
340  int posXmin = std::max(posPsfBBox.getMinX(), posModelBBox.getMinX());
341  int posYmin = std::max(posPsfBBox.getMinY(), posModelBBox.getMinY());
342  int posXmax = std::min(posPsfBBox.getMaxX(), posModelBBox.getMaxX());
343  int posYmax = std::min(posPsfBBox.getMaxY(), posModelBBox.getMaxY());
344  afwGeom::Box2I posBBox = afwGeom::Box2I(afwGeom::Point2I(posXmin, posYmin),
345  afwGeom::Point2I(posXmax, posYmax));
346  afwImage::Image<afwMath::Kernel::Pixel> posSubim(*posPsf, posBBox);
347  afwImage::Image<double> posModelSubim(posModel, posBBox);
348  posModelSubim += posSubim;
349 
350  negModel *= negFlux; // scale negative model to image
351  posModel *= posFlux; // scale positive model to image
352  afwImage::Image<double> residuals(negModel, true); // full model contains negative lobe...
353  residuals += posModel; // plus positive lobe...
354  residuals -= data; // minus the data...
355  residuals *= residuals;// squared...
356  residuals /= var; // divided by the variance : [(model-data)/sigma]**2
358  double chi2 = stats.getValue(afwMath::SUM);
359  int nPix = stats.getValue(afwMath::NPOINT);
360  return std::pair<double,int>(chi2, nPix);
361 }
362 
364  afw::table::SourceRecord & source,
365  afw::image::Exposure<float> const & exposure
366 ) const {
367  source.set(_flagMaxPixelsKey, true);
368 
369  typedef afw::image::Exposure<float>::MaskedImageT MaskedImageT;
370 
371  CONST_PTR(afw::detection::Footprint) footprint = source.getFootprint();
372  if (!footprint) {
373  throw LSST_EXCEPT(pex::exceptions::RuntimeError,
374  (boost::format("No footprint for source %d") % source.getId()).str());
375  }
376 
377  if (footprint->getArea() > _ctrl.maxPixels) {
378  // Too big
379  return;
380  }
381  source.set(_flagMaxPixelsKey, false);
382 
384  afw::detection::Footprint::PeakList(footprint->getPeaks());
385 
386  if (peakList.size() == 0) {
387  throw LSST_EXCEPT(pex::exceptions::RuntimeError,
388  (boost::format("No peak for source %d") % source.getId()).str());
389  }
390  else if (peakList.size() == 1) {
391  // No deblending to do
392  return;
393  }
394 
395  // For N>=2, just measure the brightest-positive and brightest-negative
396  // peaks. peakList is automatically ordered by peak flux, with the most
397  // positive one (brightest) being first
398  PTR(afw::detection::Peak) positivePeak = peakList.front();
399  PTR(afw::detection::Peak) negativePeak = peakList.back();
400 
401  // Set up fit parameters and param names
402  ROOT::Minuit2::MnUserParameters fitPar;
403 
404  fitPar.Add((boost::format("P%d")%NEGCENTXPAR).str(), negativePeak->getFx(), _ctrl.stepSizeCoord);
405  fitPar.Add((boost::format("P%d")%NEGCENTYPAR).str(), negativePeak->getFy(), _ctrl.stepSizeCoord);
406  fitPar.Add((boost::format("P%d")%NEGFLUXPAR).str(), negativePeak->getPeakValue(), _ctrl.stepSizeFlux);
407  fitPar.Add((boost::format("P%d")%POSCENTXPAR).str(), positivePeak->getFx(), _ctrl.stepSizeCoord);
408  fitPar.Add((boost::format("P%d")%POSCENTYPAR).str(), positivePeak->getFy(), _ctrl.stepSizeCoord);
409  fitPar.Add((boost::format("P%d")%POSFLUXPAR).str(), positivePeak->getPeakValue(), _ctrl.stepSizeFlux);
410 
411  // Create the minuit object that knows how to minimise our functor
412  //
413  MinimizeDipoleChi2 minimizerFunc(*this, source, exposure);
414  minimizerFunc.setErrorDef(_ctrl.errorDef);
415 
416  //
417  // tell minuit about it
418  //
419  ROOT::Minuit2::MnMigrad migrad(minimizerFunc, fitPar);
420 
421  //
422  // And let it loose
423  //
424  ROOT::Minuit2::FunctionMinimum min = migrad(_ctrl.maxFnCalls);
425 
426  float minChi2 = min.Fval();
427  bool const isValid = min.IsValid() && std::isfinite(minChi2);
428 
429  if (true || isValid) { // calculate coeffs even in minuit is unhappy
430 
431  /* I need to call chi2 one more time to grab nPix to calculate chi2/dof.
432  Turns out that the Minuit operator method has to be const, and the
433  measurement _apply method has to be const, so I can't store nPix as a
434  private member variable anywhere. Consted into a corner.
435  */
436  std::pair<double,int> fit = chi2(source, exposure,
437  min.UserState().Value(NEGCENTXPAR), min.UserState().Value(NEGCENTYPAR),
438  min.UserState().Value(NEGFLUXPAR), min.UserState().Value(POSCENTXPAR),
439  min.UserState().Value(POSCENTYPAR), min.UserState().Value(POSFLUXPAR));
440  double evalChi2 = fit.first;
441  int nPix = fit.second;
442 
443  PTR(afw::geom::Point2D) minNegCentroid(new afw::geom::Point2D(min.UserState().Value(NEGCENTXPAR),
444  min.UserState().Value(NEGCENTYPAR)));
445  source.set(getNegativeKeys().getFlux(), min.UserState().Value(NEGFLUXPAR));
446  source.set(getNegativeKeys().getFluxSigma(), min.UserState().Error(NEGFLUXPAR));
447 
448  PTR(afw::geom::Point2D) minPosCentroid(new afw::geom::Point2D(min.UserState().Value(POSCENTXPAR),
449  min.UserState().Value(POSCENTYPAR)));
450  source.set(getPositiveKeys().getFlux(), min.UserState().Value(POSFLUXPAR));
451  source.set(getPositiveKeys().getFluxSigma(), min.UserState().Error(POSFLUXPAR));
452 
453  source.set(_chi2dofKey, evalChi2 / (nPix - minimizerFunc.getNpar()));
454  source.set(_negCentroid.getX(), minNegCentroid->getX());
455  source.set(_negCentroid.getY(), minNegCentroid->getY());
456  source.set(_posCentroid.getX(), minPosCentroid->getX());
457  source.set(_posCentroid.getY(), minPosCentroid->getY());
458  source.set(_avgCentroid.getX(), 0.5*(minNegCentroid->getX() + minPosCentroid->getX()));
459  source.set(_avgCentroid.getY(), 0.5*(minNegCentroid->getY() + minPosCentroid->getY()));
460 
461  }
462 }
463 
465  _flagHandler.handleFailure(measRecord, error);
466 }
467 }}} // namespace lsst::ip::diffim
int y
An include file to include the public header files for lsst::afw::math.
double getValue(Property const prop=NOTHING) const
Return the value of the desired property (if specified in the constructor)
Definition: Statistics.cc:950
MaskedImageT getMaskedImage()
Return the MaskedImage.
Definition: Exposure.h:150
#define CONST_PTR(...)
Definition: base.h:47
ImagePtr getImage(bool const noThrow=false) const
Return a (Ptr to) the MaskedImage&#39;s image.
Definition: MaskedImage.h:869
An include file to include the header files for lsst::afw::geom.
double _sumNegative
int const NEGFLUXPAR(2)
double indexToPosition(double ind)
Convert image index to image position.
Definition: ImageUtils.h:54
Eigen matrix objects that present a view into an ndarray::Array.
std::vector< Peak::Ptr > PeakList
Definition: Footprint.h:80
double _varNegative
definition of the Trace messaging facilities
int const NEGCENTXPAR(0)
MinimizeDipoleChi2(PsfDipoleFlux const &psfDipoleFlux, afw::table::SourceRecord &source, afw::image::Exposure< float > const &exposure)
int getMinY() const
Definition: Box.h:125
void fail(afw::table::SourceRecord &measRecord, meas::base::MeasurementError *error=NULL) const
RecordId getId() const
Convenience accessors for the keys in the minimal reference schema.
Definition: Simple.h:203
find sum of pixels in the image
Definition: Statistics.h:78
#define PTR(...)
Definition: base.h:41
Point< int, 2 > Point2I
Definition: PSF.h:39
int getMaxX() const
Definition: Box.h:128
Exception to be thrown when a measurement algorithm experiences a known failure mode.
Definition: exceptions.h:48
boost::enable_if< typename ExpressionTraits< Scalar >::IsScalar, Scalar >::type sum(Scalar const &scalar)
Definition: operators.h:1250
PixelT Pixel
A pixel in this ImageBase.
Definition: Image.h:133
An integer coordinate rectangle.
Definition: Box.h:53
double min
Definition: attributes.cc:216
void measure(afw::table::SourceRecord &measRecord, afw::image::Exposure< float > const &exposure) const
int const POSCENTXPAR(3)
table::Key< table::Array< Kernel::Pixel > > image
Definition: FixedKernel.cc:117
afw::image::Exposure< float > const & _exposure
VariancePtr getVariance(bool const noThrow=false) const
Return a (Ptr to) the MaskedImage&#39;s variance.
Definition: MaskedImage.h:890
def error
Definition: log.py:108
An include file to include the header files for lsst::afw::image.
void measure(afw::table::SourceRecord &measRecord, afw::image::Exposure< float > const &exposure) const
double max
Definition: attributes.cc:218
A peak in an image.
Definition: Peak.h:51
tbl::Schema schema
Definition: CoaddPsf.cc:324
An include file to include the header files for lsst::afw::detection.
A class to manipulate images, masks, and variance as a single object.
Definition: MaskedImage.h:77
virtual double operator()(std::vector< double > const &params) const
NaiveDipoleCentroid(Control const &ctrl, std::string const &name, afw::table::Schema &schema)
int const POSCENTYPAR(4)
int getMaxY() const
Definition: Box.h:129
int _numPositive
void fail(afw::table::SourceRecord &measRecord, meas::base::MeasurementError *error=NULL) const
number of sample points
Definition: Statistics.h:66
double _varPositive
int getMinX() const
Definition: Box.h:124
A set of pixels in an Image.
Definition: Footprint.h:70
int isfinite(T t)
Definition: ieee.h:100
boost::shared_ptr< lsst::afw::detection::Psf > getPsf()
Return the Exposure&#39;s Psf object.
Definition: Exposure.h:224
void fail(afw::table::SourceRecord &measRecord, meas::base::MeasurementError *error=NULL) const
int x
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
int const POSFLUXPAR(5)
int _numNegative
int const NEGCENTYPAR(1)
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
boost::shared_ptr< Footprint > getFootprint() const
Definition: Source.h:89
Statistics makeStatistics(afwImage::Mask< afwImage::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl)
Specialization to handle Masks.
Definition: Statistics.cc:1023
void set(Key< T > const &key, U const &value)
Set value of a field for the given key.
Definition: BaseRecord.h:136
double _sumPositive
Record class that contains measurements made on a single exposure.
Definition: Source.h:81
afw::table::SourceRecord & _source
A polymorphic base class for representing an image&#39;s Point Spread Function.
Definition: Psf.h:68
A functor class to allow users to process all the pixels in a Footprint.
A class to represent a 2-dimensional array of pixels.
Definition: PSF.h:43
Include files required for standard LSST Exception handling.
void measure(afw::table::SourceRecord &measRecord, afw::image::Exposure< float > const &exposure) const