27#include "boost/format.hpp"
43FlagDefinitionList 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");
62typedef Eigen::Matrix<double, 4, 4, Eigen::DontAlign> Matrix4d;
80 float const sigma11W = shape.
xx;
81 float const sigma12W = shape.
xy;
82 float const sigma22W = shape.
yy;
84 double const D = sigma11W * sigma22W - sigma12W * sigma12W;
92 if (bkgd_var <= 0.0) {
94 (boost::format(
"Background variance must be positive (saw %g)") % bkgd_var).
str());
96 double const F =
geom::PI * sqrt(D) / bkgd_var;
102 double fac = F * A / (4.0 * D);
104 fisher(0, 1) = fac * sigma22W;
105 fisher(1, 0) = fisher(0, 1);
106 fisher(0, 2) = fac * sigma11W;
107 fisher(2, 0) = fisher(0, 2);
108 fisher(0, 3) = -fac * 2 * sigma12W;
109 fisher(3, 0) = fisher(0, 3);
111 fac = 3.0 * F * A * A / (16.0 * D * D);
112 fisher(1, 1) = fac * sigma22W * sigma22W;
113 fisher(2, 2) = fac * sigma11W * sigma11W;
114 fisher(3, 3) = fac * 4.0 * (sigma12W * sigma12W + D / 3.0);
116 fisher(1, 2) = fisher(3, 3) / 4.0;
117 fisher(2, 1) = fisher(1, 2);
118 fisher(1, 3) = fac * (-2 * sigma22W * sigma12W);
119 fisher(3, 1) = fisher(1, 3);
120 fisher(2, 3) = fac * (-2 * sigma11W * sigma12W);
121 fisher(3, 2) = fisher(2, 3);
128template <
typename ImageT>
130 typedef ImageT Image;
132 static bool const hasVariance =
false;
134 Image
const &getImage(ImageT
const &image)
const {
return image; }
140struct ImageAdaptor<afw::image::MaskedImage<T> > {
143 static bool const hasVariance =
true;
145 Image
const &getImage(afw::image::MaskedImage<T>
const &mimage)
const {
return *mimage.getImage(); }
147 double getVariance(afw::image::MaskedImage<T>
const &mimage,
int ix,
int iy) {
148 return mimage.at(ix, iy).variance();
159 double const det = sigma11 * sigma22 - sigma12 * sigma12;
167bool shouldInterp(
double sigma11,
double sigma22,
double det) {
168 float const xinterp = 0.25;
169 return (sigma11 < xinterp || sigma22 < xinterp || det < xinterp * xinterp);
175geom::Box2I computeAdaptiveMomentsBBox(geom::Box2I
const &bbox,
180 double maxRadius = 1000
184 geom::Box2I result(geom::Box2D(center - offset, center + offset));
193template <
typename ImageT>
194static void calcmom(ImageT
const &image,
195 float xcen,
float ycen,
199 double w11,
double w12,
double w22,
206 double sum, sumx, sumy, sumxx, sumyy, sumxy, sums4;
208 if (w11 < 0 || w11 > 1e6 ||
fabs(w12) > 1E6 || w22 < 0 || w22 > 1e6) {
209 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
"Invalid weight parameter(s)");
212 sum = sumx = sumy = sumxx = sumxy = sumyy = sums4 = 0;
214 int const ix0 =
bbox.getMinX();
215 int const ix1 =
bbox.getMaxX();
216 int const iy0 =
bbox.getMinY();
217 int const iy1 =
bbox.getMaxY();
219 if (ix0 < 0 || ix1 >=
image.getWidth() || iy0 < 0 || iy1 >=
image.getHeight()) {
220 throw LSST_EXCEPT(pex::exceptions::LengthError,
"Invalid image dimensions");
223 for (
int i = iy0; i <= iy1; ++i) {
224 typename ImageT::x_iterator ptr =
image.x_at(ix0, i);
225 float const y = i - ycen;
226 float const y2 =
y *
y;
227 float const yl =
y - 0.375;
228 float const yh =
y + 0.375;
229 for (
int j = ix0; j <= ix1; ++j, ++ptr) {
232 float const xl =
x - 0.375;
233 float const xh =
x + 0.375;
235 float expon = xl * xl * w11 + yl * yl * w22 + 2.0 * xl * yl * w12;
236 tmp = xh * xh * w11 + yh * yh * w22 + 2.0 * xh * yh * w12;
237 expon = (expon > tmp) ? expon : tmp;
238 tmp = xl * xl * w11 + yh * yh * w22 + 2.0 * xl * yh * w12;
239 expon = (expon > tmp) ? expon : tmp;
240 tmp = xh * xh * w11 + yl * yl * w22 + 2.0 * xh * yl * w12;
241 expon = (expon > tmp) ? expon : tmp;
245 for (Y = yl;
Y <= yh;
Y += 0.25) {
246 double const interpY2 =
Y *
Y;
247 for (X = xl;
X <= xh;
X += 0.25) {
248 double const interpX2 =
X *
X;
249 double const interpXy =
X *
Y;
250 expon = interpX2 * w11 + 2 * interpXy * w12 + interpY2 * w22;
253 ymod = tmod * weight;
261 float expon = x2 * w11 + 2 * xy * w12 + y2 * w22;
266 ymod = tmod * weight;
277template <
typename ImageT>
278static int calcmom(ImageT
const &image,
279 float xcen,
float ycen,
283 double w11,
double w12,
double w22,
286 double &psumx,
double &psumy,
287 double &psumxx,
double &psumxy,
double &psumyy,
289 bool negative =
false) {
294 double sum, sumx, sumy, sumxx, sumyy, sumxy, sums4;
296 if (w11 < 0 || w11 > 1e6 ||
fabs(w12) > 1E6 || w22 < 0 || w22 > 1e6) {
297 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
"Invalid weight parameter(s)");
300 sum = sumx = sumy = sumxx = sumxy = sumyy = sums4 = 0;
302 int const ix0 =
bbox.getMinX();
303 int const ix1 =
bbox.getMaxX();
304 int const iy0 =
bbox.getMinY();
305 int const iy1 =
bbox.getMaxY();
307 if (ix0 < 0 || ix1 >=
image.getWidth() || iy0 < 0 || iy1 >=
image.getHeight()) {
308 throw LSST_EXCEPT(pex::exceptions::LengthError,
"Invalid image dimensions");
311 for (
int i = iy0; i <= iy1; ++i) {
312 typename ImageT::x_iterator ptr =
image.x_at(ix0, i);
313 float const y = i - ycen;
314 float const y2 =
y *
y;
315 float const yl =
y - 0.375;
316 float const yh =
y + 0.375;
317 for (
int j = ix0; j <= ix1; ++j, ++ptr) {
320 float const xl =
x - 0.375;
321 float const xh =
x + 0.375;
323 float expon = xl * xl * w11 + yl * yl * w22 + 2.0 * xl * yl * w12;
324 tmp = xh * xh * w11 + yh * yh * w22 + 2.0 * xh * yh * w12;
325 expon = (expon > tmp) ? expon : tmp;
326 tmp = xl * xl * w11 + yh * yh * w22 + 2.0 * xl * yh * w12;
327 expon = (expon > tmp) ? expon : tmp;
328 tmp = xh * xh * w11 + yl * yl * w22 + 2.0 * xh * yl * w12;
329 expon = (expon > tmp) ? expon : tmp;
333 for (Y = yl;
Y <= yh;
Y += 0.25) {
334 double const interpY2 =
Y *
Y;
335 for (X = xl;
X <= xh;
X += 0.25) {
336 double const interpX2 =
X *
X;
337 double const interpXy =
X *
Y;
338 expon = interpX2 * w11 + 2 * interpXy * w12 + interpY2 * w22;
341 ymod = tmod * weight;
343 sumx += ymod * (
X + xcen);
344 sumy += ymod * (
Y + ycen);
345 sumxx += interpX2 * ymod;
346 sumxy += interpXy * ymod;
347 sumyy += interpY2 * ymod;
348 sums4 += expon * expon * ymod;
355 float expon = x2 * w11 + 2 * xy * w12 + y2 * w22;
360 ymod = tmod * weight;
367 sums4 += expon * expon * ymod;
375 double const detW = std::get<1>(weights) * std::get<3>(weights) -
std::pow(std::get<2>(weights), 2);
390 return (sum < 0 && sumxx < 0 && sumyy < 0) ? 0 : -1;
392 return (sum > 0 && sumxx > 0 && sumyy > 0) ? 0 : -1;
401template <
typename ImageT>
402bool getAdaptiveMoments(ImageT
const &mimage,
double bkgd,
double xcen,
double ycen,
double shiftmax,
403 SdssShapeResult *shape,
int maxIter,
float tol1,
float tol2,
bool negative) {
407 double sumxx, sumxy, sumyy;
409 float const xcen0 = xcen;
410 float const ycen0 = ycen;
412 double sigma11W = 1.5;
413 double sigma12W = 0.0;
414 double sigma22W = 1.5;
416 double w11 = -1, w12 = -1, w22 = -1;
417 float e1_old = 1e6, e2_old = 1e6;
418 float sigma11_ow_old = 1e6;
420 typename ImageAdaptor<ImageT>::Image
const &
image = ImageAdaptor<ImageT>().getImage(mimage);
428 bool interpflag =
false;
433 sigma11W, sigma12W, sigma22W);
435 getWeights(sigma11W, sigma12W, sigma22W);
436 if (!std::get<0>(weights).first) {
441 double const detW = std::get<0>(weights).second;
446 const double ow11 = w11;
447 const double ow12 = w12;
448 const double ow22 = w22;
450 w11 = std::get<1>(weights);
451 w12 = std::get<2>(weights);
452 w22 = std::get<3>(weights);
454 if (shouldInterp(sigma11W, sigma22W, detW)) {
458 sigma11_ow_old = 1.e6;
467 if (calcmom(image, xcen, ycen, bbox, bkgd, interpflag, w11, w12, w22, I0, sum, sumx, sumy,
468 sumxx, sumxy, sumyy, sums4, negative) < 0) {
473 shape->x = sumx / sum;
474 shape->y = sumy / sum;
476 if (
fabs(shape->x - xcen0) > shiftmax ||
fabs(shape->y - ycen0) > shiftmax) {
482 float const sigma11_ow = sumxx / sum;
483 float const sigma22_ow = sumyy / sum;
484 float const sigma12_ow = sumxy / sum;
486 if (sigma11_ow <= 0 || sigma22_ow <= 0) {
491 float const d = sigma11_ow + sigma22_ow;
492 float const e1 = (sigma11_ow - sigma22_ow) / d;
493 float const e2 = 2.0 * sigma12_ow / d;
497 if (iter > 0 &&
fabs(e1 - e1_old) < tol1 &&
fabs(e2 - e2_old) < tol1 &&
498 fabs(sigma11_ow / sigma11_ow_old - 1.0) < tol2) {
504 sigma11_ow_old = sigma11_ow;
529 float ow11, ow12, ow22;
532 getWeights(sigma11_ow, sigma12_ow, sigma22_ow);
533 if (!std::get<0>(weights).first) {
538 ow11 = std::get<1>(weights);
539 ow12 = std::get<2>(weights);
540 ow22 = std::get<3>(weights);
546 weights = getWeights(n11, n12, n22);
547 if (!std::get<0>(weights).first) {
553 sigma11W = std::get<1>(weights);
554 sigma12W = std::get<2>(weights);
555 sigma22W = std::get<3>(weights);
558 if (sigma11W <= 0 || sigma22W <= 0) {
564 if (iter == maxIter) {
569 if (sumxx + sumyy == 0.0) {
578 if (calcmom(image, xcen, ycen, bbox, bkgd, interpflag, w11, w12, w22, I0, sum, sumx, sumy,
579 sumxx, sumxy, sumyy, ignored, negative) < 0 ||
580 (!negative && sum <= 0) || (negative && sum >= 0)) {
585 shape->xx = 1 / 12.0;
587 shape->yy = 1 / 12.0;
593 sigma11W = sumxx / sum;
594 sigma12W = sumxy / sum;
595 sigma22W = sumyy / sum;
598 shape->instFlux = I0;
599 shape->xx = sigma11W;
600 shape->xy = sigma12W;
601 shape->yy = sigma22W;
603 if (shape->xx + shape->yy != 0.0) {
607 if (ix >= 0 && ix < mimage.getWidth() && iy >= 0 && iy < mimage.getHeight()) {
608 float const bkgd_var = ImageAdaptor<ImageT>().getVariance(
611 if (bkgd_var > 0.0) {
613 Matrix4d fisher = calc_fisher(*shape, bkgd_var);
614 Matrix4d cov = fisher.inverse();
616 shape->instFluxErr =
std::sqrt(cov(0, 0));
620 shape->instFlux_xx_Cov = cov(0, 1);
621 shape->instFlux_yy_Cov = cov(0, 2);
622 shape->instFlux_xy_Cov = cov(0, 3);
623 shape->xx_yy_Cov = cov(1, 2);
624 shape->xx_xy_Cov = cov(1, 3);
625 shape->yy_xy_Cov = cov(2, 3);
637 : instFlux_xx_Cov(
std::numeric_limits<
ErrElement>::quiet_NaN()),
638 instFlux_yy_Cov(
std::numeric_limits<
ErrElement>::quiet_NaN()),
639 instFlux_xy_Cov(
std::numeric_limits<
ErrElement>::quiet_NaN()) {}
652 r._includePsf =
true;
654 schema,
schema.join(
name,
"psf"),
"adaptive moments of the PSF model at the object position");
656 r._includePsf =
false;
661 (boost::format(
"uncertainty covariance between %s and %s") %
667 (boost::format(
"uncertainty covariance between %s and %s") %
673 (boost::format(
"uncertainty covariance between %s and %s") %
692 _instFlux_xx_Cov(s[
"instFlux"][
"xx"][
"Cov"]),
693 _instFlux_yy_Cov(s[
"instFlux"][
"yy"][
"Cov"]),
694 _instFlux_xy_Cov(s[
"instFlux"][
"xy"][
"Cov"]) {
711 static_cast<FluxResult &
>(result) = record.
get(_instFluxResult);
723 return record.
get(_psfShapeResult);
727 record.
set(_shapeResult, value);
728 record.
set(_centroidResult, value);
729 record.
set(_instFluxResult, value);
741 record.
set(_psfShapeResult, value);
745 return _shapeResult == other._shapeResult && _centroidResult == other._centroidResult &&
746 _instFluxResult == other._instFluxResult && _psfShapeResult == other._psfShapeResult &&
747 _instFlux_xx_Cov == other._instFlux_xx_Cov && _instFlux_yy_Cov == other._instFlux_yy_Cov &&
748 _instFlux_xy_Cov == other._instFlux_xy_Cov;
765template <
typename ImageT>
767 bool negative,
Control const &control) {
768 double xcen = center.getX();
769 double ycen = center.getY();
771 xcen -=
image.getX0();
772 ycen -=
image.getY0();
777 }
else if (shiftmax > 10) {
785 control.
tol1, control.
tol2, negative);
797 double epsilon = 1.0e-6;
798 if (IxxIyy < (1.0 + epsilon) * Ixy_sq)
804 (boost::format(
"computeAdaptiveMoments IxxIxy %d < (1 + eps=%d)*(Ixy^2=%d);"
805 " implying singular moments without any flag set")
806 % IxxIyy % epsilon % Ixy_sq).
str());
821 result.
x +=
image.getX0();
822 result.
y +=
image.getY0();
824 if (ImageAdaptor<ImageT>::hasVariance) {
833template <
typename ImageT>
848 if (!std::get<0>(weights).
first) {
852 double const w11 = std::get<1>(weights);
853 double const w12 = std::get<2>(weights);
854 double const w22 = std::get<3>(weights);
855 bool const interp = shouldInterp(shape.
getIxx(), shape.
getIyy(), std::get<0>(weights).second);
858 calcmom(ImageAdaptor<ImageT>().getImage(
image), localCenter.getX(), localCenter.getY(),
bbox,
859 0.0, interp, w11, w12, w22, sum0);
863 if (ImageAdaptor<ImageT>::hasVariance) {
864 int ix =
static_cast<int>(center.getX() -
image.getX0());
865 int iy =
static_cast<int>(center.getY() -
image.getY0());
868 (boost::format(
"Center (%d,%d) not in image (%dx%d)") % ix % iy %
872 double var = ImageAdaptor<ImageT>().getVariance(
image, ix, iy);
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;
944 if (
mapper.getInputSchema().getNames().count(
mapper.getInputSchema().join(
name, flag.
name)) == 0)
947 mapper.getInputSchema().find<afw::table::Flag>(
name +
"_" + flag.
name).key;
955 "PSF shape in celestial moments",
956 afw::table::CoordinateType::CELESTIAL);
965 _instFluxTransform(inputCatalog, outputCatalog,
wcs,
photoCalib);
966 _centroidTransform(inputCatalog, outputCatalog,
wcs,
photoCalib);
978 for (; inSrc != inputCatalog.
end(); ++inSrc, ++outSrc) {
991 _outShapeKey.
set(*outSrc, outShape);
table::Key< std::string > name
#define LSST_EXCEPT(type,...)
#define INSTANTIATE_PIXEL(PIXEL)
table::Key< table::Array< std::uint8_t > > wcs
Transformer transform(lsst::geom::LinearTransform const &transform)
double const getIxy() const
double getDeterminant() const
double const getIxx() const
double const getIyy() const
MaskedImageT getMaskedImage()
std::shared_ptr< lsst::afw::detection::Psf const > getPsf() const
lsst::afw::image::Image< ImagePixelT > Image
Field< T >::Value get(Key< T > const &key) const
void set(Key< T > const &key, U const &value)
bool isValid() const noexcept
geom::ellipses::Quadrupole get(BaseRecord const &record) const override
void set(BaseRecord &record, geom::ellipses::Quadrupole const &value) const override
static QuadrupoleKey addFields(Schema &schema, std::string const &name, std::string const &doc, CoordinateType coordType=CoordinateType::PIXEL)
bool isValid() const noexcept
std::string join(std::string const &a, std::string const &b) const
SchemaItem< T > find(std::string const &name) const
typename Base::const_iterator const_iterator
A FunctorKey for CentroidResult.
virtual CentroidResult get(afw::table::BaseRecord const &record) const
Get a CentroidResult from the given record.
bool isValid() const
Return True if the centroid key is valid.
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.
vector-type utility class to build a collection of FlagDefinitions
std::size_t size() const
return the current size (number of defined elements) of the collection
Utility class for handling flag fields that indicate the failure modes of an algorithm.
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.
void setValue(afw::table::BaseRecord &record, std::size_t i, bool value) const
Set the flag field corresponding to the given flag index.
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.
bool isValid() const
Return True if both the instFlux and instFluxErr Keys are valid.
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...
Exception to be thrown when a measurement algorithm experiences a known failure mode.
static FlagDefinition const SHIFT
static FlagDefinitionList const & getFlagDefinitions()
virtual void measure(afw::table::SourceRecord &measRecord, afw::image::Exposure< float > const &exposure) const
Called to measure a single child source in an image.
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.
static FlagDefinition const FAILURE
static unsigned int const N_FLAGS
static FluxResult computeFixedMomentsFlux(ImageT const &image, afw::geom::ellipses::Quadrupole const &shape, geom::Point2D const &position)
Compute the instFlux within a fixed Gaussian aperture.
static FlagDefinition const MAXITER
static FlagDefinition const UNWEIGHTED
static FlagDefinition const PSF_SHAPE_BAD
static FlagDefinition const UNWEIGHTED_BAD
SdssShapeAlgorithm(Control const &ctrl, std::string const &name, afw::table::Schema &schema)
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.
A C++ control class to handle SdssShapeAlgorithm's configuration.
double maxShift
"Maximum centroid shift, limited to 2-10" ;
int maxIter
"Maximum number of iterations" ;
float tol2
"Convergence tolerance for FWHM" ;
bool doMeasurePsf
"Whether to also compute the shape of the PSF model" ;
float tol1
"Convergence tolerance for e1,e2" ;
double background
"Additional value to add to background" ;
Result object SdssShapeAlgorithm.
ErrElement instFlux_yy_Cov
instFlux, yy term in the uncertainty covariance matrix
SdssShapeResult()
Constructor; initializes everything to NaN.
ErrElement instFlux_xy_Cov
instFlux, xy term in the uncertainty covariance matrix
std::bitset< SdssShapeAlgorithm::N_FLAGS > flags
Status flags (see SdssShapeAlgorithm).
ErrElement instFlux_xx_Cov
instFlux, xx term in the uncertainty covariance matrix
A FunctorKey that maps SdssShapeResult to afw::table Records.
SdssShapeResultKey()
Default constructor; instance will not be usuable unless subsequently assigned to.
virtual SdssShapeResult get(afw::table::BaseRecord const &record) const
Get an SdssShapeResult from the given record.
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 afw::geom::ellipses::Quadrupole getPsfShape(afw::table::BaseRecord const &record) const
Get a Quadrupole for the Psf from the given record.
bool isValid() const
Return True if the key is valid.
bool operator==(SdssShapeResultKey const &other) const
Compare the FunctorKey for equality with another, using the underlying Keys.
virtual void set(afw::table::BaseRecord &record, SdssShapeResult const &value) const
Set an SdssShapeResult in the given record.
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.
FlagHandler const & getFlagHandler() const
A FunctorKey for ShapeResult.
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.
virtual ShapeResult get(afw::table::BaseRecord const &record) const
Get a ShapeResult from the given record.
bool isValid() const
Return True if the shape key is valid.
virtual void set(afw::table::BaseRecord &record, ShapeResult const &value) const
Set a ShapeResult in the given record.
int positionToIndex(double pos)
Extent< double, 2 > Extent2D
AngleUnit constexpr radians
Point< double, 2 > Point2D
@ SIGMA_ONLY
Only the diagonal elements of the covariance matrix are provided.
@ FULL_COVARIANCE
The full covariance matrix is provided.
@ NO_UNCERTAINTY
Algorithm provides no uncertainy information at all.
Eigen::Matrix< ShapeElement, 3, 3, Eigen::DontAlign > ShapeTrMatrix
ShapeTrMatrix makeShapeTransformMatrix(geom::LinearTransform const &xform)
Construct a matrix suitable for transforming second moments.
A reusable struct for centroid measurements.
CentroidElement y
y (row) coordinate of the measured position
Centroid const getCentroid() const
Return a Point object containing the measured x and y.
CentroidElement x
x (column) coordinate of the measured position
Simple class used to define and document flags The name and doc constitute the identity of the FlagDe...
A reusable result struct for instFlux measurements.
meas::base::Flux instFlux
Measured instFlux in DN.
meas::base::FluxErrElement instFluxErr
Standard deviation of instFlux in DN.
A reusable struct for moments-based shape measurements.
Shape const getShape() const
Return an afw::geom::ellipses object corresponding to xx, yy, xy.
ShapeCov const getShapeErr() const
Return the 3x3 symmetric covariance matrix, with rows and columns ordered (xx, yy,...
afw::geom::ellipses::Quadrupole getQuadrupole()
void setShape(Shape const &shape)
Set struct elements from the given Quadrupole object.
ShapeElement xy
image or model second moment for xy^2
ShapeElement xx
image or model second moment for x^2
void setShapeErr(ShapeCov const &matrix)
Set the struct standard deviation elements from the given matrix, with rows and columns ordered (xx,...
ShapeElement yy
image or model second moment for y^2