27 #include "boost/tuple/tuple.hpp" 43 FlagDefinitionList flagDefinitions;
48 flagDefinitions.add(
"flag_unweightedBad",
"Both weighted and unweighted moments were invalid");
50 "flag_unweighted",
"Weighted moments converged to an invalid value; using unweighted moments");
52 flagDefinitions.add(
"flag_shift",
"centroid shifted by more than the maximum allowed amount");
54 flagDefinitions.add(
"flag_maxIter",
"Too many iterations in adaptive moments");
56 flagDefinitions.add(
"flag_psf",
"Failure in measuring PSF model shape");
62 typedef Eigen::Matrix<double, 4, 4, Eigen::DontAlign> Matrix4d;
72 double const Mxx = result.
xx;
73 double const Mxy = result.
xy;
74 double const Myy = result.
yy;
76 double const Muu_p_Mvv = Mxx + Myy;
77 double const Muu_m_Mvv = ::sqrt(::pow(Mxx - Myy, 2) + 4 * ::pow(Mxy, 2));
78 double const Muu = 0.5 * (Muu_p_Mvv + Muu_m_Mvv);
79 double const Mvv = 0.5 * (Muu_p_Mvv - Muu_m_Mvv);
100 float const sigma11W = shape.
xx;
101 float const sigma12W = shape.
xy;
102 float const sigma22W = shape.
yy;
104 double const D = sigma11W * sigma22W - sigma12W * sigma12W;
112 if (bkgd_var <= 0.0) {
114 (boost::format(
"Background variance must be positive (saw %g)") % bkgd_var).str());
116 double const F =
geom::PI * sqrt(D) / bkgd_var;
122 double fac = F * A / (4.0 * D);
124 fisher(0, 1) = fac * sigma22W;
125 fisher(1, 0) = fisher(0, 1);
126 fisher(0, 2) = fac * sigma11W;
127 fisher(2, 0) = fisher(0, 2);
128 fisher(0, 3) = -fac * 2 * sigma12W;
129 fisher(3, 0) = fisher(0, 3);
131 fac = 3.0 * F * A * A / (16.0 * D * D);
132 fisher(1, 1) = fac * sigma22W * sigma22W;
133 fisher(2, 2) = fac * sigma11W * sigma11W;
134 fisher(3, 3) = fac * 4.0 * (sigma12W * sigma12W + D / 3.0);
136 fisher(1, 2) = fisher(3, 3) / 4.0;
137 fisher(2, 1) = fisher(1, 2);
138 fisher(1, 3) = fac * (-2 * sigma22W * sigma12W);
139 fisher(3, 1) = fisher(1, 3);
140 fisher(2, 3) = fac * (-2 * sigma11W * sigma12W);
141 fisher(3, 2) = fisher(2, 3);
148 template <
typename ImageT>
149 struct ImageAdaptor {
150 typedef ImageT Image;
152 static bool const hasVariance =
false;
154 Image
const &getImage(ImageT
const &
image)
const {
return image; }
159 template <
typename T>
160 struct ImageAdaptor<afw::image::MaskedImage<T> > {
163 static bool const hasVariance =
true;
168 return mimage.
at(ix, iy).variance();
179 double const det = sigma11 * sigma22 - sigma12 * sigma12;
187 bool shouldInterp(
double sigma11,
double sigma22,
double det) {
188 float const xinterp = 0.25;
189 return (sigma11 < xinterp || sigma22 < xinterp || det < xinterp * xinterp);
200 double maxRadius = 1000
213 template <
bool instFluxOnly,
typename ImageT>
214 static int calcmom(ImageT
const &
image,
215 float xcen,
float ycen,
219 double w11,
double w12,
double w22,
222 double *psumx,
double *psumy,
223 double *psumxx,
double *psumxy,
double *psumyy,
225 bool negative =
false) {
230 double sum, sumx, sumy, sumxx, sumyy, sumxy, sums4;
231 #define RECALC_W 0 // estimate sigmaXX_w within BBox? 233 double wsum, wsumxx, wsumxy, wsumyy;
235 wsum = wsumxx = wsumxy = wsumyy = 0;
239 if (fabs(w11) > 1e6 || fabs(w12) > 1e6 || fabs(w22) > 1e6) {
243 sum = sumx = sumy = sumxx = sumxy = sumyy = sums4 = 0;
245 int const ix0 = bbox.
getMinX();
246 int const ix1 = bbox.
getMaxX();
247 int const iy0 = bbox.
getMinY();
248 int const iy1 = bbox.
getMaxY();
250 if (ix0 < 0 || ix1 >= image.getWidth() || iy0 < 0 || iy1 >= image.getHeight()) {
254 for (
int i = iy0; i <= iy1; ++i) {
255 typename ImageT::x_iterator ptr = image.x_at(ix0, i);
256 float const y = i - ycen;
257 float const y2 = y * y;
258 float const yl = y - 0.375;
259 float const yh = y + 0.375;
260 for (
int j = ix0; j <= ix1; ++j, ++ptr) {
263 float const xl = x - 0.375;
264 float const xh = x + 0.375;
266 float expon = xl * xl * w11 + yl * yl * w22 + 2.0 * xl * yl * w12;
267 tmp = xh * xh * w11 + yh * yh * w22 + 2.0 * xh * yh * w12;
268 expon = (expon > tmp) ? expon : tmp;
269 tmp = xl * xl * w11 + yh * yh * w22 + 2.0 * xl * yh * w12;
270 expon = (expon > tmp) ? expon : tmp;
271 tmp = xh * xh * w11 + yl * yl * w22 + 2.0 * xh * yl * w12;
272 expon = (expon > tmp) ? expon : tmp;
276 for (Y = yl; Y <= yh; Y += 0.25) {
277 double const interpY2 = Y * Y;
278 for (X = xl; X <= xh; X += 0.25) {
279 double const interpX2 = X * X;
280 double const interpXy = X * Y;
281 expon = interpX2 * w11 + 2 * interpXy * w12 + interpY2 * w22;
284 ymod = tmod * weight;
287 sumx += ymod * (X + xcen);
288 sumy += ymod * (Y + ycen);
292 tmp = interpX2 * weight;
296 tmp = interpXy * weight;
300 tmp = interpY2 * weight;
304 sumxx += interpX2 * ymod;
305 sumxy += interpXy * ymod;
306 sumyy += interpY2 * ymod;
308 sums4 += expon * expon * ymod;
316 float expon = x2 * w11 + 2 * xy * w12 + y2 * w22;
321 ymod = tmod * weight;
345 sums4 += expon * expon * ymod;
353 double const detW = std::get<1>(weights) * std::get<3>(weights) -
std::pow(std::get<2>(weights), 2);
354 *pI0 = sum / (
geom::PI * sqrt(detW));
364 if (psums4 != NULL) {
370 if (wsum > 0 && !instFluxOnly) {
371 double det = w11 * w22 - w12 * w12;
375 printf(
"%g %g %g %g %g %g\n", w22 / det, -w12 / det, w11 / det, wsumxx, wsumxy, wsumyy);
380 return (instFluxOnly || (sum < 0 && sumxx < 0 && sumyy < 0)) ? 0 : -1;
382 return (instFluxOnly || (sum > 0 && sumxx > 0 && sumyy > 0)) ? 0 : -1;
391 template <
typename ImageT>
392 bool getAdaptiveMoments(ImageT
const &mimage,
double bkgd,
double xcen,
double ycen,
double shiftmax,
393 SdssShapeResult *shape,
int maxIter,
float tol1,
float tol2,
bool negative) {
397 double sumxx, sumxy, sumyy;
399 float const xcen0 = xcen;
400 float const ycen0 = ycen;
402 double sigma11W = 1.5;
403 double sigma12W = 0.0;
404 double sigma22W = 1.5;
406 double w11 = -1, w12 = -1, w22 = -1;
407 float e1_old = 1e6, e2_old = 1e6;
408 float sigma11_ow_old = 1e6;
410 typename ImageAdaptor<ImageT>::Image
const &image = ImageAdaptor<ImageT>().getImage(mimage);
414 shape->
flags[SdssShapeAlgorithm::UNWEIGHTED_BAD.number] =
true;
418 bool interpflag =
false;
421 for (; iter < maxIter; iter++) {
423 sigma11W, sigma12W, sigma22W);
425 getWeights(sigma11W, sigma12W, sigma22W);
426 if (!std::get<0>(weights).
first) {
427 shape->
flags[SdssShapeAlgorithm::UNWEIGHTED.number] =
true;
431 double const detW = std::get<0>(weights).
second;
433 #if 0 // this form was numerically unstable on my G4 powerbook 440 const double ow11 = w11;
441 const double ow12 = w12;
442 const double ow22 = w22;
444 w11 = std::get<1>(weights);
445 w12 = std::get<2>(weights);
446 w22 = std::get<3>(weights);
448 if (shouldInterp(sigma11W, sigma22W, detW)) {
452 sigma11_ow_old = 1.e6;
462 if (calcmom<false>(image, xcen, ycen, bbox, bkgd, interpflag, w11, w12, w22, &I0, &sum, &sumx, &sumy,
463 &sumxx, &sumxy, &sumyy, &sums4, negative) < 0) {
464 shape->
flags[SdssShapeAlgorithm::UNWEIGHTED.number] =
true;
477 shape->
x = sumx / sum;
478 shape->
y = sumy / sum;
480 if (fabs(shape->
x - xcen0) > shiftmax || fabs(shape->
y - ycen0) > shiftmax) {
481 shape->
flags[SdssShapeAlgorithm::SHIFT.number] =
true;
486 float const sigma11_ow = sumxx / sum;
487 float const sigma22_ow = sumyy / sum;
488 float const sigma12_ow = sumxy / sum;
490 if (sigma11_ow <= 0 || sigma22_ow <= 0) {
491 shape->
flags[SdssShapeAlgorithm::UNWEIGHTED.number] =
true;
495 float const d = sigma11_ow + sigma22_ow;
496 float const e1 = (sigma11_ow - sigma22_ow) / d;
497 float const e2 = 2.0 * sigma12_ow / d;
501 if (iter > 0 && fabs(e1 - e1_old) < tol1 && fabs(e2 - e2_old) < tol1 &&
502 fabs(sigma11_ow / sigma11_ow_old - 1.0) < tol2) {
508 sigma11_ow_old = sigma11_ow;
533 float ow11, ow12, ow22;
535 std::tuple<std::pair<bool, double>, double, double,
double> weights =
536 getWeights(sigma11_ow, sigma12_ow, sigma22_ow);
537 if (!std::get<0>(weights).first) {
538 shape->
flags[SdssShapeAlgorithm::UNWEIGHTED.number] =
true;
542 ow11 = std::get<1>(weights);
543 ow12 = std::get<2>(weights);
544 ow22 = std::get<3>(weights);
550 weights = getWeights(n11, n12, n22);
551 if (!std::get<0>(weights).first) {
553 shape->
flags[SdssShapeAlgorithm::UNWEIGHTED.number] =
true;
557 sigma11W = std::get<1>(weights);
558 sigma12W = std::get<2>(weights);
559 sigma22W = std::get<3>(weights);
562 if (sigma11W <= 0 || sigma22W <= 0) {
563 shape->
flags[SdssShapeAlgorithm::UNWEIGHTED.number] =
true;
568 if (iter == maxIter) {
569 shape->
flags[SdssShapeAlgorithm::UNWEIGHTED.number] =
true;
570 shape->
flags[SdssShapeAlgorithm::MAXITER.number] =
true;
573 if (sumxx + sumyy == 0.0) {
574 shape->
flags[SdssShapeAlgorithm::UNWEIGHTED.number] =
true;
579 if (shape->
flags[SdssShapeAlgorithm::UNWEIGHTED.number]) {
581 if (calcmom<false>(image, xcen, ycen, bbox, bkgd, interpflag, w11, w12, w22, &I0, &sum, &sumx, &sumy,
582 &sumxx, &sumxy, &sumyy, NULL, negative) < 0 ||
583 (!negative && sum <= 0) || (negative && sum >= 0)) {
584 shape->
flags[SdssShapeAlgorithm::UNWEIGHTED.number] =
false;
585 shape->
flags[SdssShapeAlgorithm::UNWEIGHTED_BAD.number] =
true;
588 shape->
xx = 1 / 12.0;
590 shape->
yy = 1 / 12.0;
596 sigma11W = sumxx / sum;
597 sigma12W = sumxy / sum;
598 sigma22W = sumyy / sum;
602 shape->
xx = sigma11W;
603 shape->
xy = sigma12W;
604 shape->
yy = sigma22W;
606 if (shape->
xx + shape->
yy != 0.0) {
610 if (ix >= 0 && ix < mimage.getWidth() && iy >= 0 && iy < mimage.getHeight()) {
611 float const bkgd_var = ImageAdaptor<ImageT>().getVariance(
614 if (bkgd_var > 0.0) {
615 if (!(shape->
flags[SdssShapeAlgorithm::UNWEIGHTED.number])) {
616 Matrix4d fisher = calc_fisher(*shape, bkgd_var);
617 Matrix4d cov = fisher.inverse();
642 : instFlux_xx_Cov(
std::numeric_limits<
ErrElement>::quiet_NaN()),
643 instFlux_yy_Cov(
std::numeric_limits<
ErrElement>::quiet_NaN()),
644 instFlux_xy_Cov(
std::numeric_limits<
ErrElement>::quiet_NaN()) {}
657 r._includePsf =
true;
659 schema, schema.
join(name,
"psf"),
"adaptive moments of the PSF model at the object position");
661 r._includePsf =
false;
666 (boost::format(
"uncertainty covariance between %s and %s") %
667 schema.
join(name,
"instFlux") % schema.
join(name,
"xx"))
672 (boost::format(
"uncertainty covariance between %s and %s") %
673 schema.
join(name,
"instFlux") % schema.
join(name,
"yy"))
678 (boost::format(
"uncertainty covariance between %s and %s") %
679 schema.
join(name,
"instFlux") % schema.
join(name,
"xy"))
688 {SdssShapeAlgorithm::PSF_SHAPE_BAD});
697 _instFlux_xx_Cov(s[
"instFlux"][
"xx"][
"Cov"]),
698 _instFlux_yy_Cov(s[
"instFlux"][
"yy"][
"Cov"]),
699 _instFlux_xy_Cov(s[
"instFlux"][
"xy"][
"Cov"]) {
716 static_cast<FluxResult &
>(result) = record.
get(_instFluxResult);
721 if (n == SdssShapeAlgorithm::PSF_SHAPE_BAD.number && !_includePsf)
continue;
728 return record.
get(_psfShapeResult);
732 record.
set(_shapeResult, value);
733 record.
set(_centroidResult, value);
734 record.
set(_instFluxResult, value);
739 if (n == SdssShapeAlgorithm::PSF_SHAPE_BAD.number && !_includePsf)
continue;
746 record.
set(_psfShapeResult, value);
750 return _shapeResult == other._shapeResult && _centroidResult == other._centroidResult &&
751 _instFluxResult == other._instFluxResult && _psfShapeResult == other._psfShapeResult &&
752 _instFlux_xx_Cov == other._instFlux_xx_Cov && _instFlux_yy_Cov == other._instFlux_yy_Cov &&
753 _instFlux_xy_Cov == other._instFlux_xy_Cov;
768 _centroidExtractor(schema, name) {}
770 template <
typename ImageT>
772 bool negative,
Control const &control) {
773 double xcen = center.getX();
774 double ycen = center.getY();
776 xcen -= image.getX0();
777 ycen -= image.getY0();
782 }
else if (shiftmax > 10) {
789 !getAdaptiveMoments(image, control.
background, xcen, ycen, shiftmax, &result, control.
maxIter,
790 control.
tol1, control.
tol2, negative);
807 "Should not get singular moments unless a flag is set");
814 double instFluxScale = computeFluxScale(result);
818 result.
x += image.getX0();
819 result.
y += image.getY0();
821 if (ImageAdaptor<ImageT>::hasVariance) {
830 template <
typename ImageT>
845 if (!std::get<0>(weights).first) {
849 double const w11 = std::get<1>(weights);
850 double const w12 = std::get<2>(weights);
851 double const w22 = std::get<3>(weights);
852 bool const interp = shouldInterp(shape.
getIxx(), shape.
getIyy(), std::get<0>(weights).
second);
855 if (calcmom<true>(ImageAdaptor<ImageT>().getImage(image), localCenter.getX(), localCenter.getY(), bbox,
856 0.0, interp, w11, w12, w22, &i0, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) {
862 result.instFlux = i0 * 2 * wArea;
864 if (ImageAdaptor<ImageT>::hasVariance) {
865 int ix =
static_cast<int>(center.getX() - image.getX0());
866 int iy =
static_cast<int>(center.getY() - image.getY0());
869 (boost::format(
"Center (%d,%d) not in image (%dx%d)") % ix % iy %
870 image.getWidth() % image.getHeight())
873 double var = ImageAdaptor<ImageT>().getVariance(image, ix, iy);
875 result.instFluxErr = i0Err * 2 * wArea;
883 bool negative =
false;
886 negative = measRecord.
get(measRecord.
getSchema().
find<afw::table::Flag>(
"flags_negative").
key);
887 }
catch (pexExcept::Exception &e) {
913 measRecord.
set(_resultKey, result);
920 #define INSTANTIATE_IMAGE(IMAGE) \ 921 template SdssShapeResult SdssShapeAlgorithm::computeAdaptiveMoments( \ 922 IMAGE const &, geom::Point2D const &, bool, Control const &); \ 923 template FluxResult SdssShapeAlgorithm::computeFixedMomentsFlux( \ 924 IMAGE const &, afw::geom::ellipses::Quadrupole const &, geom::Point2D const &) 926 #define INSTANTIATE_PIXEL(PIXEL) \ 927 INSTANTIATE_IMAGE(afw::image::Image<PIXEL>); \ 928 INSTANTIATE_IMAGE(afw::image::MaskedImage<PIXEL>); 938 _transformPsf = mapper.getInputSchema().getNames().count(
"sdssShape_flag_psf") ? true :
false;
943 if (flag == SdssShapeAlgorithm::FAILURE)
continue;
944 if (mapper.getInputSchema().getNames().count(mapper.getInputSchema().join(
name, flag.
name)) == 0)
947 mapper.getInputSchema().find<afw::table::Flag>(
name +
"_" + flag.
name).key;
948 mapper.addMapping(key);
955 "PSF shape in celestial moments",
965 _instFluxTransform(inputCatalog, outputCatalog, wcs, photoCalib);
966 _centroidTransform(inputCatalog, outputCatalog, wcs, photoCalib);
978 for (; inSrc != inputCatalog.
end(); ++inSrc, ++outSrc) {
991 _outShapeKey.
set(*outSrc, outShape);
994 _outPsfShapeKey.
set(*outSrc, inPsfShapeKey.get(*inSrc).transform(crdTr.
getLinear()));
std::size_t size() const
return the current size (number of defined elements) of the collection
virtual void set(afw::table::BaseRecord &record, ShapeResult const &value) const
Set a ShapeResult in the given record.
bool doMeasurePsf
"Whether to also compute the shape of the PSF model" ;
static Result computeAdaptiveMoments(ImageT const &image, geom::Point2D const &position, bool negative=false, Control const &ctrl=Control())
Compute the adaptive Gaussian-weighted moments of an image.
virtual void measure(afw::table::SourceRecord &measRecord, afw::image::Exposure< float > const &exposure) const
Called to measure a single child source in an image.
ErrElement yy_xy_Cov
yy,xy term in the uncertainty convariance matrix
ErrElement instFlux_yy_Cov
instFlux, yy term in the uncertainty covariance matrix
float tol2
"Convergence tolerance for FWHM" ;
int positionToIndex(double pos)
ShapeElement xy
image or model second moment for xy^2
static FlagDefinition const SHIFT
ErrElement xxErr
standard deviation of xx
std::string join(std::string const &a, std::string const &b) const
Shape const getShape() const
Return an afw::geom::ellipses object corresponding to xx, yy, xy.
iterator at(int const x, int const y) const
Simple class used to define and document flags The name and doc constitute the identity of the FlagDe...
Only the diagonal elements of the covariance matrix are provided.
A reusable struct for centroid measurements.
afw::geom::ellipses::Quadrupole getQuadrupole()
double background
"Additional value to add to background" ;
bool isValid() const
Return True if the centroid key is valid.
The full covariance matrix is provided.
CentroidElement x
x (column) coordinate of the measured position
ShapeTrMatrix makeShapeTransformMatrix(geom::LinearTransform const &xform)
Construct a matrix suitable for transforming second moments.
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...
int maxIter
"Maximum number of iterations" ;
bool operator==(SdssShapeResultKey const &other) const
Compare the FunctorKey for equality with another, using the underlying Keys.
void setValue(afw::table::BaseRecord &record, std::size_t i, bool value) const
Set the flag field corresponding to the given flag index.
meas::base::FluxErrElement instFluxErr
Standard deviation of instFlux in DN.
Exception to be thrown when a measurement algorithm experiences a known failure mode.
ShapeElement xx
image or model second moment for x^2
static FlagDefinition const UNWEIGHTED
static FluxResultKey addFields(afw::table::Schema &schema, std::string const &name, std::string const &doc)
Add a pair of _instFlux, _instFluxErr fields to a Schema, and return a FluxResultKey that points to t...
Field< T >::Value get(Key< T > const &key) const
AngleUnit constexpr radians
bool isValid() const noexcept
float tol1
"Convergence tolerance for e1,e2" ;
bool isValid() const
Return True if the key is valid.
static FlagDefinition const UNWEIGHTED_BAD
double maxShift
"Maximum centroid shift, limited to 2-10" ;
Point< double, 2 > Point2D
ImagePtr getImage() const
A FunctorKey for ShapeResult.
ErrElement xx_xy_Cov
xx,xy term in the uncertainty convariance matrix
void setShapeErr(ShapeCov const &matrix)
Set the struct standard deviation elements from the given matrix, with rows and columns ordered (xx...
ErrElement xx_yy_Cov
xx,yy term in the uncertainty convariance matrix
Utility class for handling flag fields that indicate the failure modes of an algorithm.
A reusable struct for moments-based shape measurements.
double const getIxy() const
double const getIyy() const
static unsigned int const N_FLAGS
SchemaItem< T > find(std::string const &name) const
MaskedImageT getMaskedImage()
Result object SdssShapeAlgorithm.
int getMaxY() const noexcept
static FlagDefinitionList const & getFlagDefinitions()
static QuadrupoleKey addFields(Schema &schema, std::string const &name, std::string const &doc, CoordinateType coordType=CoordinateType::PIXEL)
SdssShapeResult()
Constructor; initializes everything to NaN.
SdssShapeAlgorithm(Control const &ctrl, std::string const &name, afw::table::Schema &schema)
ErrElement xyErr
standard deviation of xy
lsst::geom::AffineTransform linearizePixelToSky(lsst::geom::SpherePoint const &coord, lsst::geom::AngleUnit const &skyUnit) const
virtual void set(afw::table::BaseRecord &record, SdssShapeResult const &value) const
Set an SdssShapeResult in the given record.
static CentroidResultKey addFields(afw::table::Schema &schema, std::string const &name, std::string const &doc, UncertaintyEnum uncertainty)
Add the appropriate fields to a Schema, and return a CentroidResultKey that manages them...
A C++ control class to handle SdssShapeAlgorithm's configuration.
Eigen::Matrix< ShapeElement, 3, 3, Eigen::DontAlign > ShapeTrMatrix
int getMaxX() const noexcept
static FluxResult computeFixedMomentsFlux(ImageT const &image, afw::geom::ellipses::Quadrupole const &shape, geom::Point2D const &position)
Compute the instFlux within a fixed Gaussian aperture.
bool isValid() const
Return True if the shape key is valid.
std::unique_ptr< SchemaItem< U > > result
bool isValid() const
Return True if both the instFlux and instFluxErr Keys are valid.
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::bitset< SdssShapeAlgorithm::N_FLAGS > flags
Status flags (see SdssShapeAlgorithm).
virtual SdssShapeResult get(afw::table::BaseRecord const &record) const
Get an SdssShapeResult from the given record.
int getMinX() const noexcept
virtual afw::geom::ellipses::Quadrupole getPsfShape(afw::table::BaseRecord const &record) const
Get a Quadrupole for the Psf from the given record.
#define LSST_EXCEPT(type,...)
ShapeElement yy
image or model second moment for y^2
Transformer transform(lsst::geom::LinearTransform const &transform)
Base::const_iterator const_iterator
static FlagDefinition const MAXITER
static FlagDefinition const PSF_SHAPE_BAD
A FunctorKey that maps SdssShapeResult to afw::table Records.
Algorithm provides no uncertainy information at all.
void clip(Box2I const &other) noexcept
static FlagDefinition const FAILURE
void handleFailure(afw::table::BaseRecord &record, MeasurementError const *error=nullptr) const
Handle an expected or unexpected Exception thrown by a measurement algorithm.
A FunctorKey for CentroidResult.
void set(Key< T > const &key, U const &value)
CentroidElement y
y (row) coordinate of the measured position
void set(BaseRecord &record, geom::ellipses::Quadrupole const &value) const override
std::shared_ptr< lsst::afw::detection::Psf const > getPsf() const
meas::base::Flux instFlux
Measured instFlux in DN.
ErrElement instFlux_xx_Cov
instFlux, xx term in the uncertainty covariance matrix
bool getValue(afw::table::BaseRecord const &record, std::size_t i) const
Return the value of the flag field corresponding to the given flag index.
ErrElement yyErr
standard deviation of yy
SdssShapeResultKey()
Default constructor; instance will not be usuable unless subsequently assigned to.
FlagHandler const & getFlagHandler() const
Extent< double, 2 > Extent2D
ErrElement instFlux_xy_Cov
instFlux, xy term in the uncertainty covariance matrix
bool isValid() const noexcept
#define INSTANTIATE_PIXEL(PIXEL)
vector-type utility class to build a collection of FlagDefinitions
double getDeterminant() const
void setShape(Shape const &shape)
Set struct elements from the given Quadrupole object.
static SdssShapeResultKey addFields(afw::table::Schema &schema, std::string const &name, bool doMeasurePsf)
Add the appropriate fields to a Schema, and return a SdssShapeResultKey that manages them...
virtual void setPsfShape(afw::table::BaseRecord &record, afw::geom::ellipses::Quadrupole const &value) const
Set a Quadrupole for the Psf at the position of the given record.
Key< T > addField(Field< T > const &field, bool doReplace=false)
A reusable result struct for instFlux measurements.
int getMinY() const noexcept
CatalogIterator< typename Internal::iterator > iterator
double const getIxx() const
ShapeCov const getShapeErr() const
Return the 3x3 symmetric covariance matrix, with rows and columns ordered (xx, yy, xy)
static ShapeResultKey addFields(afw::table::Schema &schema, std::string const &name, std::string const &doc, UncertaintyEnum uncertainty, afw::table::CoordinateType coordType=afw::table::CoordinateType::PIXEL)
Add the appropriate fields to a Schema, and return a ShapeResultKey that manages them.