LSSTApplications  10.0-2-g4f67435,11.0.rc2+1,11.0.rc2+12,11.0.rc2+3,11.0.rc2+4,11.0.rc2+5,11.0.rc2+6,11.0.rc2+7,11.0.rc2+8
LSSTDataManagementBasePackage
PeakLikelihoodFlux.cc
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
2 /*
3  * LSST Data Management System
4  * Copyright 2008-2013 LSST Corporation.
5  *
6  * This product includes software developed by the
7  * LSST Project (http://www.lsst.org/).
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the LSST License Statement and
20  * the GNU General Public License along with this program. If not,
21  * see <http://www.lsstcorp.org/LegalNotices/>.
22  */
23 
24 #include "ndarray/eigen.h"
25 
26 #include "lsst/afw/detection/Psf.h"
27 #include "lsst/afw/geom/Box.h"
28 #include "lsst/pex/exceptions.h"
29 #include "lsst/afw/geom.h"
30 #include "lsst/afw/image.h"
31 #include "lsst/afw/math.h"
32 
34 #include "lsst/afw/table/Source.h"
35 
36 namespace lsst { namespace meas { namespace base {
37 
38 namespace {
39 
40 /************************************************************************************************************/
57 class PsfAttributes {
58 public:
59  enum Method { ADAPTIVE_MOMENT,
60  FIRST_MOMENT,
61  SECOND_MOMENT,
62  NOISE_EQUIVALENT,
63  BICKERTON
64  };
65 
66  PsfAttributes(CONST_PTR(lsst::afw::detection::Psf) psf, int const iX, int const iY);
67  PsfAttributes(CONST_PTR(lsst::afw::detection::Psf) psf, lsst::afw::geom::Point2I const& cen);
68 
69  double computeGaussianWidth(Method how=ADAPTIVE_MOMENT) const;
70  double computeEffectiveArea() const;
71 
72 private:
74 };
75 
79 PsfAttributes::PsfAttributes(
80  CONST_PTR(lsst::afw::detection::Psf) psf,
81  int const iX,
82  int const iY
83  )
84 {
85  // N.b. (iX, iY) are ints so that we know this image is centered in the central pixel of _psfImage
86  _psfImage = psf->computeImage(afw::geom::PointD(iX, iY));
87 }
88 
92 PsfAttributes::PsfAttributes(
94  lsst::afw::geom::Point2I const& cen
95  ) :
96  // N.b. cen is a PointI so that we know this image is centered in the central pixel of _psfImage
97  _psfImage(psf->computeImage(afw::geom::PointD(cen)))
98 {
99 }
100 
105 double PsfAttributes::computeEffectiveArea() const {
106 
107  double sum = 0.0;
108  double sumsqr = 0.0;
109  for (int iY = 0; iY != _psfImage->getHeight(); ++iY) {
110  afw::image::Image<double>::x_iterator end = _psfImage->row_end(iY);
111  for (afw::image::Image<double>::x_iterator ptr = _psfImage->row_begin(iY); ptr != end; ++ptr) {
112  sum += *ptr;
113  sumsqr += (*ptr)*(*ptr);
114  }
115  }
116  return sum*sum/sumsqr;
117 }
118 
119 } // end anonymous namespace
120 
128 template<typename T>
130  afw::image::MaskedImage<T> const &maskedImage,
131  std::string const &warpingKernelName,
132  afw::geom::Point2D const &fracShift,
133  afw::geom::Point2I const &parentInd
134 ) {
135  typedef typename afw::image::Exposure<T>::MaskedImageT MaskedImageT;
136  typedef typename afw::image::Image<double> KernelImageT;
137 
138  PTR(afw::math::SeparableKernel) warpingKernelPtr = afw::math::makeWarpingKernel(warpingKernelName);
139 
140  if ((std::abs(fracShift[0]) >= 1) || (std::abs(fracShift[1]) >= 1)) {
141  std::ostringstream os;
142  os << "fracShift = " << fracShift << " too large; abs value must be < 1 in both axes";
143  throw LSST_EXCEPT(pex::exceptions::RangeError, os.str());
144  }
145 
146  // warping kernels have even dimension and want the peak to the right of center
147  if (fracShift[0] < 0) {
148  warpingKernelPtr->setCtrX(warpingKernelPtr->getCtrX() + 1);
149  }
150  if (fracShift[1] < 0) {
151  warpingKernelPtr->setCtrY(warpingKernelPtr->getCtrY() + 1);
152  }
153  afw::geom::Box2I warpingOverlapBBox(
154  parentInd - afw::geom::Extent2I(warpingKernelPtr->getCtr()),
155  warpingKernelPtr->getDimensions());
156  if (!maskedImage.getBBox().contains(warpingOverlapBBox)) {
157  std::ostringstream os;
158  os << "Warping kernel extends off the edge"
159  << "; kernel bbox = " << warpingOverlapBBox
160  << "; exposure bbox = " << maskedImage.getBBox();
161  throw LSST_EXCEPT(pex::exceptions::RangeError, os.str());
162  }
163  warpingKernelPtr->setKernelParameters(std::make_pair(fracShift[0], fracShift[1]));
164  KernelImageT warpingKernelImage(warpingKernelPtr->getDimensions());
165  warpingKernelPtr->computeImage(warpingKernelImage, true);
166  typename KernelImageT::const_xy_locator const warpingKernelLoc = warpingKernelImage.xy_at(0,0);
167 
168  // Compute imLoc: an image locator that matches kernel locator (0,0) such that
169  // image ctrPix overlaps center of warping kernel
170  afw::geom::Point2I subimMin = warpingOverlapBBox.getMin();
171  typename MaskedImageT::const_xy_locator const mimageLoc = maskedImage.xy_at(subimMin.getX(), subimMin.getY());
172  return afw::math::convolveAtAPoint<MaskedImageT, MaskedImageT>(
173  mimageLoc, warpingKernelLoc, warpingKernelPtr->getWidth(), warpingKernelPtr->getHeight());
174 }
175 PeakLikelihoodFluxAlgorithm::PeakLikelihoodFluxAlgorithm(
176  Control const & ctrl,
177  std::string const & name,
179 ) : _ctrl(ctrl),
180  _fluxResultKey(
181  FluxResultKey::addFields(schema, name, "flux from PeakLikelihood Flux algorithm")
182  ),
183  _centroidExtractor(schema, name)
184 {
185  static boost::array<FlagDefinition,N_FLAGS> const flagDefs = {{
186  {"flag", "general failure flag, set if anything went wrong"}
187  }};
188  _flagHandler = FlagHandler::addFields(schema, name, flagDefs.begin(), flagDefs.end());
189 }
190 
192  afw::table::SourceRecord & measRecord,
193  afw::image::Exposure<float> const & exposure
194 ) const {
195  // get the value from the centroid slot only
196  afw::geom::Point2D center = _centroidExtractor(measRecord, _flagHandler);
197  FluxResult result;
198  typedef afw::image::Exposure<float>::MaskedImageT MaskedImageT;
199  MaskedImageT const& mimage = exposure.getMaskedImage();
200 
211  if (!exposure.hasPsf()) {
212  throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, "exposure has no PSF");
213  }
214  PTR(afw::detection::Psf const) psfPtr = exposure.getPsf();
215  if (!afw::geom::Box2D(mimage.getBBox()).contains(center)) {
216  std::ostringstream os;
217  os << "Center = " << center << " not in exposure bbox" << mimage.getBBox();
218  throw LSST_EXCEPT(pex::exceptions::RangeError, os.str());
219  }
220 
221  // compute parent index and fractional offset of ctrPix: the pixel closest to "center",
222  // the centroid of the source
223  std::pair<int, double> const xCtrPixParentIndFrac = afw::image::positionToIndex(center.getX(), true);
224  std::pair<int, double> const yCtrPixParentIndFrac = afw::image::positionToIndex(center.getY(), true);
225 
226  afw::geom::Point2I ctrPixParentInd(xCtrPixParentIndFrac.first, yCtrPixParentIndFrac.first);
227  afw::geom::Point2D ctrPixPos(
228  afw::image::indexToPosition(ctrPixParentInd[0]),
229  afw::image::indexToPosition(ctrPixParentInd[1])
230  );
231 
232  // compute weight = 1/sum(PSF^2) for PSF at ctrPix, where PSF is normalized to a sum of 1
233  PsfAttributes psfAttr(psfPtr, ctrPixParentInd);
234  double weight = psfAttr.computeEffectiveArea();
235 
236  /*
237  * Compute value of image at center of source, as shifted by a fractional pixel to center the source
238  * on ctrPix.
239  */
240  MaskedImageT::SinglePixel mimageCtrPix = computeShiftedValue(
241  mimage,
243  afw::geom::Point2D(xCtrPixParentIndFrac.second, yCtrPixParentIndFrac.second),
244  ctrPixParentInd
245  );
246  double flux = mimageCtrPix.image()*weight;
247  double var = mimageCtrPix.variance()*weight*weight;
248  result.flux = flux;
249  result.fluxSigma = std::sqrt(var);
250  measRecord.set(_fluxResultKey, result);
251  _flagHandler.setValue(measRecord, FAILURE, false);
252 
253 }
254 
256  _flagHandler.handleFailure(measRecord, error);
257 }
258 
259 }}} // namespace lsst::meas::base
An include file to include the public header files for lsst::afw::math.
Defines the fields and offsets for a table.
Definition: Schema.h:46
MaskedImageT getMaskedImage()
Return the MaskedImage.
Definition: Exposure.h:150
An include file to include the header files for lsst::afw::geom.
#define PTR(...)
Definition: base.h:41
double indexToPosition(double ind)
Convert image index to image position.
Definition: ImageUtils.h:54
table::Key< std::string > name
Definition: ApCorrMap.cc:71
Eigen matrix objects that present a view into an ndarray::Array.
tbl::Key< double > weight
virtual void fail(afw::table::SourceRecord &measRecord, MeasurementError *error=NULL) const
int positionToIndex(double pos)
Convert image position to nearest integer index.
Definition: ImageUtils.h:69
boost::shared_ptr< SeparableKernel > makeWarpingKernel(std::string name)
Return a warping kernel given its name.
#define CONST_PTR(...)
Definition: base.h:47
A kernel described by a pair of functions: func(x, y) = colFunc(x) * rowFunc(y)
Definition: Kernel.h:986
A single pixel of the same type as a MaskedImage.
Definition: Pixel.h:63
Exception to be thrown when a measurement algorithm experiences a known failure mode.
Definition: exceptions.h:48
C++ control object for peak likelihood flux.
boost::enable_if< typename ExpressionTraits< Scalar >::IsScalar, Scalar >::type sum(Scalar const &scalar)
Definition: operators.h:1250
An integer coordinate rectangle.
Definition: Box.h:53
def error
Definition: log.py:108
An include file to include the header files for lsst::afw::image.
boost::shared_ptr< lsst::afw::image::Image< double > > _psfImage
xy_locator xy_at(int x, int y) const
Return an xy_locator at the point (x, y)
Definition: MaskedImage.h:1039
virtual void measure(afw::table::SourceRecord &measRecord, afw::image::Exposure< float > const &exposure) const
geom::Box2I getBBox(ImageOrigin const origin=PARENT) const
Definition: MaskedImage.h:905
A class to manipulate images, masks, and variance as a single object.
Definition: MaskedImage.h:77
Flux flux
Measured flux in DN.
Definition: FluxUtilities.h:38
void setValue(afw::table::BaseRecord &record, int i, bool value) const
Definition: FlagHandler.h:72
bool contains(Point2I const &point) const
Return true if the box contains the point.
tbl::Schema schema
A FunctorKey for FluxResult.
Definition: FluxUtilities.h:56
boost::shared_ptr< lsst::afw::detection::Psf > getPsf()
Return the Exposure&#39;s Psf object.
Definition: Exposure.h:224
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
tbl::Key< std::string > warpingKernelName
Definition: CoaddPsf.cc:320
std::string warpingKernelName
&quot;Name of warping kernel (e.g. \&quot;lanczos4") used to compute the peak" ;
void set(Key< T > const &key, U const &value)
Set value of a field for the given key.
Definition: BaseRecord.h:136
void handleFailure(afw::table::BaseRecord &record, MeasurementError const *error=NULL) const
Definition: FlagHandler.cc:59
Point< double, 2 > PointD
Definition: Point.h:285
bool hasPsf() const
Does this Exposure have a Psf?
Definition: Exposure.h:229
afw::image::MaskedImage< T >::SinglePixel computeShiftedValue(afw::image::MaskedImage< T > const &maskedImage, std::string const &warpingKernelName, afw::geom::Point2D const &fracShift, afw::geom::Point2I const &parentInd)
Record class that contains measurements made on a single exposure.
Definition: Source.h:81
A floating-point coordinate rectangle geometry.
Definition: Box.h:271
A polymorphic base class for representing an image&#39;s Point Spread Function.
Definition: Psf.h:68
FluxErrElement fluxSigma
1-Sigma error (sqrt of variance) on flux in DN.
Definition: FluxUtilities.h:39
A class to represent a 2-dimensional array of pixels.
Definition: PSF.h:43
static FlagHandler addFields(afw::table::Schema &schema, std::string const &prefix, FlagDefinition const *begin, FlagDefinition const *end)
Definition: FlagHandler.cc:28
A reusable result struct for flux measurements.
Definition: FluxUtilities.h:37
Include files required for standard LSST Exception handling.