24 #include "ndarray/eigen.h"
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"
34 #include "lsst/afw/table/Source.h"
36 namespace lsst {
namespace meas {
namespace base {
38 FlagDefinitionList flagDefinitions;
44 return flagDefinitions;
69 enum Method { ADAPTIVE_MOMENT,
76 PsfAttributes(CONST_PTR(lsst::afw::detection::Psf) psf,
int const iX,
int const iY);
77 PsfAttributes(CONST_PTR(lsst::afw::detection::Psf) psf, lsst::afw::geom::Point2I
const& cen);
79 double computeGaussianWidth(Method how=ADAPTIVE_MOMENT)
const;
80 double computeEffectiveArea()
const;
89 PsfAttributes::PsfAttributes(
90 CONST_PTR(lsst::afw::detection::Psf) psf,
96 _psfImage = psf->computeImage(afw::geom::PointD(iX, iY));
102 PsfAttributes::PsfAttributes(
103 CONST_PTR(lsst::afw::detection::Psf) psf,
104 lsst::afw::geom::Point2I
const& cen
107 _psfImage(psf->computeImage(afw::geom::PointD(cen)))
115 double PsfAttributes::computeEffectiveArea()
const {
119 for (
int iY = 0; iY !=
_psfImage->getHeight(); ++iY) {
120 afw::image::Image<double>::x_iterator end =
_psfImage->row_end(iY);
121 for (afw::image::Image<double>::x_iterator ptr =
_psfImage->row_begin(iY); ptr != end; ++ptr) {
123 sumsqr += (*ptr)*(*ptr);
126 return sum*sum/sumsqr;
140 afw::image::MaskedImage<T>
const &maskedImage,
141 std::string
const &warpingKernelName,
142 afw::geom::Point2D
const &fracShift,
143 afw::geom::Point2I
const &parentInd
145 typedef typename afw::image::Exposure<T>::MaskedImageT MaskedImageT;
146 typedef typename afw::image::Image<double> KernelImageT;
148 PTR(afw::math::SeparableKernel) warpingKernelPtr = afw::math::makeWarpingKernel(warpingKernelName);
150 if ((std::abs(fracShift[0]) >= 1) || (std::abs(fracShift[1]) >= 1)) {
151 std::ostringstream os;
152 os <<
"fracShift = " << fracShift <<
" too large; abs value must be < 1 in both axes";
153 throw LSST_EXCEPT(pex::exceptions::RangeError, os.str());
157 if (fracShift[0] < 0) {
158 warpingKernelPtr->setCtrX(warpingKernelPtr->getCtrX() + 1);
160 if (fracShift[1] < 0) {
161 warpingKernelPtr->setCtrY(warpingKernelPtr->getCtrY() + 1);
163 afw::geom::Box2I warpingOverlapBBox(
164 parentInd - afw::geom::Extent2I(warpingKernelPtr->getCtr()),
165 warpingKernelPtr->getDimensions());
166 if (!maskedImage.getBBox().contains(warpingOverlapBBox)) {
167 std::ostringstream os;
168 os <<
"Warping kernel extends off the edge"
169 <<
"; kernel bbox = " << warpingOverlapBBox
170 <<
"; exposure bbox = " << maskedImage.getBBox();
171 throw LSST_EXCEPT(pex::exceptions::RangeError, os.str());
173 warpingKernelPtr->setKernelParameters(std::make_pair(fracShift[0], fracShift[1]));
174 KernelImageT warpingKernelImage(warpingKernelPtr->getDimensions());
175 warpingKernelPtr->computeImage(warpingKernelImage,
true);
176 typename KernelImageT::const_xy_locator
const warpingKernelLoc = warpingKernelImage.xy_at(0,0);
180 afw::geom::Point2I subimMin = warpingOverlapBBox.getMin();
181 typename MaskedImageT::const_xy_locator
const mimageLoc = maskedImage.xy_at(subimMin.getX(), subimMin.getY());
182 return afw::math::convolveAtAPoint<MaskedImageT, MaskedImageT>(
183 mimageLoc, warpingKernelLoc, warpingKernelPtr->getWidth(), warpingKernelPtr->getHeight());
185 PeakLikelihoodFluxAlgorithm::PeakLikelihoodFluxAlgorithm(
187 std::string
const & name,
188 afw::table::Schema & schema
191 FluxResultKey::addFields(schema, name,
"flux from PeakLikelihood Flux algorithm")
199 afw::table::SourceRecord & measRecord,
200 afw::image::Exposure<float>
const & exposure
203 afw::geom::Point2D center = _centroidExtractor(measRecord, _flagHandler);
205 typedef afw::image::Exposure<float>::MaskedImageT MaskedImageT;
206 MaskedImageT
const& mimage = exposure.getMaskedImage();
218 if (!exposure.hasPsf()) {
219 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
"exposure has no PSF");
221 PTR(afw::detection::Psf
const) psfPtr = exposure.getPsf();
222 if (!afw::geom::Box2D(mimage.getBBox()).contains(center)) {
223 std::ostringstream os;
224 os <<
"Center = " << center <<
" not in exposure bbox" << mimage.getBBox();
225 throw LSST_EXCEPT(pex::exceptions::RangeError, os.str());
230 std::pair<int, double>
const xCtrPixParentIndFrac = afw::image::positionToIndex(center.getX(),
true);
231 std::pair<int, double>
const yCtrPixParentIndFrac = afw::image::positionToIndex(center.getY(),
true);
233 afw::geom::Point2I ctrPixParentInd(xCtrPixParentIndFrac.first, yCtrPixParentIndFrac.first);
234 afw::geom::Point2D ctrPixPos(
235 afw::image::indexToPosition(ctrPixParentInd[0]),
236 afw::image::indexToPosition(ctrPixParentInd[1])
240 PsfAttributes psfAttr(psfPtr, ctrPixParentInd);
241 double weight = psfAttr.computeEffectiveArea();
250 afw::geom::Point2D(xCtrPixParentIndFrac.second, yCtrPixParentIndFrac.second),
253 double flux = mimageCtrPix.image()*weight;
254 double var = mimageCtrPix.variance()*weight*weight;
257 measRecord.set(_fluxResultKey, result);
boost::shared_ptr< lsst::afw::image::Image< double > > _psfImage
Exception to be thrown when a measurement algorithm experiences a known failure mode.
C++ control object for peak likelihood flux.
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...
static FlagDefinition const FAILURE
virtual void measure(afw::table::SourceRecord &measRecord, afw::image::Exposure< float > const &exposure) const
Called to measure a single child source in an image.
_centroidExtractor(schema, name)
Flux flux
Measured flux in DN.
void setValue(afw::table::BaseRecord &record, std::size_t i, bool value) const
Set the flag field corresponding to the given flag index.
A FunctorKey for FluxResult.
void handleFailure(afw::table::BaseRecord &record, MeasurementError const *error=nullptr) const
Handle an expected or unexpected Exception thrown by a measurement algorithm.
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.
std::string warpingKernelName
"Name of warping kernel (e.g. \"lanczos4") used to compute the peak" ;
static FlagDefinitionList const & getFlagDefinitions()
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)
Compute the value of one pixel of an image after a fractional pixel shift Since we only want the valu...
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.