LSSTApplications  8.0.0.0+107,8.0.0.1+13,9.1+18,9.2,master-g084aeec0a4,master-g0aced2eed8+6,master-g15627eb03c,master-g28afc54ef9,master-g3391ba5ea0,master-g3d0fb8ae5f,master-g4432ae2e89+36,master-g5c3c32f3ec+17,master-g60f1e072bb+1,master-g6a3ac32d1b,master-g76a88a4307+1,master-g7bce1f4e06+57,master-g8ff4092549+31,master-g98e65bf68e,master-ga6b77976b1+53,master-gae20e2b580+3,master-gb584cd3397+53,master-gc5448b162b+1,master-gc54cf9771d,master-gc69578ece6+1,master-gcbf758c456+22,master-gcec1da163f+63,master-gcf15f11bcc,master-gd167108223,master-gf44c96c709
LSSTDataManagementBasePackage
SincFlux.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/pex/exceptions.h"
29 #include "lsst/afw/table/Source.h"
32 
33 namespace pexExceptions = lsst::pex::exceptions;
34 namespace afwDet = lsst::afw::detection;
35 namespace afwImage = lsst::afw::image;
36 namespace afwMath = lsst::afw::math;
37 namespace afwGeom = lsst::afw::geom;
38 
39 namespace lsst { namespace meas { namespace base {
40 
41 namespace {
42 
43 template <typename MaskedImageT, typename WeightImageT>
44 class FootprintWeightFlux : public afwDet::FootprintFunctor<MaskedImageT> {
45 public:
46  FootprintWeightFlux(
47  MaskedImageT const& mimage,
48  typename WeightImageT::Ptr wimage
49  ) :
50  afwDet::FootprintFunctor<MaskedImageT>(mimage),
51  _wimage(wimage),
52  _sum(0.0), _sumVar(0.0),
53  _x0(wimage->getX0()), _y0(wimage->getY0()) {}
54 
56  void reset() {}
57  void reset(afwDet::Footprint const& foot) {
58  _sum = 0.0;
59  _sumVar = 0.0;
60 
61  afwGeom::BoxI const& bbox(foot.getBBox());
62  _x0 = bbox.getMinX();
63  _y0 = bbox.getMinY();
64 
65  if (bbox.getDimensions() != _wimage->getDimensions()) {
66  throw LSST_EXCEPT(pexExceptions::LengthError,
67  (boost::format("Footprint at %d,%d -- %d,%d is wrong size "
68  "for %d x %d weight image") %
69  bbox.getMinX() % bbox.getMinY() % bbox.getMaxX() % bbox.getMaxY() %
70  _wimage->getWidth() % _wimage->getHeight()).str());
71  }
72  }
73 
75  void operator()(typename MaskedImageT::xy_locator iloc,
76  int x,
77  int y
78  ) {
79  typename MaskedImageT::Image::Pixel ival = iloc.image(0, 0);
80  typename MaskedImageT::Image::Pixel vval = iloc.variance(0, 0);
81  typename WeightImageT::Pixel wval = (*_wimage)(x - _x0, y - _y0);
82  _sum += wval*ival;
83  _sumVar += wval*wval*vval;
84  }
85 
87  double getSum() const { return _sum; }
88  double getSumVar() const { return _sumVar; }
89 
90 private:
91  typename WeightImageT::Ptr const& _wimage; // The weight image
92  double _sum; // our desired sum
93  double _sumVar; // sum of the variance
94  int _x0, _y0; // the origin of the current Footprint
95 };
96 
97 /************************************************************************************************************/
98 
102 template<typename MaskedImageT>
103 std::pair<double, double>
104 calculateSincApertureFlux(MaskedImageT const& mimage, afw::geom::ellipses::Ellipse const& ellipse,
105  double const innerFactor)
106 {
107  double flux = std::numeric_limits<double>::quiet_NaN();
108  double fluxErr = std::numeric_limits<double>::quiet_NaN();
109 
110  typedef typename MaskedImageT::Image Image;
111  typedef typename Image::Pixel Pixel;
112  typedef typename Image::Ptr ImagePtr;
113 
114  // BBox for data image
115  afwGeom::BoxI imageBBox(mimage.getBBox());
116 
117 
118  // make the coeff image
119  // compute c_i as double integral over aperture def g_i(), and sinc()
120  CONST_PTR(Image) cimage0 = SincCoeffs<Pixel>::get(ellipse.getCore(), innerFactor);
121 
122  // as long as we're asked for the same radius, we don't have to recompute cimage0
123  // shift to center the aperture on the object being measured
124  ImagePtr cimage = afwMath::offsetImage(*cimage0, ellipse.getCenter().getX(), ellipse.getCenter().getY());
125  afwGeom::BoxI bbox(cimage->getBBox());
126 #if 0
127  // I (Steve Bickerton) think this should work, but doesn't.
128  // For the time being, I'll do the bounds check here
129  // ... should determine why bbox/image behaviour not as expected.
130  afwGeom::BoxI mbbox(mimage.getBBox());
131  bbox.clip(mbbox);
132  afwGeom::Point2I cimXy0(cimage->getXY0());
133  bbox.shift(-cimage->getX0(), -cimage->getY0());
134  cimage = typename Image::Ptr(new Image(*cimage, bbox, false));
135  cimage->setXY0(cimXy0);
136 #else
137  int x1 = (cimage->getX0() < mimage.getX0()) ? mimage.getX0() : cimage->getX0();
138  int y1 = (cimage->getY0() < mimage.getY0()) ? mimage.getY0() : cimage->getY0();
139  int x2 = (cimage->getX0() + cimage->getWidth() > mimage.getX0() + mimage.getWidth()) ?
140  mimage.getX0() + mimage.getWidth() - 1 : cimage->getX0() + cimage->getWidth() - 1;
141  int y2 = (cimage->getY0() + cimage->getHeight() > mimage.getY0() + mimage.getHeight()) ?
142  mimage.getY0() + mimage.getHeight() - 1 : cimage->getY0() + cimage->getHeight() - 1;
143 
144  // if the dimensions changed, put the image in a smaller bbox
145  if ( (x2 - x1 + 1 != cimage->getWidth()) || (y2 - y1 + 1 != cimage->getHeight()) ) {
146  bbox = afwGeom::BoxI(afwGeom::Point2I(x1 - cimage->getX0(), y1 - cimage->getY0()),
147  afwGeom::Extent2I(x2 - x1 + 1, y2 - y1 + 1));
148  cimage = ImagePtr(new Image(*cimage, bbox, afwImage::LOCAL, false));
149 
150  // shift back to correct place
151  cimage = afwMath::offsetImage(*cimage, x1, y1);
152  bbox = afwGeom::BoxI(afwGeom::Point2I(x1, y1),
153  afwGeom::Extent2I(x2-x1+1, y2-y1+1));
154  }
155 #endif
156 
157  // pass the image and cimage into the wfluxFunctor to do the sum
158  FootprintWeightFlux<MaskedImageT, Image> wfluxFunctor(mimage, cimage);
159 
160  afwDet::Footprint foot(bbox, imageBBox);
161  wfluxFunctor.apply(foot);
162  flux = wfluxFunctor.getSum();
163  fluxErr = ::sqrt(wfluxFunctor.getSumVar());
164 
165  return std::make_pair(flux, fluxErr);
166 }
167 
168 } // anonymous
169 
171  Control const & ctrl,
172  std::string const & name,
174 ) : _ctrl(ctrl),
175  _fluxResultKey(
176  FluxResultKey::addFields(schema, name, "flux from Sinc Flux algorithm")
177  ),
178  _centroidExtractor(schema, name)
179 {
180  static boost::array<FlagDefinition,N_FLAGS> const flagDefs = {{
181  {"flag", "general failure flag, set if anything went wrong"},
182  }};
183  _flagHandler = FlagHandler::addFields(schema, name, flagDefs.begin(), flagDefs.end());
184 }
185 
187  afw::table::SourceRecord & measRecord,
188  afw::image::Exposure<float> const & exposure
189 ) const {
190  // get the value from the centroid slot only
191  afw::geom::Point2D center = _centroidExtractor(measRecord, _flagHandler);
192  FluxResult result;
193 
195  std::pair<double, double> fluxes = calculateSincApertureFlux(exposure.getMaskedImage(),
196  afw::geom::ellipses::Ellipse(axes, center),
198  double flux = fluxes.first;
199  double fluxErr = fluxes.second;
200  result.flux = flux;
201  result.fluxSigma = fluxErr;
202 
203  // End of meas_algorithms code
204 
205  measRecord.set(_fluxResultKey, result);
206  _flagHandler.setValue(measRecord, FAILURE, false);
207 }
208 
209 
211  _flagHandler.handleFailure(measRecord, error);
212 }
213 
214 }}} // namespace lsst::meas::base
215 
Defines the fields and offsets for a table.
Definition: Schema.h:46
SafeCentroidExtractor _centroidExtractor
Definition: SincFlux.h:108
static boost::shared_ptr< CoeffT const > get(afw::geom::ellipses::Axes const &outerEllipse, float const innerRadiusFactor=0.0)
Definition: SincCoeffs.cc:532
WeightImageT::Ptr const & _wimage
Definition: NaiveFlux.cc:116
Eigen matrix objects that present a view into an ndarray::Array.
virtual void fail(afw::table::SourceRecord &measRecord, MeasurementError *error=NULL) const
Definition: SincFlux.cc:210
double _sum
Definition: NaiveFlux.cc:67
int y
Box2I BoxI
Definition: Box.h:479
A class to contain the data, WCS, and other information needed to describe an image of the sky...
Definition: Exposure.h:48
double _sumVar
Definition: NaiveFlux.cc:68
int _y0
Definition: NaiveFlux.cc:119
Exception to be thrown when a measurement algorithm experiences a known failure mode.
Definition: exceptions.h:48
An integer coordinate rectangle.
Definition: Box.h:53
table::Key< table::Array< Kernel::Pixel > > image
Definition: FixedKernel.cc:117
std::pair< double, double > calculateSincApertureFlux(MaskedImageT const &mimage, afw::geom::ellipses::Ellipse const &ellipse, double const innerFactor)
Definition: SincFlux.cc:687
Include files required for standard LSST Exception handling.
A C++ control class to handle SincFluxAlgorithm&#39;s configuration.
Definition: SincFlux.h:46
MaskedImageT getMaskedImage()
Return the MaskedImage.
Definition: Exposure.h:150
tbl::Schema schema
Definition: CoaddPsf.cc:324
SincFluxAlgorithm(Control const &ctrl, std::string const &name, afw::table::Schema &schema)
Definition: SincFlux.cc:170
void shift(Extent< T, N > const &offset)
Shift the point by the given offset.
Definition: Point.h:110
int x
virtual void measure(afw::table::SourceRecord &measRecord, afw::image::Exposure< float > const &exposure) const
Definition: SincFlux.cc:186
An ellipse defined by an arbitrary BaseCore and a center point.
Definition: Ellipse.h:50
Flux flux
Measured flux in DN.
Definition: FluxUtilities.h:37
void setValue(afw::table::BaseRecord &record, int i, bool value) const
Definition: FlagHandler.h:72
double radius2
&quot;major axis of outer boundary (pixels)&quot; ;
Definition: SincFlux.h:50
int _x0
Definition: NaiveFlux.cc:119
#define CONST_PTR(...)
Definition: base.h:47
A FunctorKey for FluxResult.
Definition: FluxUtilities.h:55
A set of pixels in an Image.
Definition: Footprint.h:73
ImageT::Ptr offsetImage(ImageT const &image, float dx, float dy, std::string const &algorithmName="lanczos5", unsigned int buffer=0)
Return an image offset by (dx, dy) using the specified algorithm.
Definition: offsetImage.cc:55
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
An ellipse core for the semimajor/semiminor axis and position angle parametrization (a...
Definition: Axes.h:45
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
Record class that contains measurements made on a single exposure.
Definition: Source.h:81
void clip(Box2I const &other)
Shrink this to ensure that other.contains(*this).
FluxErrElement fluxSigma
1-Sigma error (sqrt of variance) on flux in DN.
Definition: FluxUtilities.h:38
A functor class to allow users to process all the pixels in a Footprint.
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:36
geom::Box2I getBBox() const
Return the Footprint&#39;s bounding box.
Definition: Footprint.h:194
double radius1
&quot;major axis of inner boundary (pixels)&quot; ;
Definition: SincFlux.h:49