26 #include "boost/algorithm/string/replace.hpp" 28 #include "ndarray/eigen.h" 30 #include "lsst/afw/math/offsetImage.h" 31 #include "lsst/afw/geom/ellipses/PixelRegion.h" 32 #include "lsst/afw/table/Source.h" 36 namespace lsst {
namespace meas {
namespace base {
38 FlagDefinitionList flagDefinitions;
46 return flagDefinitions;
52 static std::array<double,10> defaultRadii = {{
53 3.0, 4.5, 6.0, 9.0, 12.0, 17.0, 25.0, 35.0, 50.0, 70.0
55 std::copy(defaultRadii.begin(), defaultRadii.end(),
radii.begin());
60 std::string prefix = (boost::format(
"%s_%.1f") % name % radius).str();
61 return boost::replace_all_copy(prefix,
".",
"_");
64 ApertureFluxAlgorithm::Keys::Keys(
65 afw::table::Schema & schema, std::string
const & prefix, std::string
const & doc,
bool isSinc
80 std::string
const & name,
81 afw::table::Schema & schema,
82 daf::base::PropertySet & metadata
85 _centroidExtractor(schema, name)
87 _keys.reserve(ctrl.
radii.size());
88 for (std::size_t i = 0; i < ctrl.
radii.size(); ++i) {
89 metadata.add(name +
"_radii", ctrl.
radii[i]);
91 std::string doc = (boost::format(
"flux within %f-pixel aperture") % ctrl.
radii[i]).str();
100 for (std::size_t i = 0; i <
_ctrl.
radii.size(); ++i) {
101 _keys[i].flags.handleFailure(measRecord, error);
107 afw::table::SourceRecord & record,
110 record.set(_keys[index].fluxKey, result);
126 template <
typename T>
127 CONST_PTR(afw::image::Image<T>) getSincCoeffs(
128 afw::geom::Box2I
const & bbox,
129 afw::geom::ellipses::Ellipse
const & ellipse,
134 cImage = afw::math::offsetImage(
136 ellipse.getCenter().getX(),
137 ellipse.getCenter().getY(),
140 if (!bbox.contains(cImage->getBBox())) {
145 result.
setFlag(ApertureFluxAlgorithm::SINC_COEFFS_TRUNCATED.number);
146 afw::geom::Box2I overlap = cImage->getBBox();
148 if (!overlap.contains(afw::geom::Box2I(ellipse.computeBBox()))) {
151 result.
setFlag(ApertureFluxAlgorithm::APERTURE_TRUNCATED.number);
152 result.
setFlag(ApertureFluxAlgorithm::FAILURE.number);
154 cImage = std::make_shared< afw::image::Image<T> >(*cImage, overlap);
161 template <
typename T>
163 afw::image::Image<T>
const & image,
164 afw::geom::ellipses::Ellipse
const & ellipse,
168 CONST_PTR(afw::image::Image<T>) cImage = getSincCoeffs<T>(image.getBBox(), ellipse, result, ctrl);
170 afw::image::Image<T> subImage(image, cImage->getBBox());
171 result.
flux = (subImage.getArray().template asEigen<Eigen::ArrayXpr>()
172 * cImage->getArray().template asEigen<Eigen::ArrayXpr>()).sum();
176 template <
typename T>
178 afw::image::MaskedImage<T>
const & image,
179 afw::geom::ellipses::Ellipse
const & ellipse,
183 CONST_PTR(afw::image::Image<T>) cImage = getSincCoeffs<T>(image.getBBox(), ellipse, result, ctrl);
185 afw::image::MaskedImage<T> subImage(image, cImage->getBBox(afw::image::PARENT), afw::image::PARENT);
186 result.
flux = (subImage.getImage()->getArray().template asEigen<Eigen::ArrayXpr>()
187 * cImage->getArray().template asEigen<Eigen::ArrayXpr>()).sum();
188 result.fluxSigma = std::sqrt(
189 (subImage.getVariance()->getArray().template asEigen<Eigen::ArrayXpr>().
template cast<T>()
190 * cImage->getArray().template asEigen<Eigen::ArrayXpr>().square()).sum()
195 template <
typename T>
197 afw::image::Image<T>
const & image,
198 afw::geom::ellipses::Ellipse
const & ellipse,
202 afw::geom::ellipses::PixelRegion region(ellipse);
203 if (!image.getBBox().contains(region.getBBox())) {
210 afw::geom::ellipses::PixelRegion::Iterator spanIter = region.begin(), spanEnd = region.end();
214 typename afw::image::Image<T>::x_iterator pixIter = image.x_at(
215 spanIter->getBeginX() - image.getX0(),
216 spanIter->getY() - image.getY0()
218 result.
flux += std::accumulate(pixIter, pixIter + spanIter->getWidth(), 0.0);
223 template <
typename T>
225 afw::image::MaskedImage<T>
const & image,
226 afw::geom::ellipses::Ellipse
const & ellipse,
230 afw::geom::ellipses::PixelRegion region(ellipse);
231 if (!image.getBBox().contains(region.getBBox())) {
239 afw::geom::ellipses::PixelRegion::Iterator spanIter = region.begin(), spanEnd = region.end();
243 typename afw::image::MaskedImage<T>::Image::x_iterator pixIter = image.getImage()->x_at(
244 spanIter->getBeginX() - image.getX0(),
245 spanIter->getY() - image.getY0()
247 typename afw::image::MaskedImage<T>::Variance::x_iterator varIter = image.getVariance()->x_at(
248 spanIter->getBeginX() - image.getX0(),
249 spanIter->getY() - image.getY0()
251 result.
flux += std::accumulate(pixIter, pixIter + spanIter->getWidth(), 0.0);
253 result.
fluxSigma += std::accumulate(varIter, varIter + spanIter->getWidth(), 0.0);
259 template <
typename T>
261 afw::image::Image<T>
const & image,
262 afw::geom::ellipses::Ellipse
const & ellipse,
265 return (afw::geom::ellipses::Axes(ellipse.getCore()).getB() <= ctrl.
maxSincRadius)
270 template <
typename T>
272 afw::image::MaskedImage<T>
const & image,
273 afw::geom::ellipses::Ellipse
const & ellipse,
276 return (afw::geom::ellipses::Axes(ellipse.getCore()).getB() <= ctrl.
maxSincRadius)
280 #define INSTANTIATE(T) \ 282 ApertureFluxAlgorithm::Result ApertureFluxAlgorithm::computeFlux( \ 283 afw::image::Image<T> const &, \ 284 afw::geom::ellipses::Ellipse const &, \ 288 ApertureFluxAlgorithm::Result ApertureFluxAlgorithm::computeFlux( \ 289 afw::image::MaskedImage<T> const &, \ 290 afw::geom::ellipses::Ellipse const &, \ 294 ApertureFluxAlgorithm::Result ApertureFluxAlgorithm::computeSincFlux( \ 295 afw::image::Image<T> const &, \ 296 afw::geom::ellipses::Ellipse const &, \ 300 ApertureFluxAlgorithm::Result ApertureFluxAlgorithm::computeSincFlux( \ 301 afw::image::MaskedImage<T> const &, \ 302 afw::geom::ellipses::Ellipse const &, \ 306 ApertureFluxAlgorithm::Result ApertureFluxAlgorithm::computeNaiveFlux( \ 307 afw::image::Image<T> const &, \ 308 afw::geom::ellipses::Ellipse const &, \ 312 ApertureFluxAlgorithm::Result ApertureFluxAlgorithm::computeNaiveFlux( \ 313 afw::image::MaskedImage<T> const &, \ 314 afw::geom::ellipses::Ellipse const &, \ 323 std::string
const & name,
324 afw::table::SchemaMapper & mapper
329 for (std::size_t i = 0; i < _ctrl.
radii.size(); ++i) {
332 if (_ctrl.
radii[i] > _ctrl.
maxSincRadius && flag == ApertureFluxAlgorithm::SINC_COEFFS_TRUNCATED) {
335 mapper.addMapping(mapper.getInputSchema().find<afw::table::Flag>((boost::format(
"%s_%s") %
337 flag.
name).str()).key);
345 afw::table::SourceCatalog
const & inputCatalog,
346 afw::table::BaseCatalog & outputCatalog,
347 afw::image::Wcs
const & wcs,
348 afw::image::Calib
const & calib
351 std::vector<FluxResultKey> fluxKeys;
352 for (std::size_t i = 0; i < _ctrl.
radii.size(); ++i) {
356 afw::table::SourceCatalog::const_iterator inSrc = inputCatalog.begin();
357 afw::table::BaseCatalog::iterator outSrc = outputCatalog.begin();
362 for (; inSrc != inputCatalog.end() && outSrc != outputCatalog.end(); ++inSrc, ++outSrc) {
363 for (std::size_t i = 0; i < _ctrl.
radii.size(); ++i) {
364 FluxResult fluxResult = fluxKeys[i].get(*inSrc);
365 _magKeys[i].set(*outSrc, calib.getMagnitude(fluxResult.
flux, fluxResult.
fluxSigma));
std::size_t size() const
return the current size (number of defined elements) of the collection
static boost::shared_ptr< CoeffT const > get(afw::geom::ellipses::Axes const &outerEllipse, float const innerRadiusFactor=0.0)
Get the coefficients for an aperture.
virtual void fail(afw::table::SourceRecord &measRecord, MeasurementError *error=nullptr) const
Handle an exception thrown by the current algorithm by setting flags in the given record...
bool getFlag(unsigned int index) const
Return the flag value associated with the given bit.
void setFlag(unsigned int index, bool value=true)
Set the flag value associated with the given bit.
static FlagDefinitionList const & getFlagDefinitions()
Simple class used to define and document flags The name and doc constitute the identity of the FlagDe...
Temporarily replace negative fluxes with NaNs.
ApertureFluxAlgorithm(Control const &ctrl, std::string const &name, afw::table::Schema &schema, daf::base::PropertySet &metadata)
Construct the algorithm and add its fields to the given Schema.
void copyResultToRecord(Result const &result, afw::table::SourceRecord &record, int index) const
Return the flag definitions which apply to aperture flux measurements.
Exception to be thrown when a measurement algorithm experiences a known failure mode.
static FluxResultKey addFields(afw::table::Schema &schema, std::string const &name, std::string const &doc)
Add a pair of _flux, _fluxSigma fields to a Schema, and return a FluxResultKey that points to them...
Configuration object for multiple-aperture flux algorithms.
static FlagDefinition const FAILURE
static FlagDefinition const APERTURE_TRUNCATED
static Result computeFlux(afw::image::Image< T > const &image, afw::geom::ellipses::Ellipse const &ellipse, Control const &ctrl=Control())
Compute the flux (and optionally, uncertanties) within an aperture using the algorithm determined by ...
double maxSincRadius
"Maximum radius (in pixels) for which the sinc algorithm should be used instead of the " "faster naiv...
static std::string makeFieldPrefix(std::string const &name, double radius)
Construct an appropriate prefix for table fields.
static FlagDefinition const SINC_COEFFS_TRUNCATED
static Result computeNaiveFlux(afw::image::Image< T > const &image, afw::geom::ellipses::Ellipse const &ellipse, Control const &ctrl=Control())
Compute the flux (and optionally, uncertanties) within an aperture using naive photometry.
Flux flux
Measured flux in DN.
A FunctorKey for FluxResult.
static FlagHandler addFields(afw::table::Schema &schema, std::string const &prefix, FlagDefinitionList const &flagDefs, FlagDefinitionList const &exclDefs=FlagDefinitionList::getEmptyList())
Add Flag fields to a schema, creating a FlagHandler object to manage them.
static MagResultKey addFields(afw::table::Schema &schema, std::string const &name)
Add a pair of _mag, _magErr fields to a Schema, and return a MagResultKey that points to them...
static Result computeSincFlux(afw::image::Image< T > const &image, afw::geom::ellipses::Ellipse const &ellipse, Control const &ctrl=Control())
Compute the flux (and optionally, uncertanties) within an aperture using Sinc photometry.
std::string shiftKernel
"Warping kernel used to shift Sinc photometry coefficients to different center positions" ; ...
std::vector< double > radii
"Radius (in pixels) of apertures." ;
vector-type utility class to build a collection of FlagDefinitions
FluxErrElement fluxSigma
1-Sigma error (sqrt of variance) on flux in DN.
A reusable result struct for flux measurements.
A Result struct for running an aperture flux algorithm with a single radius.