lsst.meas.extensions.photometryKron  19.0.0-1-ga3b31f8+3
KronPhotometry.cc
Go to the documentation of this file.
1 // -*- LSST-C++ -*-
2 /*
3  * LSST Data Management System
4  * Copyright 2008-2015 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 <numeric>
25 #include <cmath>
26 #include <functional>
27 #include "boost/math/constants/constants.hpp"
28 #include "lsst/pex/exceptions.h"
29 #include "lsst/geom/Point.h"
30 #include "lsst/geom/Box.h"
31 #include "lsst/afw/geom/SpanSet.h"
33 #include "lsst/afw/table/Source.h"
37 #include "lsst/afw/detection/Psf.h"
39 #include "lsst/afw/geom/ellipses.h"
40 #include "lsst/meas/base.h"
42 
44 
45 namespace lsst {
46 namespace meas {
47 namespace extensions {
48 namespace photometryKron {
49 
50 namespace {
51 base::FlagDefinitionList flagDefinitions;
52 } // end anonymous
53 
54 base::FlagDefinition const KronFluxAlgorithm::FAILURE = flagDefinitions.addFailureFlag( "general failure flag, set if anything went wrong");
55 base::FlagDefinition const KronFluxAlgorithm::EDGE = flagDefinitions.add("flag_edge", "bad measurement due to image edge");
56 base::FlagDefinition const KronFluxAlgorithm::BAD_SHAPE_NO_PSF = flagDefinitions.add("flag_bad_shape_no_psf", "bad shape and no PSF");
57 base::FlagDefinition const KronFluxAlgorithm::NO_MINIMUM_RADIUS = flagDefinitions.add("flag_no_minimum_radius", "minimum radius could not enforced: no minimum value or PSF");
58 base::FlagDefinition const KronFluxAlgorithm::NO_FALLBACK_RADIUS = flagDefinitions.add("flag_no_fallback_radius", "no minimum radius and no PSF provided");
59 base::FlagDefinition const KronFluxAlgorithm::BAD_RADIUS = flagDefinitions.add("flag_bad_radius", "bad Kron radius");
60 base::FlagDefinition const KronFluxAlgorithm::USED_MINIMUM_RADIUS = flagDefinitions.add("flag_used_minimum_radius", "used the minimum radius for the Kron aperture");
61 base::FlagDefinition const KronFluxAlgorithm::USED_PSF_RADIUS = flagDefinitions.add("flag_used_psf_radius", "used the PSF Kron radius for the Kron aperture");
62 base::FlagDefinition const KronFluxAlgorithm::SMALL_RADIUS = flagDefinitions.add("flag_small_radius", "measured Kron radius was smaller than that of the PSF");
63 base::FlagDefinition const KronFluxAlgorithm::BAD_SHAPE = flagDefinitions.add("flag_bad_shape", "shape for measuring Kron radius is bad; used PSF shape");
64 
66  return flagDefinitions;
67 }
68 
71 
72 namespace {
73 
74 template <typename MaskedImageT>
75  class FootprintFlux {
76 public:
77  explicit FootprintFlux() : _sum(0.0), _sumVar(0.0) {}
78 
80  void reset() {
81  _sum = _sumVar = 0.0;
82  }
83  void reset(afw::detection::Footprint const&) {}
84 
86  void operator()(geom::Point2I const & pos,
87  typename MaskedImageT::Image::Pixel const & ival,
88  typename MaskedImageT::Variance::Pixel const & vval) {
89  _sum += ival;
90  _sumVar += vval;
91  }
92 
94  double getSum() const { return _sum; }
95 
97  double getSumVar() const { return _sumVar; }
98 
99 private:
100  double _sum;
101  double _sumVar;
102 };
103 
104 /************************************************************************************************************/
115 template <typename MaskedImageT, typename WeightImageT>
116 class FootprintFindMoment {
117 public:
118  FootprintFindMoment(MaskedImageT const& mimage,
119  geom::Point2D const& center, // center of the object
120  double const ab, // axis ratio
121  double const theta // rotation of ellipse +ve from x axis
122  ) : _xcen(center.getX()), _ycen(center.getY()),
123  _ab(ab),
124  _cosTheta(::cos(theta)),
125  _sinTheta(::sin(theta)),
126  _sum(0.0), _sumR(0.0),
127 #if 0
128  _sumVar(0.0), _sumRVar(0.0),
129 #endif
130  _imageX0(mimage.getX0()), _imageY0(mimage.getY0())
131  {}
132 
134  void reset() {}
135  void reset(afw::detection::Footprint const& foot) {
136  _sum = _sumR = 0.0;
137 #if 0
138  _sumVar = _sumRVar = 0.0;
139 #endif
140 
141  MaskedImageT const& mimage = this->getImage();
142  geom::Box2I const& bbox(foot.getBBox());
143  int const x0 = bbox.getMinX(), y0 = bbox.getMinY(), x1 = bbox.getMaxX(), y1 = bbox.getMaxY();
144 
145  if (x0 < _imageX0 || y0 < _imageY0 ||
146  x1 >= _imageX0 + mimage.getWidth() || y1 >= _imageY0 + mimage.getHeight()) {
148  (boost::format("Footprint %d,%d--%d,%d doesn't fit in image %d,%d--%d,%d")
149  % x0 % y0 % x1 % y1
150  % _imageX0 % _imageY0
151  % (_imageX0 + mimage.getWidth() - 1) % (_imageY0 + mimage.getHeight() - 1)
152  ).str());
153  }
154  }
155 
157  void operator()(geom::Point2I const & pos, typename MaskedImageT::Image::Pixel const & ival) {
158  double x = static_cast<double>(pos.getX());
159  double y = static_cast<double>(pos.getY());
160  double const dx = x - _xcen;
161  double const dy = y - _ycen;
162  double const du = dx*_cosTheta + dy*_sinTheta;
163  double const dv = -dx*_sinTheta + dy*_cosTheta;
164 
165  double r = ::hypot(du, dv*_ab); // ellipsoidal radius
166 #if 1
167  if (::hypot(dx, dy) < 0.5) { // within a pixel of the centre
168  /*
169  * We gain significant precision for flattened Gaussians by treating the central pixel specially
170  *
171  * If the object's centered in the pixel (and has constant surface brightness) we have <r> == eR;
172  * if it's at the corner <r> = 2*eR; we interpolate between these exact results linearily in the
173  * displacement. And then add in quadrature which is also a bit dubious
174  *
175  * We could avoid all these issues by estimating <r> using the same trick as we use for
176  * the sinc fluxes; it's not clear that it's worth it.
177  */
178 
179  double const eR = 0.38259771140356325; // <r> for a single square pixel, about the centre
180  r = ::hypot(r, eR*(1 + ::hypot(dx, dy)/geom::ROOT2));
181  }
182 #endif
183 
184  _sum += ival;
185  _sumR += r*ival;
186 #if 0
187  typename MaskedImageT::Variance::Pixel vval = iloc.variance(0, 0);
188  _sumVar += vval;
189  _sumRVar += r*r*vval;
190 #endif
191  }
192 
194  double getIr() const { return _sumR/_sum; }
195 
196 #if 0
197 // double getIrVar() const { return _sumRVar/_sum - getIr()*getIr(); } // Wrong?
199  double getIrVar() const { return _sumRVar/(_sum*_sum) + _sumVar*_sumR*_sumR/::pow(_sum, 4); }
200 #endif
201 
203  bool getGood() const { return _sum > 0 && _sumR > 0; }
204 
205 private:
206  double const _xcen; // center of object
207  double const _ycen; // center of object
208  double const _ab; // axis ratio
209  double const _cosTheta, _sinTheta; // {cos,sin}(angle from x-axis)
210  double _sum; // sum of I
211  double _sumR; // sum of R*I
212 #if 0
213  double _sumVar; // sum of Var(I)
214  double _sumRVar; // sum of R*R*Var(I)
215 #endif
216  int const _imageX0, _imageY0; // origin of image we're measuring
217 
218 };
219 } // end anonymous namespace
220 
222  afw::geom::ellipses::Axes const& shape,
223  geom::LinearTransform const& transformation,
224  double const radius
225  )
226 {
227  afw::geom::ellipses::Axes axes(shape);
228  axes.scale(radius/axes.getDeterminantRadius());
229  return axes.transform(transformation);
230 }
231 
232 template<typename ImageT>
234  ImageT const& image,
236  geom::Point2D const& center,
237  KronFluxControl const& ctrl
238  )
239 {
240  //
241  // We might smooth the image because this is what SExtractor and Pan-STARRS do. But I don't see much gain
242  //
243  double const sigma = ctrl.smoothingSigma; // Gaussian width of smoothing sigma to apply
244  bool const smoothImage = sigma > 0;
245  int kSize = smoothImage ? 2*int(2*sigma) + 1 : 1;
246  afw::math::GaussianFunction1<afw::math::Kernel::Pixel> gaussFunc(smoothImage ? sigma : 100);
247  afw::math::SeparableKernel kernel(kSize, kSize, gaussFunc, gaussFunc);
248  bool const doNormalize = true, doCopyEdge = false;
249  afw::math::ConvolutionControl convCtrl(doNormalize, doCopyEdge);
250  double radius0 = axes.getDeterminantRadius();
251  double radius = std::numeric_limits<double>::quiet_NaN();
252  float radiusForRadius = std::nanf("");
253  for (int i = 0; i < ctrl.nIterForRadius; ++i) {
254  axes.scale(ctrl.nSigmaForRadius);
255  radiusForRadius = axes.getDeterminantRadius(); // radius we used to estimate R_K
256  //
257  // Build an elliptical Footprint of the proper size
258  //
260  afw::geom::ellipses::Ellipse(axes, center)));
261  geom::Box2I bbox = !smoothImage ?
262  foot.getBBox() :
263  kernel.growBBox(foot.getBBox()); // the smallest bbox needed to convolve with Kernel
264  bbox.clip(image.getBBox());
265  ImageT subImage(image, bbox, afw::image::PARENT, smoothImage);
266  if (smoothImage) {
267  afw::math::convolve(subImage, ImageT(image, bbox, afw::image::PARENT, false), kernel, convCtrl);
268  }
269  //
270  // Find the desired first moment of the elliptical radius, which corresponds to the major axis.
271  //
272  FootprintFindMoment<ImageT, afw::detection::Psf::Image> iRFunctor(
273  subImage, center, axes.getA()/axes.getB(), axes.getTheta()
274  );
275 
276  try {
277  foot.getSpans()->applyFunctor(
278  iRFunctor, *(subImage.getImage()));
280  if (i == 0) {
281  LSST_EXCEPT_ADD(e, "Determining Kron aperture");
282  }
283  break; // use the radius we have
284  }
285 
286  if (!iRFunctor.getGood()) {
287  throw LSST_EXCEPT(BadKronException, "Bad integral defining Kron radius");
288  }
289 
290  radius = iRFunctor.getIr()*sqrt(axes.getB()/axes.getA());
291  if (radius <= radius0) {
292  break;
293  }
294  radius0 = radius;
295 
296  axes.scale(radius/axes.getDeterminantRadius()); // set axes to our current estimate of R_K
297  iRFunctor.reset();
298  }
299 
300  return std::make_shared<KronAperture>(center, axes, radiusForRadius);
301 }
302 
303 // Photometer an image with a particular aperture
304 template<typename ImageT>
306  ImageT const& image, // Image to measure
307  afw::geom::ellipses::Ellipse const& aperture, // Aperture in which to measure
308  double const maxSincRadius // largest radius that we use sinc apertures to measure
309  )
310 {
311  afw::geom::ellipses::Axes const& axes = aperture.getCore();
312  if (axes.getB() > maxSincRadius) {
313  FootprintFlux<ImageT> fluxFunctor;
314  auto spans = afw::geom::SpanSet::fromShape(aperture);
315  spans->applyFunctor(
316  fluxFunctor, *(image.getImage()), *(image.getVariance()));
317  return std::make_pair(fluxFunctor.getSum(), ::sqrt(fluxFunctor.getSumVar()));
318  }
319  try {
320  base::ApertureFluxResult fluxResult = base::ApertureFluxAlgorithm::computeSincFlux<float>(image, aperture);
321  return std::make_pair(fluxResult.instFlux, fluxResult.instFluxErr);
322  } catch(pex::exceptions::LengthError &e) {
323  LSST_EXCEPT_ADD(e, (boost::format("Measuring Kron flux for object at (%.3f, %.3f);"
324  " aperture radius %g,%g theta %g")
325  % aperture.getCenter().getX() % aperture.getCenter().getY()
326  % axes.getA() % axes.getB() % geom::radToDeg(axes.getTheta())).str());
327  throw e;
328  }
329 }
330 
331 
333  CONST_PTR(afw::detection::Psf) const& psf, // PSF to measure
334  geom::Point2D const& center, // Centroid of source on parent image
335  double smoothingSigma=0.0 // Gaussian sigma of smoothing applied
336  )
337 {
338  assert(psf);
339  double const radius = psf->computeShape(center).getDeterminantRadius();
340  // For a Gaussian N(0, sigma^2), the Kron radius is sqrt(pi/2)*sigma
341  return ::sqrt(geom::PI/2)*::hypot(radius, std::max(0.0, smoothingSigma));
342 }
343 
344 template<typename ImageT>
346  ImageT const& image,
347  double const nRadiusForFlux,
348  double const maxSincRadius
349  ) const
350 {
351  afw::geom::ellipses::Axes axes(getAxes()); // Copy of ellipse core, so we can scale
352  axes.scale(nRadiusForFlux);
353  afw::geom::ellipses::Ellipse const ellip(axes, getCenter());
354 
355  return photometer(image, ellip, maxSincRadius);
356 }
357 
358 /************************************************************************************************************/
359 
366  KronFluxControl const & ctrl,
367  std::string const & name,
368  afw::table::Schema & schema,
369  daf::base::PropertySet & metadata
370 ) : _name(name),
371  _ctrl(ctrl),
372  _fluxResultKey(
373  meas::base::FluxResultKey::addFields(schema, name, "flux from Kron Flux algorithm")
374  ),
375  _radiusKey(schema.addField<float>(name + "_radius", "Kron radius (sqrt(a*b))")),
376  _radiusForRadiusKey(schema.addField<float>(name + "_radius_for_radius",
377  "radius used to estimate <radius> (sqrt(a*b))")),
378  _psfRadiusKey(schema.addField<float>(name + "_psf_radius", "Radius of PSF")),
379  _centroidExtractor(schema, name, true)
380 {
382  metadata.add(name + "_nRadiusForFlux", ctrl.nRadiusForFlux);
383 }
384 
386  afw::table::SourceRecord & measRecord,
388 ) const {
389  _flagHandler.handleFailure(measRecord, error);
390 }
391 
392 void KronFluxAlgorithm::_applyAperture(
393  afw::table::SourceRecord & source,
394  afw::image::Exposure<float> const& exposure,
395  KronAperture const& aperture
396  ) const
397 {
398  double const rad = aperture.getAxes().getDeterminantRadius();
400  throw LSST_EXCEPT(
402  BAD_RADIUS.doc,
404  );
405  }
406 
408  try {
409  result = aperture.measureFlux(exposure.getMaskedImage(), _ctrl.nRadiusForFlux, _ctrl.maxSincRadius);
410  } catch (pex::exceptions::LengthError const& e) {
411  // We hit the edge of the image; there's no reasonable fallback or recovery
412  throw LSST_EXCEPT(
414  EDGE.doc,
415  EDGE.number
416  );
418  throw LSST_EXCEPT(
420  EDGE.doc,
421  EDGE.number
422  );
423  }
424 
425  // set the results in the source object
426  meas::base::FluxResult fluxResult;
427  fluxResult.instFlux = result.first;
428  fluxResult.instFluxErr = result.second;
429  source.set(_fluxResultKey, fluxResult);
430  source.set(_radiusKey, aperture.getAxes().getDeterminantRadius());
431  //
432  // REMINDER: In the old code, the psfFactor is calculated using getPsfFactor,
433  // and the values set for _fluxCorrectionKeys. See old meas_algorithms version.
434 }
435 
436 void KronFluxAlgorithm::_applyForced(
437  afw::table::SourceRecord & source,
438  afw::image::Exposure<float> const & exposure,
439  geom::Point2D const & center,
440  afw::table::SourceRecord const & reference,
441  geom::AffineTransform const & refToMeas
442  ) const
443 {
444  float const radius = reference.get(reference.getSchema().find<float>(_ctrl.refRadiusName).key);
445  KronAperture const aperture(reference, refToMeas, radius);
446  _applyAperture(source, exposure, aperture);
447  if (exposure.getPsf()) {
448  source.set(_psfRadiusKey, calculatePsfKronRadius(exposure.getPsf(), center, _ctrl.smoothingSigma));
449  }
450 }
451 
453  afw::table::SourceRecord & source,
454  afw::image::Exposure<float> const& exposure
455  ) const {
456  geom::Point2D center = _centroidExtractor(source, _flagHandler);
457 
458  // Did we hit a condition that fundamentally prevented measuring the Kron flux?
459  // Such conditions include hitting the edge of the image and bad input shape, but not low signal-to-noise.
460  bool bad = false;
461 
462  afw::image::MaskedImage<float> const& mimage = exposure.getMaskedImage();
463 
464  double R_K_psf = -1;
465  if (exposure.getPsf()) {
466  R_K_psf = calculatePsfKronRadius(exposure.getPsf(), center, _ctrl.smoothingSigma);
467  }
468 
469  //
470  // Get the shape of the desired aperture
471  //
473  if (!source.getShapeFlag()) {
474  axes = source.getShape();
475  } else {
476  bad = true;
477  if (!exposure.getPsf()) {
478  throw LSST_EXCEPT(
482  );
483  }
484  axes = exposure.getPsf()->computeShape();
485  _flagHandler.setValue(source, BAD_SHAPE.number, true);
486  }
487  if (_ctrl.useFootprintRadius) {
488  afw::geom::ellipses::Axes footprintAxes(source.getFootprint()->getShape());
489  // if the Footprint's a disk of radius R we want footRadius == R.
490  // As <r^2> = R^2/2 for a disk, we need to scale up by sqrt(2)
491  footprintAxes.scale(::sqrt(2));
492 
493  double radius0 = axes.getDeterminantRadius();
494  double const footRadius = footprintAxes.getDeterminantRadius();
495 
496  if (footRadius > radius0*_ctrl.nSigmaForRadius) {
497  radius0 = footRadius/_ctrl.nSigmaForRadius; // we'll scale it up by nSigmaForRadius
498  axes.scale(radius0/axes.getDeterminantRadius());
499  }
500  }
501 
502  PTR(KronAperture) aperture;
503  if (_ctrl.fixed) {
504  aperture.reset(new KronAperture(source));
505  } else {
506  try {
507  aperture = KronAperture::determineRadius(mimage, axes, center, _ctrl);
508  } catch (pex::exceptions::OutOfRangeError& e) {
509  // We hit the edge of the image: no reasonable fallback or recovery possible
510  throw LSST_EXCEPT(
512  EDGE.doc,
513  EDGE.number
514  );
515  } catch (BadKronException& e) {
516  // Not setting bad=true because we only failed due to low S/N
517  aperture = _fallbackRadius(source, R_K_psf, e);
518  } catch(pex::exceptions::Exception& e) {
519  bad = true; // There's something fundamental keeping us from measuring the Kron aperture
520  aperture = _fallbackRadius(source, R_K_psf, e);
521  }
522  }
523 
524  /*
525  * Estimate the minimum acceptable Kron radius as the Kron radius of the PSF or the
526  * provided minimum radius
527  */
528 
529  // Enforce constraints on minimum radius
530  double rad = aperture->getAxes().getDeterminantRadius();
531  if (_ctrl.enforceMinimumRadius) {
532  double newRadius = rad;
533  if (_ctrl.minimumRadius > 0.0) {
534  if (rad < _ctrl.minimumRadius) {
535  newRadius = _ctrl.minimumRadius;
536  _flagHandler.setValue(source, USED_MINIMUM_RADIUS.number, true);
537  }
538  } else if (!exposure.getPsf()) {
539  throw LSST_EXCEPT(
543  );
544  } else if (rad < R_K_psf) {
545  newRadius = R_K_psf;
546  _flagHandler.setValue(source, USED_PSF_RADIUS.number, true);
547  }
548  if (newRadius != rad) {
549  aperture->getAxes().scale(newRadius/rad);
550  _flagHandler.setValue(source, SMALL_RADIUS.number, true); // guilty after all
551  }
552  }
553 
554  _applyAperture(source, exposure, *aperture);
555  source.set(_radiusForRadiusKey, aperture->getRadiusForRadius());
556  source.set(_psfRadiusKey, R_K_psf);
557  if (bad) _flagHandler.setValue(source, FAILURE.number, true);
558 }
559 
561  afw::table::SourceRecord & measRecord,
562  afw::image::Exposure<float> const & exposure,
563  afw::table::SourceRecord const & refRecord,
564  afw::geom::SkyWcs const & refWcs
565  ) const {
566  geom::Point2D center = _centroidExtractor(measRecord, _flagHandler);
567  auto xytransform = afw::geom::makeWcsPairTransform(refWcs, *exposure.getWcs());
568  _applyForced(measRecord, exposure, center, refRecord,
569  linearizeTransform(*xytransform, refRecord.getCentroid())
570  );
571 
572 }
573 
574 
575 PTR(KronAperture) KronFluxAlgorithm::_fallbackRadius(afw::table::SourceRecord& source, double const R_K_psf,
576  pex::exceptions::Exception& exc) const
577 {
578  _flagHandler.setValue(source, BAD_RADIUS.number, true);
579  double newRadius;
580  if (_ctrl.minimumRadius > 0) {
581  newRadius = _ctrl.minimumRadius;
582  _flagHandler.setValue(source, USED_MINIMUM_RADIUS.number, true);
583  } else if (R_K_psf > 0) {
584  newRadius = R_K_psf;
585  _flagHandler.setValue(source, USED_PSF_RADIUS.number, true);
586  } else {
587  throw LSST_EXCEPT(
591  );
592  }
593  PTR(KronAperture) aperture(new KronAperture(source));
594  aperture->getAxes().scale(newRadius/aperture->getAxes().getDeterminantRadius());
595  return aperture;
596 }
597 
598 
599 #define INSTANTIATE(TYPE) \
600 template PTR(KronAperture) KronAperture::determineRadius<afw::image::MaskedImage<TYPE> >( \
601  afw::image::MaskedImage<TYPE> const&, \
602  afw::geom::ellipses::Axes, \
603  geom::Point2D const&, \
604  KronFluxControl const& \
605  ); \
606 template std::pair<double, double> KronAperture::measureFlux<afw::image::MaskedImage<TYPE> >( \
607  afw::image::MaskedImage<TYPE> const&, \
608  double const, \
609  double const \
610  ) const;
611 
612 INSTANTIATE(float);
613 
614 }}}} // namespace lsst::meas::extensions::photometryKron
y
int y
schema
table::Schema schema
lsst::geom::radToDeg
constexpr double radToDeg(double x) noexcept
lsst::afw::detection::Footprint::getBBox
lsst::geom::Box2I getBBox() const
lsst::afw::image::Exposure::getPsf
std::shared_ptr< lsst::afw::detection::Psf const > getPsf() const
lsst::afw::math::GaussianFunction1
std::nanf
T nanf(T... args)
lsst::meas::extensions::photometryKron::KronFluxControl::minimumRadius
double minimumRadius
"Minimum Kron radius (if == 0.0 use PSF's Kron radius) if enforceMinimumRadius. " "Also functions as ...
Definition: photometryKron.h:61
lsst::geom::PI
constexpr double PI
lsst::meas::base::FlagDefinition::number
std::size_t number
lsst::meas::extensions::photometryKron::KronFluxAlgorithm::NO_FALLBACK_RADIUS
static meas::base::FlagDefinition const NO_FALLBACK_RADIUS
Definition: photometryKron.h:96
std::string
STL class.
lsst::meas::base::ApertureFluxResult::instFlux
meas::base::Flux instFlux
Psf.h
lsst::meas::base::FlagHandler::handleFailure
void handleFailure(afw::table::BaseRecord &record, MeasurementError const *error=nullptr) const
lsst::afw::table::SourceRecord
lsst::afw::image::Exposure
lsst::afw::table::SourceRecord::getCentroid
CentroidSlotDefinition::MeasValue getCentroid() const
base
std::pair< double, double >
lsst::afw::geom::ellipses::Axes::getB
double const getB() const
lsst::meas::extensions::photometryKron::KronFluxControl::fixed
bool fixed
"if true, use existing shape and centroid measurements instead of fitting" ;
Definition: photometryKron.h:52
CONST_PTR
#define CONST_PTR(...)
Integrate.h
std::cos
T cos(T... args)
std::numeric_limits::quiet_NaN
T quiet_NaN(T... args)
lsst::daf::base::PropertySet::add
void add(std::string const &name, T const &value)
LSST_EXCEPT_ADD
#define LSST_EXCEPT_ADD(e, m)
psf
Key< int > psf
lsst::meas::base::FlagDefinition::doc
std::string doc
lsst::geom::LinearTransform
lsst::meas::extensions::photometryKron::KronFluxAlgorithm::KronFluxAlgorithm
KronFluxAlgorithm(Control const &ctrl, std::string const &name, afw::table::Schema &schema, daf::base::PropertySet &metadata)
A class that knows how to calculate fluxes using the KRON photometry algorithm.
Definition: KronPhotometry.cc:365
sigma
afw::table::Key< double > sigma
lsst::afw::detection::Footprint::getSpans
std::shared_ptr< geom::SpanSet > getSpans() const
lsst::meas::extensions::photometryKron::KronAperture::getRadiusForRadius
float getRadiusForRadius() const
Definition: photometryKron.h:185
lsst::afw::geom::ellipses::Axes::getTheta
double const getTheta() const
lsst::meas::base::MeasurementError
linearizeTransform
lsst::geom::AffineTransform linearizeTransform(TransformPoint2ToPoint2 const &original, lsst::geom::Point2D const &inPoint)
lsst::meas::extensions::photometryKron::KronFluxControl
C++ control object for Kron flux.
Definition: photometryKron.h:48
lsst::afw::table::Schema
lsst::meas::extensions::photometryKron::KronFluxControl::nSigmaForRadius
double nSigmaForRadius
"Multiplier of rms size for aperture used to initially estimate the Kron radius" ;
Definition: photometryKron.h:54
lsst::afw::geom::ellipses::Axes
lsst::afw::geom::SkyWcs
lsst::afw::math::SeparableKernel::growBBox
lsst::geom::Box2I growBBox(lsst::geom::Box2I const &bbox) const
lsst::geom::Point2D
Point< double, 2 > Point2D
base.h
lsst::afw::geom::ellipses::Axes::getDeterminantRadius
double getDeterminantRadius() const
lsst::meas::base::ApertureFluxResult
lsst::afw::image::Exposure::getMaskedImage
MaskedImageT getMaskedImage()
lsst::meas::extensions::photometryKron::KronAperture
Definition: photometryKron.h:160
lsst::meas::extensions::photometryKron::KronFluxAlgorithm::USED_PSF_RADIUS
static meas::base::FlagDefinition const USED_PSF_RADIUS
Definition: photometryKron.h:99
photometryKron.h
ellipses.h
lsst::meas::base::FlagDefinitionList
AffineTransform.h
lsst::afw::geom::ellipses::Axes::getA
double const getA() const
lsst::meas::base::ApertureFluxResult::instFluxErr
meas::base::FluxErrElement instFluxErr
FunctionLibrary.h
std::hypot
T hypot(T... args)
lsst::meas::base::FlagHandler::setValue
void setValue(afw::table::BaseRecord &record, std::size_t i, bool value) const
result
std::unique_ptr< SchemaItem< U > > result
lsst::afw::image::MaskedImage
source
const char * source()
lsst::meas::extensions::photometryKron::KronAperture::getKronAxes
static afw::geom::ellipses::Axes getKronAxes(afw::geom::ellipses::Axes const &shape, geom::LinearTransform const &transformation, double const radius)
Determine Kron axes from a reference image.
Definition: KronPhotometry.cc:221
image
afw::table::Key< afw::table::Array< ImagePixelT > > image
PTR
#define PTR(...)
INSTANTIATE
#define INSTANTIATE(TYPE)
Definition: KronPhotometry.cc:599
lsst::meas::extensions::photometryKron::KronFluxControl::nRadiusForFlux
double nRadiusForFlux
"Number of Kron radii for Kron flux" ;
Definition: photometryKron.h:56
Box.h
x
double x
lsst::afw::geom::ellipses::Ellipse::getCenter
lsst::geom::Point2D const & getCenter() const
lsst::meas::extensions::photometryKron::KronFluxAlgorithm::EDGE
static meas::base::FlagDefinition const EDGE
Definition: photometryKron.h:93
lsst::pex::exceptions::LengthError
lsst::meas::extensions::photometryKron::KronFluxControl::useFootprintRadius
bool useFootprintRadius
"Use the Footprint size as part of initial estimate of Kron radius" ;
Definition: photometryKron.h:64
lsst::meas::extensions::photometryKron::KronAperture::measureFlux
std::pair< double, double > measureFlux(ImageT const &image, double const nRadiusForFlux, double const maxSincRadius) const
Photometer within the Kron Aperture on an image.
Definition: KronPhotometry.cc:345
Point.h
lsst::meas::extensions::photometryKron::calculatePsfKronRadius
double calculatePsfKronRadius(boost::shared_ptr< afw::detection::Psf const > const &psf, geom::Point2D const &center, double smoothingSigma=0.0)
Definition: KronPhotometry.cc:332
lsst::meas::extensions::photometryKron::KronFluxAlgorithm::BAD_SHAPE
static meas::base::FlagDefinition const BAD_SHAPE
Definition: photometryKron.h:101
lsst::meas::extensions::photometryKron::KronFluxAlgorithm::measure
virtual void measure(afw::table::SourceRecord &measRecord, afw::image::Exposure< float > const &exposure) const
Definition: KronPhotometry.cc:452
lsst::meas::extensions::photometryKron::KronFluxAlgorithm::SMALL_RADIUS
static meas::base::FlagDefinition const SMALL_RADIUS
Definition: photometryKron.h:100
lsst::meas::extensions::photometryKron::KronFluxAlgorithm::BAD_SHAPE_NO_PSF
static meas::base::FlagDefinition const BAD_SHAPE_NO_PSF
Definition: photometryKron.h:94
lsst
LSST_EXCEPT
#define LSST_EXCEPT(type,...)
lsst::meas::extensions::photometryKron::KronFluxControl::enforceMinimumRadius
bool enforceMinimumRadius
"If true check that the Kron radius exceeds some minimum" ;
Definition: photometryKron.h:62
lsst::afw::math::convolve
void convolve(OutImageT &convolvedImage, InImageT const &inImage, KernelT const &kernel, ConvolutionControl const &convolutionControl=ConvolutionControl())
exceptions.h
lsst::meas::extensions::photometryKron::photometer
std::pair< double, double > photometer(ImageT const &image, afw::geom::ellipses::Ellipse const &aperture, double const maxSincRadius)
Definition: KronPhotometry.cc:305
lsst::afw::geom::ellipses::Ellipse
std::sin
T sin(T... args)
lsst::meas::extensions::photometryKron::KronFluxAlgorithm::FAILURE
static meas::base::FlagDefinition const FAILURE
Definition: photometryKron.h:92
lsst::meas::extensions::photometryKron::KronFluxAlgorithm::BAD_RADIUS
static meas::base::FlagDefinition const BAD_RADIUS
Definition: photometryKron.h:97
lsst::meas::extensions::photometryKron::KronFluxControl::refRadiusName
std::string refRadiusName
"Name of field specifying reference Kron radius for forced measurement" ;
Definition: photometryKron.h:68
lsst::afw::geom::SpanSet::fromShape
static std::shared_ptr< geom::SpanSet > fromShape(int r, Stencil s=Stencil::CIRCLE, lsst::geom::Point2I offset=lsst::geom::Point2I())
lsst::geom::ROOT2
constexpr double ROOT2
lsst::meas::extensions::photometryKron::KronAperture::getCenter
geom::Point2D const & getCenter() const
Definition: photometryKron.h:187
lsst::afw::math::ConvolutionControl
lsst::afw::geom::makeWcsPairTransform
std::shared_ptr< TransformPoint2ToPoint2 > makeWcsPairTransform(SkyWcs const &src, SkyWcs const &dst)
lsst::meas::extensions::photometryKron::KronAperture::determineRadius
static boost::shared_ptr< KronAperture > determineRadius(ImageT const &image, afw::geom::ellipses::Axes axes, geom::Point2D const &center, KronFluxControl const &ctrl)
Determine the Kron Aperture from an image.
Definition: KronPhotometry.cc:233
KernelFunctions.h
Point< int, 2 >
ApertureFlux.h
lsst::meas::extensions::photometryKron::KronFluxControl::maxSincRadius
double maxSincRadius
"Largest aperture for which to use the slow, accurate, sinc aperture code" ;
Definition: photometryKron.h:58
lsst::afw::geom::ellipses::Axes::transform
Transformer transform(lsst::geom::LinearTransform const &transform)
lsst::pex::exceptions::OutOfRangeError
lsst::daf::base::PropertySet
lsst::geom::Point2I
Point< int, 2 > Point2I
lsst::geom::Box2I
lsst::afw::image::PARENT
PARENT
lsst::meas::extensions::photometryKron::KronFluxAlgorithm::getFlagDefinitions
static meas::base::FlagDefinitionList const & getFlagDefinitions()
Definition: KronPhotometry.cc:65
lsst::afw::geom::ellipses::Ellipse::getCore
BaseCore const & getCore() const
std::make_pair
T make_pair(T... args)
lsst::pex::exceptions::Exception
lsst::meas::extensions::photometryKron::KronFluxControl::nIterForRadius
int nIterForRadius
"Number of times to iterate when setting the Kron radius" ;
Definition: photometryKron.h:55
lsst::afw::detection::Psf
lsst::meas::extensions::photometryKron::BadKronException
Definition: KronPhotometry.cc:70
lsst::meas::extensions::photometryKron::KronFluxAlgorithm::fail
virtual void fail(afw::table::SourceRecord &measRecord, meas::base::MeasurementError *error=NULL) const
Definition: KronPhotometry.cc:385
lsst::meas::extensions::photometryKron::KronFluxAlgorithm::NO_MINIMUM_RADIUS
static meas::base::FlagDefinition const NO_MINIMUM_RADIUS
Definition: photometryKron.h:95
std::max
T max(T... args)
lsst::afw::detection::Footprint
Source.h
lsst::afw::image::Exposure::getWcs
std::shared_ptr< geom::SkyWcs const > getWcs() const
LSST_EXCEPTION_TYPE
#define LSST_EXCEPTION_TYPE(t, b, c)
lsst::meas::extensions::photometryKron.name
name
Definition: __init__.py:30
lsst::meas::extensions::photometryKron::KronAperture::getAxes
afw::geom::ellipses::Axes & getAxes()
Definition: photometryKron.h:189
std::numeric_limits
lsst::afw::math::SeparableKernel
lsst::meas::extensions::photometryKron::KronFluxAlgorithm::measureForced
virtual void measureForced(afw::table::SourceRecord &measRecord, afw::image::Exposure< float > const &exposure, afw::table::SourceRecord const &refRecord, afw::geom::SkyWcs const &refWcs) const
Definition: KronPhotometry.cc:560
lsst::afw::geom::ellipses::Axes::scale
void scale(double factor)
lsst::meas::base::FlagHandler::addFields
static FlagHandler addFields(afw::table::Schema &schema, std::string const &prefix, FlagDefinitionList const &flagDefs, FlagDefinitionList const &exclDefs=FlagDefinitionList::getEmptyList())
bbox
AmpInfoBoxKey bbox
lsst::pex::exceptions::RuntimeError
lsst::meas::extensions::photometryKron::KronFluxAlgorithm::USED_MINIMUM_RADIUS
static meas::base::FlagDefinition const USED_MINIMUM_RADIUS
Definition: photometryKron.h:98
SpanSet.h
lsst::meas::extensions::photometryKron::KronFluxControl::smoothingSigma
double smoothingSigma
"Smooth image with N(0, smoothingSigma^2) Gaussian while estimating R_K" ;
Definition: photometryKron.h:66
std::pow
T pow(T... args)
Exposure.h