lsst.meas.extensions.photometryKron
19.0.0-1-ga3b31f8+6
|
Go to the documentation of this file.
27 #include "boost/math/constants/constants.hpp"
47 namespace extensions {
48 namespace photometryKron {
51 base::FlagDefinitionList flagDefinitions;
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");
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");
66 return flagDefinitions;
74 template <
typename MaskedImageT>
77 explicit FootprintFlux() : _sum(0.0), _sumVar(0.0) {}
87 typename MaskedImageT::Image::Pixel
const & ival,
88 typename MaskedImageT::Variance::Pixel
const & vval) {
94 double getSum()
const {
return _sum; }
97 double getSumVar()
const {
return _sumVar; }
115 template <
typename MaskedImageT,
typename WeightImageT>
116 class FootprintFindMoment {
118 FootprintFindMoment(MaskedImageT
const& mimage,
122 ) : _xcen(center.getX()), _ycen(center.getY()),
124 _cosTheta(::
cos(theta)),
125 _sinTheta(::
sin(theta)),
126 _sum(0.0), _sumR(0.0),
128 _sumVar(0.0), _sumRVar(0.0),
130 _imageX0(mimage.getX0()), _imageY0(mimage.getY0())
135 void reset(afw::detection::Footprint
const& foot) {
138 _sumVar = _sumRVar = 0.0;
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();
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")
150 % _imageX0 % _imageY0
151 % (_imageX0 + mimage.getWidth() - 1) % (_imageY0 + mimage.getHeight() - 1)
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;
165 double r = ::hypot(du, dv*_ab);
167 if (::
hypot(dx, dy) < 0.5) {
179 double const eR = 0.38259771140356325;
187 typename MaskedImageT::Variance::Pixel vval = iloc.variance(0, 0);
189 _sumRVar += r*r*vval;
194 double getIr()
const {
return _sumR/_sum; }
199 double getIrVar()
const {
return _sumRVar/(_sum*_sum) + _sumVar*_sumR*_sumR/::
pow(_sum, 4); }
203 bool getGood()
const {
return _sum > 0 && _sumR > 0; }
209 double const _cosTheta, _sinTheta;
216 int const _imageX0, _imageY0;
232 template<
typename ImageT>
244 bool const smoothImage =
sigma > 0;
245 int kSize = smoothImage ? 2*int(2*
sigma) + 1 : 1;
248 bool const doNormalize =
true, doCopyEdge =
false;
272 FootprintFindMoment<ImageT, afw::detection::Psf::Image> iRFunctor(
278 iRFunctor, *(subImage.getImage()));
286 if (!iRFunctor.getGood()) {
290 radius = iRFunctor.getIr()*sqrt(axes.
getB()/axes.
getA());
291 if (radius <= radius0) {
300 return std::make_shared<KronAperture>(center, axes, radiusForRadius);
304 template<
typename ImageT>
308 double const maxSincRadius
312 if (axes.
getB() > maxSincRadius) {
313 FootprintFlux<ImageT> fluxFunctor;
316 fluxFunctor, *(
image.getImage()), *(
image.getVariance()));
317 return std::make_pair(fluxFunctor.getSum(), ::sqrt(fluxFunctor.getSumVar()));
323 LSST_EXCEPT_ADD(e, (boost::format(
"Measuring Kron flux for object at (%.3f, %.3f);"
324 " aperture radius %g,%g theta %g")
335 double smoothingSigma=0.0
339 double const radius =
psf->computeShape(center).getDeterminantRadius();
344 template<
typename ImageT>
347 double const nRadiusForFlux,
348 double const maxSincRadius
352 axes.
scale(nRadiusForFlux);
373 meas::
base::FluxResultKey::addFields(
schema,
name,
"flux from Kron Flux algorithm")
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")),
392 void KronFluxAlgorithm::_applyAperture(
426 meas::base::FluxResult fluxResult;
427 fluxResult.instFlux =
result.first;
428 fluxResult.instFluxErr =
result.second;
429 source.set(_fluxResultKey, fluxResult);
436 void KronFluxAlgorithm::_applyForced(
437 afw::table::SourceRecord & source,
438 afw::image::Exposure<float>
const & exposure,
440 afw::table::SourceRecord
const & reference,
441 geom::AffineTransform
const & refToMeas
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()) {
473 if (!
source.getShapeFlag()) {
484 axes = exposure.
getPsf()->computeShape();
491 footprintAxes.
scale(::sqrt(2));
517 aperture = _fallbackRadius(
source, R_K_psf, e);
520 aperture = _fallbackRadius(
source, R_K_psf, e);
532 double newRadius = rad;
538 }
else if (!exposure.
getPsf()) {
544 }
else if (rad < R_K_psf) {
548 if (newRadius != rad) {
554 _applyAperture(
source, exposure, *aperture);
556 source.set(_psfRadiusKey, R_K_psf);
566 geom::Point2D center = _centroidExtractor(measRecord, _flagHandler);
568 _applyForced(measRecord, exposure, center, refRecord,
583 }
else if (R_K_psf > 0) {
593 PTR(KronAperture) aperture(
new KronAperture(source));
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& \
606 template std::pair<double, double> KronAperture::measureFlux<afw::image::MaskedImage<TYPE> >( \
607 afw::image::MaskedImage<TYPE> const&, \
constexpr double radToDeg(double x) noexcept
std::shared_ptr< lsst::afw::detection::Psf const > getPsf() const
double minimumRadius
"Minimum Kron radius (if == 0.0 use PSF's Kron radius) if enforceMinimumRadius. " "Also functions as ...
static meas::base::FlagDefinition const NO_FALLBACK_RADIUS
meas::base::Flux instFlux
void handleFailure(afw::table::BaseRecord &record, MeasurementError const *error=nullptr) const
CentroidSlotDefinition::MeasValue getCentroid() const
double const getB() const
bool fixed
"if true, use existing shape and centroid measurements instead of fitting" ;
void add(std::string const &name, T const &value)
#define LSST_EXCEPT_ADD(e, m)
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.
afw::table::Key< double > sigma
float getRadiusForRadius() const
double const getTheta() const
lsst::geom::AffineTransform linearizeTransform(TransformPoint2ToPoint2 const &original, lsst::geom::Point2D const &inPoint)
C++ control object for Kron flux.
double nSigmaForRadius
"Multiplier of rms size for aperture used to initially estimate the Kron radius" ;
lsst::geom::Box2I growBBox(lsst::geom::Box2I const &bbox) const
Point< double, 2 > Point2D
double getDeterminantRadius() const
MaskedImageT getMaskedImage()
static meas::base::FlagDefinition const USED_PSF_RADIUS
double const getA() const
meas::base::FluxErrElement instFluxErr
void setValue(afw::table::BaseRecord &record, std::size_t i, bool value) const
std::unique_ptr< SchemaItem< U > > result
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.
#define INSTANTIATE(TYPE)
double nRadiusForFlux
"Number of Kron radii for Kron flux" ;
lsst::geom::Point2D const & getCenter() const
static meas::base::FlagDefinition const EDGE
bool useFootprintRadius
"Use the Footprint size as part of initial estimate of Kron radius" ;
std::pair< double, double > measureFlux(ImageT const &image, double const nRadiusForFlux, double const maxSincRadius) const
Photometer within the Kron Aperture on an image.
double calculatePsfKronRadius(boost::shared_ptr< afw::detection::Psf const > const &psf, geom::Point2D const ¢er, double smoothingSigma=0.0)
static meas::base::FlagDefinition const BAD_SHAPE
virtual void measure(afw::table::SourceRecord &measRecord, afw::image::Exposure< float > const &exposure) const
static meas::base::FlagDefinition const SMALL_RADIUS
static meas::base::FlagDefinition const BAD_SHAPE_NO_PSF
#define LSST_EXCEPT(type,...)
bool enforceMinimumRadius
"If true check that the Kron radius exceeds some minimum" ;
void convolve(OutImageT &convolvedImage, InImageT const &inImage, KernelT const &kernel, ConvolutionControl const &convolutionControl=ConvolutionControl())
std::pair< double, double > photometer(ImageT const &image, afw::geom::ellipses::Ellipse const &aperture, double const maxSincRadius)
static meas::base::FlagDefinition const FAILURE
static meas::base::FlagDefinition const BAD_RADIUS
std::string refRadiusName
"Name of field specifying reference Kron radius for forced measurement" ;
static std::shared_ptr< geom::SpanSet > fromShape(int r, Stencil s=Stencil::CIRCLE, lsst::geom::Point2I offset=lsst::geom::Point2I())
geom::Point2D const & getCenter() const
std::shared_ptr< TransformPoint2ToPoint2 > makeWcsPairTransform(SkyWcs const &src, SkyWcs const &dst)
static boost::shared_ptr< KronAperture > determineRadius(ImageT const &image, afw::geom::ellipses::Axes axes, geom::Point2D const ¢er, KronFluxControl const &ctrl)
Determine the Kron Aperture from an image.
double maxSincRadius
"Largest aperture for which to use the slow, accurate, sinc aperture code" ;
Transformer transform(lsst::geom::LinearTransform const &transform)
static meas::base::FlagDefinitionList const & getFlagDefinitions()
BaseCore const & getCore() const
int nIterForRadius
"Number of times to iterate when setting the Kron radius" ;
virtual void fail(afw::table::SourceRecord &measRecord, meas::base::MeasurementError *error=NULL) const
static meas::base::FlagDefinition const NO_MINIMUM_RADIUS
std::shared_ptr< geom::SkyWcs const > getWcs() const
#define LSST_EXCEPTION_TYPE(t, b, c)
afw::geom::ellipses::Axes & getAxes()
virtual void measureForced(afw::table::SourceRecord &measRecord, afw::image::Exposure< float > const &exposure, afw::table::SourceRecord const &refRecord, afw::geom::SkyWcs const &refWcs) const
void scale(double factor)
static FlagHandler addFields(afw::table::Schema &schema, std::string const &prefix, FlagDefinitionList const &flagDefs, FlagDefinitionList const &exclDefs=FlagDefinitionList::getEmptyList())
static meas::base::FlagDefinition const USED_MINIMUM_RADIUS
double smoothingSigma
"Smooth image with N(0, smoothingSigma^2) Gaussian while estimating R_K" ;