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;
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);
180 double maxRadius = 1000
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;
261 float expon = x2 * w11 + 2 * xy * w12 + y2 * w22;
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;
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;
367 sums4 += expon * expon * ymod;
375 double const detW = std::get<1>(weights) * std::get<3>(weights) -
std::pow(std::get<2>(weights), 2);
376 pI0 = sum / (
geom::PI * sqrt(detW));
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") %
662 schema.join(name,
"instFlux") %
schema.join(name,
"xx"))
667 (boost::format(
"uncertainty covariance between %s and %s") %
668 schema.join(name,
"instFlux") %
schema.join(name,
"yy"))
673 (boost::format(
"uncertainty covariance between %s and %s") %
674 schema.join(name,
"instFlux") %
schema.join(name,
"xy"))
692 _instFlux_xx_Cov(s[
"instFlux"][
"xx"][
"Cov"]),
693 _instFlux_yy_Cov(s[
"instFlux"][
"yy"][
"Cov"]),
694 _instFlux_xy_Cov(s[
"instFlux"][
"xy"][
"Cov"]) {
712 result.instFlux_xx_Cov = record.
get(_instFlux_xx_Cov);
713 result.instFlux_yy_Cov = record.
get(_instFlux_yy_Cov);
714 result.instFlux_xy_Cov = record.
get(_instFlux_xy_Cov);
723 return record.
get(_psfShapeResult);
727 record.
set(_shapeResult, value);
728 record.
set(_centroidResult, value);
729 record.
set(_instFluxResult, value);
730 record.
set(_instFlux_xx_Cov, value.instFlux_xx_Cov);
731 record.
set(_instFlux_yy_Cov, value.instFlux_yy_Cov);
732 record.
set(_instFlux_xy_Cov, value.instFlux_xy_Cov);
735 _flagHandler.
setValue(record, n, value.flags[n]);
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;
763 _centroidExtractor(
schema, name) {}
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);
794 double IxxIyy =
result.getQuadrupole().getIxx() *
result.getQuadrupole().getIyy();
795 double Ixy_sq =
result.getQuadrupole().getIxy();
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());
819 result.instFlux *= instFluxScale;
820 result.instFluxErr *= instFluxScale;
824 if (ImageAdaptor<ImageT>::hasVariance) {
825 result.instFlux_xx_Cov *= instFluxScale;
826 result.instFlux_yy_Cov *= instFluxScale;
827 result.instFlux_xy_Cov *= instFluxScale;
833template <
typename ImageT>
840 geom::BoxI const bbox = computeAdaptiveMomentsBBox(
image.getBBox(afw::image::LOCAL), localCenter,
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);
861 result.instFlux = sum0 * 2.0;
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);
890 exposure.getMaskedImage(), _centroidExtractor(measRecord, _resultKey.
getFlagHandler()), negative,
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",
965 _instFluxTransform(inputCatalog, outputCatalog, wcs, photoCalib);
966 _centroidTransform(inputCatalog, outputCatalog, wcs, photoCalib);
973 inputCatalog.getSchema()[inputCatalog.getSchema().join(
_name,
"psf")]);
978 for (; inSrc != inputCatalog.end(); ++inSrc, ++outSrc) {
991 _outShapeKey.
set(*outSrc, outShape);
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
A 2-dimensional celestial WCS that transform pixels to ICRS RA/Dec, using the LSST standard for pixel...
Transformer transform(lsst::geom::LinearTransform const &transform)
Return the transform that maps the ellipse to the unit circle.
An ellipse core with quadrupole moments as parameters.
double const getIxy() const
double getDeterminant() const
Return the determinant of the matrix representation.
double const getIxx() const
double const getIyy() const
A class to contain the data, WCS, and other information needed to describe an image of the sky.
A class to manipulate images, masks, and variance as a single object.
lsst::afw::image::Image< ImagePixelT > Image
The photometric calibration of an exposure.
Tag types used to declare specialized field types.
Base class for all records.
Field< T >::Value get(Key< T > const &key) const
Return the value of a field for the given key.
Schema getSchema() const
Return the Schema that holds this record's fields and keys.
void set(Key< T > const &key, U const &value)
Set value of a field for the given key.
iterator begin()
Iterator access.
bool isValid() const noexcept
Return true if the key was initialized to valid offset.
A FunctorKey used to get or set a geom::ellipses::Quadrupole from a tuple of constituent Keys.
geom::ellipses::Quadrupole get(BaseRecord const &record) const override
Get a Quadrupole from the given record.
void set(BaseRecord &record, geom::ellipses::Quadrupole const &value) const override
Set a Quadrupole in the given record.
static QuadrupoleKey addFields(Schema &schema, std::string const &name, std::string const &doc, CoordinateType coordType=CoordinateType::PIXEL)
Add a set of quadrupole subfields to a schema and return a QuadrupoleKey that points to them.
bool isValid() const noexcept
Return True if all the constituent Keys are valid.
Defines the fields and offsets for a table.
SchemaItem< T > find(std::string const &name) const
Find a SchemaItem in the Schema by name.
A mapping between the keys of two Schemas, used to copy data between them.
typename Base::const_iterator const_iterator
Record class that contains measurements made on a single exposure.
A proxy type for name lookups in a Schema.
A floating-point coordinate rectangle geometry.
An integer coordinate rectangle.
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.
SdssShapeResult()
Constructor; initializes everything to NaN.
std::bitset< SdssShapeAlgorithm::N_FLAGS > flags
Status flags (see SdssShapeAlgorithm).
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.
Reports arguments outside the domain of an operation.
Provides consistent interface for LSST exceptions.
Reports invalid arguments.
Reports errors in the logical structure of the program.
Reports attempts to access elements using an invalid key.
Reports errors that are due to events beyond the control of the program.
int positionToIndex(double pos)
Convert image position to nearest integer index.
Extent< double, 2 > Extent2D
AngleUnit constexpr radians
constant with units of radians
double constexpr PI
The ratio of a circle's circumference to diameter.
@ 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.
afw::table::Key< double > weight
#define INSTANTIATE_PIXEL(PIXEL)
A reusable struct for centroid measurements.
Centroid const getCentroid() const
Return a Point object containing the measured x and y.
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.
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,...
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
g2d::python::Image< double > Image