27 #include "boost/tuple/tuple.hpp"
38 namespace pexPolicy = lsst::pex::policy;
39 namespace pexExceptions = lsst::pex::exceptions;
40 namespace afwDet = lsst::afw::detection;
42 namespace afwGeom = lsst::afw::geom;
43 namespace afwTable = lsst::afw::table;
51 typedef Eigen::Matrix<double,4,4,Eigen::DontAlign> Matrix4d;
54 double computeFluxScale(SdssShapeResult
const & result) {
61 double const Mxx = result.xx;
62 double const Mxy = result.xy;
63 double const Myy = result.yy;
65 double const Muu_p_Mvv = Mxx + Myy;
66 double const Muu_m_Mvv = ::sqrt(::pow(Mxx - Myy, 2) + 4*::pow(Mxy, 2));
67 double const Muu = 0.5*(Muu_p_Mvv + Muu_m_Mvv);
68 double const Mvv = 0.5*(Muu_p_Mvv - Muu_m_Mvv);
86 calc_fisher(SdssShapeResult
const& shape,
89 float const A = shape.flux;
90 float const sigma11W = shape.xx;
91 float const sigma12W = shape.xy;
92 float const sigma22W = shape.yy;
94 double const D = sigma11W*sigma22W - sigma12W*sigma12W;
96 if (D <= std::numeric_limits<double>::epsilon()) {
97 throw LSST_EXCEPT(lsst::pex::exceptions::DomainError,
98 "Determinant is too small calculating Fisher matrix");
103 if (bkgd_var <= 0.0) {
104 throw LSST_EXCEPT(lsst::pex::exceptions::DomainError,
105 (
boost::format(
"Background variance must be positive (saw %g)") % bkgd_var).str());
113 double fac = F*A/(4.0*D);
115 fisher(0, 1) = fac*sigma22W;
116 fisher(1, 0) = fisher(0, 1);
117 fisher(0, 2) = fac*sigma11W;
118 fisher(2, 0) = fisher(0, 2);
119 fisher(0, 3) = -fac*2*sigma12W;
120 fisher(3, 0) = fisher(0, 3);
122 fac = 3.0*F*A*A/(16.0*D*D);
123 fisher(1, 1) = fac*sigma22W*sigma22W;
124 fisher(2, 2) = fac*sigma11W*sigma11W;
125 fisher(3, 3) = fac*4.0*(sigma12W*sigma12W + D/3.0);
127 fisher(1, 2) = fisher(3, 3)/4.0;
128 fisher(2, 1) = fisher(1, 2);
129 fisher(1, 3) = fac*(-2*sigma22W*sigma12W);
130 fisher(3, 1) = fisher(1, 3);
131 fisher(2, 3) = fac*(-2*sigma11W*sigma12W);
132 fisher(3, 2) = fisher(2, 3);
139 template<
typename ImageT>
140 struct ImageAdaptor {
141 typedef ImageT Image;
143 static bool const hasVariance =
false;
145 Image
const& getImage(ImageT
const&
image)
const {
149 double getVariance(ImageT
const&,
int,
int) {
150 return std::numeric_limits<double>::quiet_NaN();
155 struct ImageAdaptor<afwImage::MaskedImage<T> > {
158 static bool const hasVariance =
true;
165 return mimage.
at(ix, iy).variance();
170 std::tuple<std::pair<bool, double>, double, double,
double>
171 getWeights(
double sigma11,
double sigma12,
double sigma22) {
172 double const NaN = std::numeric_limits<double>::quiet_NaN();
173 if (std::isnan(sigma11) || std::isnan(sigma12) || std::isnan(sigma22)) {
174 return std::make_tuple(std::make_pair(
false, NaN), NaN, NaN, NaN);
176 double const det = sigma11*sigma22 - sigma12*sigma12;
177 if (std::isnan(det) || det < std::numeric_limits<float>::epsilon()) {
178 return std::make_tuple(std::make_pair(
false, det), NaN, NaN, NaN);
180 return std::make_tuple(std::make_pair(
true, det), sigma22/det, -sigma12/det, sigma11/det);
184 bool shouldInterp(
double sigma11,
double sigma22,
double det) {
185 float const xinterp = 0.25;
186 return (sigma11 < xinterp || sigma22 < xinterp || det < xinterp*xinterp);
192 afw::geom::Box2I computeAdaptiveMomentsBBox(
193 afw::geom::Box2I
const & bbox,
198 double maxRadius = 1000
200 double radius = std::min(4*std::sqrt(std::max(sigma11_w, sigma22_w)), maxRadius);
202 afw::geom::Box2I result(afw::geom::Box2D(center - offset, center + offset));
211 template<
bool fluxOnly,
typename ImageT>
213 calcmom(ImageT
const&
image,
214 float xcen,
float ycen,
218 double w11,
double w12,
double w22,
221 double *psumx,
double *psumy,
222 double *psumxx,
double *psumxy,
double *psumyy,
224 bool negative =
false
232 double sum, sumx, sumy, sumxx, sumyy, sumxy, sums4;
233 #define RECALC_W 0 // estimate sigmaXX_w within BBox?
235 double wsum, wsumxx, wsumxy, wsumyy;
237 wsum = wsumxx = wsumxy = wsumyy = 0;
241 if (fabs(w11) > 1e6 || fabs(w12) > 1e6 || fabs(w22) > 1e6) {
245 sum = sumx = sumy = sumxx = sumxy = sumyy = sums4 = 0;
247 int const ix0 = bbox.
getMinX();
248 int const ix1 = bbox.
getMaxX();
249 int const iy0 = bbox.
getMinY();
250 int const iy1 = bbox.
getMaxY();
252 if (ix0 < 0 || ix1 >= image.getWidth() || iy0 < 0 || iy1 >= image.getHeight()) {
256 for (
int i = iy0; i <= iy1; ++i) {
257 typename ImageT::x_iterator ptr = image.x_at(ix0, i);
258 float const y = i - ycen;
259 float const y2 = y*
y;
260 float const yl = y - 0.375;
261 float const yh = y + 0.375;
262 for (
int j = ix0; j <= ix1; ++j, ++ptr) {
265 float const xl = x - 0.375;
266 float const xh = x + 0.375;
268 float expon = xl*xl*w11 + yl*yl*w22 + 2.0*xl*yl*w12;
269 tmp = xh*xh*w11 + yh*yh*w22 + 2.0*xh*yh*w12;
270 expon = (expon > tmp) ? expon : tmp;
271 tmp = xl*xl*w11 + yh*yh*w22 + 2.0*xl*yh*w12;
272 expon = (expon > tmp) ? expon : tmp;
273 tmp = xh*xh*w11 + yl*yl*w22 + 2.0*xh*yl*w12;
274 expon = (expon > tmp) ? expon : tmp;
278 for (Y = yl; Y <= yh; Y += 0.25) {
279 double const interpY2 = Y*
Y;
280 for (X = xl; X <= xh; X += 0.25) {
281 double const interpX2 = X*
X;
282 double const interpXy = X*
Y;
283 expon = interpX2*w11 + 2*interpXy*w12 + interpY2*w22;
284 weight = std::exp(-0.5*expon);
289 sumx += ymod*(X + xcen);
290 sumy += ymod*(Y + ycen);
306 sumxx += interpX2*ymod;
307 sumxy += interpXy*ymod;
308 sumyy += interpY2*ymod;
310 sums4 += expon*expon*ymod;
318 float expon = x2*w11 + 2*xy*w12 + y2*w22;
321 weight = std::exp(-0.5*expon);
347 sums4 += expon*expon*ymod;
355 std::tuple<std::pair<bool, double>, double, double,
double>
const weights = getWeights(w11, w12, w22);
356 double const detW = std::get<1>(weights)*std::get<3>(weights) - std::pow(std::get<2>(weights), 2);
367 if (psums4 != NULL) {
373 if (wsum > 0 && !fluxOnly) {
374 double det = w11*w22 - w12*w12;
378 printf(
"%g %g %g %g %g %g\n", w22/det, -w12/det, w11/det, wsumxx, wsumxy, wsumyy);
383 return (fluxOnly || (sum < 0 && sumxx < 0 && sumyy < 0)) ? 0 : -1;
385 return (fluxOnly || (sum > 0 && sumxx > 0 && sumyy > 0)) ? 0 : -1;
394 template<
typename ImageT>
395 bool getAdaptiveMoments(ImageT
const& mimage,
double bkgd,
double xcen,
double ycen,
double shiftmax,
396 SdssShapeResult *shape,
int maxIter,
float tol1,
float tol2,
bool negative)
401 double sumxx, sumxy, sumyy;
403 float const xcen0 = xcen;
404 float const ycen0 = ycen;
406 double sigma11W = 1.5;
407 double sigma12W = 0.0;
408 double sigma22W = 1.5;
410 double w11 = -1, w12 = -1, w22 = -1;
411 float e1_old = 1e6, e2_old = 1e6;
412 float sigma11_ow_old = 1e6;
414 typename ImageAdaptor<ImageT>::Image
const &image = ImageAdaptor<ImageT>().getImage(mimage);
416 if (std::isnan(xcen) || std::isnan(ycen)) {
422 bool interpflag =
false;
425 for (; iter < maxIter; iter++) {
427 sigma11W, sigma12W, sigma22W);
428 std::tuple<std::pair<bool, double>, double, double,
double> weights =
429 getWeights(sigma11W, sigma12W, sigma22W);
430 if (!std::get<0>(weights).first) {
435 double const detW = std::get<0>(weights).second;
437 #if 0 // this form was numerically unstable on my G4 powerbook
440 assert(sigma11W*sigma22W >= sigma12W*sigma12W - std::numeric_limits<float>::epsilon());
444 const double ow11 = w11;
445 const double ow12 = w12;
446 const double ow22 = w22;
448 w11 = std::get<1>(weights);
449 w12 = std::get<2>(weights);
450 w22 = std::get<3>(weights);
452 if (shouldInterp(sigma11W, sigma22W, detW)) {
456 sigma11_ow_old = 1.e6;
466 if (calcmom<false>(image, xcen, ycen, bbox, bkgd, interpflag, w11, w12, w22,
467 &I0, &sum, &sumx, &sumy, &sumxx, &sumxy, &sumyy, &sums4, negative) < 0) {
484 if (fabs(shape->x - xcen0) > shiftmax || fabs(shape->y - ycen0) > shiftmax) {
490 float const sigma11_ow = sumxx/sum;
491 float const sigma22_ow = sumyy/sum;
492 float const sigma12_ow = sumxy/sum;
494 if (sigma11_ow <= 0 || sigma22_ow <= 0) {
499 float const d = sigma11_ow + sigma22_ow;
500 float const e1 = (sigma11_ow - sigma22_ow)/d;
501 float const e2 = 2.0*sigma12_ow/d;
506 fabs(e1 - e1_old) < tol1 && fabs(e2 - e2_old) < tol1 &&
507 fabs(sigma11_ow/sigma11_ow_old - 1.0) < tol2 ) {
513 sigma11_ow_old = sigma11_ow;
538 float ow11, ow12, ow22;
540 std::tuple<std::pair<bool, double>, double, double,
double> weights =
541 getWeights(sigma11_ow, sigma12_ow, sigma22_ow);
542 if (!std::get<0>(weights).first) {
547 ow11 = std::get<1>(weights);
548 ow12 = std::get<2>(weights);
549 ow22 = std::get<3>(weights);
555 weights = getWeights(n11, n12, n22);
556 if (!std::get<0>(weights).first) {
562 sigma11W = std::get<1>(weights);
563 sigma12W = std::get<2>(weights);
564 sigma22W = std::get<3>(weights);
567 if (sigma11W <= 0 || sigma22W <= 0) {
573 if (iter == maxIter) {
578 if (sumxx + sumyy == 0.0) {
586 if (calcmom<false>(image, xcen, ycen, bbox, bkgd, interpflag, w11, w12, w22,
587 &I0, &sum, &sumx, &sumy, &sumxx, &sumxy, &sumyy, NULL, negative) < 0 ||
588 (!negative && sum <= 0) || (negative && sum >= 0)) {
601 sigma11W = sumxx/sum;
602 sigma12W = sumxy/sum;
603 sigma22W = sumyy/sum;
607 shape->xx = sigma11W;
608 shape->xy = sigma12W;
609 shape->yy = sigma22W;
611 if (shape->xx + shape->yy != 0.0) {
615 if (ix >= 0 && ix < mimage.getWidth() && iy >= 0 && iy < mimage.getHeight()) {
616 float const bkgd_var =
617 ImageAdaptor<ImageT>().getVariance(mimage, ix, iy);
619 if (bkgd_var > 0.0) {
621 Matrix4d fisher = calc_fisher(*shape, bkgd_var);
622 Matrix4d cov = fisher.inverse();
626 shape->fluxSigma = std::sqrt(cov(0, 0));
627 shape->xxSigma = std::sqrt(cov(1, 1));
628 shape->xySigma = std::sqrt(cov(2, 2));
629 shape->yySigma = std::sqrt(cov(3, 3));
630 shape->flux_xx_Cov = cov(0, 1);
631 shape->flux_xy_Cov = cov(0, 2);
632 shape->flux_yy_Cov = cov(0, 3);
633 shape->xx_yy_Cov = cov(1, 3);
634 shape->xx_xy_Cov = cov(1, 2);
635 shape->yy_xy_Cov = cov(2, 3);
648 flux_xx_Cov(std::numeric_limits<
ErrElement>::quiet_NaN()),
649 flux_yy_Cov(std::numeric_limits<
ErrElement>::quiet_NaN()),
650 flux_xy_Cov(std::numeric_limits<
ErrElement>::quiet_NaN())
653 static std::array<FlagDefinition,SdssShapeAlgorithm::N_FLAGS>
const flagDefs = {{
654 {
"flag",
"general failure flag, set if anything went wrong"},
655 {
"flag_unweightedBad",
"Both weighted and unweighted moments were invalid"},
656 {
"flag_unweighted",
"Weighted moments converged to an invalid value; using unweighted moments"},
657 {
"flag_shift",
"centroid shifted by more than the maximum allowed amount"},
658 {
"flag_maxIter",
"Too many iterations in adaptive moments"},
659 {
"flag_psf",
"Failure in measuring PSF model shape"}
664 std::string
const &
name,
679 schema, schema.
join(name,
"psf"),
"adaptive moments of the PSF model at the object position");
685 schema.
join(name,
"flux",
"xx",
"Cov"),
687 % schema.
join(name,
"flux") % schema.
join(name,
"xx")).str(),
691 schema.
join(name,
"flux",
"yy",
"Cov"),
693 % schema.
join(name,
"flux") % schema.
join(name,
"yy")).str(),
697 schema.
join(name,
"flux",
"xy",
"Cov"),
699 % schema.
join(name,
"flux") % schema.
join(name,
"xy")).str(),
714 _flux_xx_Cov(s[
"flux"][
"xx"][
"Cov"]),
715 _flux_yy_Cov(s[
"flux"][
"yy"][
"Cov"]),
716 _flux_xy_Cov(s[
"flux"][
"xy"][
"Cov"])
723 }
catch (pex::exceptions::NotFoundError& e) {
760 afwGeom::ellipses::Quadrupole
const & value)
const {
788 std::string
const &
name,
792 _resultKey(
ResultKey::addFields(schema, name, ctrl.doMeasurePsf)),
793 _centroidExtractor(schema, name)
796 template <
typename ImageT>
798 ImageT
const & image,
803 double xcen = center.getX();
804 double ycen = center.getY();
806 xcen -= image.getX0();
807 ycen -= image.getY0();
812 }
else if (shiftmax > 10) {
819 image, control.
background, xcen, ycen, shiftmax, &result,
838 pex::exceptions::LogicError,
839 "Should not get singular moments unless a flag is set");
846 double fluxScale = computeFluxScale(result);
848 result.
flux *= fluxScale;
850 result.
x += image.getX0();
851 result.
y += image.getY0();
853 if (ImageAdaptor<ImageT>::hasVariance) {
862 template <
typename ImageT>
864 ImageT
const & image,
875 std::tuple<std::pair<bool, double>, double, double,
double> weights =
880 if (!std::get<0>(weights).first) {
881 throw pex::exceptions::InvalidParameterError(
"Input shape is singular");
884 double const w11 = std::get<1>(weights);
885 double const w12 = std::get<2>(weights);
886 double const w22 = std::get<3>(weights);
887 bool const interp = shouldInterp(shape.
getIxx(), shape.
getIyy(), std::get<0>(weights).second);
890 if (calcmom<true>(ImageAdaptor<ImageT>().getImage(image), localCenter.getX(), localCenter.getY(),
891 bbox, 0.0, interp, w11, w12, w22, &i0, NULL, NULL, NULL, NULL, NULL, NULL, NULL)< 0) {
892 throw LSST_EXCEPT(pex::exceptions::RuntimeError,
"Error from calcmom");
897 result.flux = i0*2*wArea;
899 if (ImageAdaptor<ImageT>::hasVariance) {
900 int ix =
static_cast<int>(center.getX() - image.getX0());
901 int iy =
static_cast<int>(center.getY() - image.getY0());
905 ix % iy % image.getWidth() % image.getHeight()).str());
907 double var = ImageAdaptor<ImageT>().getVariance(image, ix, iy);
908 double i0Err = std::sqrt(var/wArea);
909 result.fluxSigma = i0Err*2*wArea;
919 bool negative =
false;
922 negative = measRecord.
get(measRecord.
getSchema().
find<afw::table::Flag>(
"flags_negative").key);
962 #define INSTANTIATE_IMAGE(IMAGE) \
963 template SdssShapeResult SdssShapeAlgorithm::computeAdaptiveMoments( \
965 afw::geom::Point2D const &, \
969 template FluxResult SdssShapeAlgorithm::computeFixedMomentsFlux( \
971 afw::geom::ellipses::Quadrupole const &, \
972 afw::geom::Point2D const & \
975 #define INSTANTIATE_PIXEL(PIXEL) \
976 INSTANTIATE_IMAGE(lsst::afw::image::Image<PIXEL>); \
977 INSTANTIATE_IMAGE(lsst::afw::image::MaskedImage<PIXEL>);
985 std::string
const &
name,
989 _fluxTransform{
name, mapper},
990 _centroidTransform{
name, mapper}
993 _transformPsf = mapper.getInputSchema().getNames().count(
"sdssShape_flag_psf") ?
true :
false;
996 for (
auto flag = flagDefs.begin() + 1; flag < flagDefs.end() - (_transformPsf ? 0 : 1); flag++) {
997 mapper.addMapping(mapper.getInputSchema().find<afw::table::Flag>(
998 mapper.getInputSchema().join(
name, flag->name)).key);
1003 if (_transformPsf) {
1005 "PSF shape in celestial moments",
1031 for (; inSrc != inputCatalog.
end(); ++inSrc, ++outSrc) {
An ellipse core with quadrupole moments as parameters.
Defines the fields and offsets for a table.
bool doMeasurePsf
"Whether to also compute the shape of the PSF model" ;
A proxy type for name lookups in a Schema.
static Result computeAdaptiveMoments(ImageT const &image, afw::geom::Point2D const &position, bool negative=false, Control const &ctrl=Control())
Compute the adaptive Gaussian-weighted moments of an image.
afw::table::Key< ErrElement > _flux_yy_Cov
ShapeTrMatrix makeShapeTransformMatrix(afw::geom::LinearTransform const &xform)
Construct a matrix suitable for transforming second moments.
SafeCentroidExtractor _centroidExtractor
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.
virtual void set(BaseRecord &record, geom::ellipses::Quadrupole const &value) const
Set a Quadrupole in the given record.
table::Key< std::string > name
bool isValid() const
Return True if all the constituent Keys are valid.
Public header class for ellipse library.
geom::AffineTransform linearizePixelToSky(coord::Coord const &coord, geom::AngleUnit skyUnit=geom::degrees) const
Return the local linear approximation to Wcs::pixelToSky at a point given in sky coordinates.
tbl::Key< double > weight
static FluxResult computeFixedMomentsFlux(ImageT const &image, afw::geom::ellipses::Quadrupole const &shape, afw::geom::Point2D const &position)
Compute the flux within a fixed Gaussian aperture.
float tol2
"Convergence tolerance for FWHM" ;
int positionToIndex(double pos)
Convert image position to nearest integer index.
FlagHandler const & getFlagHandler() const
AngleUnit const radians
constant with units of radians
A custom container class for records, based on std::vector.
bool getValue(afw::table::BaseRecord const &record, std::size_t i) const
Return the value of the flag field corresponding to the given enum value.
afw::table::Schema schema
A mapping between the keys of two Schemas, used to copy data between them.
Only the diagonal elements of the covariance matrix are provided.
Extent< double, 2 > Extent2D
A reusable struct for centroid measurements.
iterator at(int const x, int const y) const
Return an iterator at the point (x, y)
afw::geom::ellipses::Quadrupole getQuadrupole()
double background
"Additional value to add to background" ;
The full covariance matrix is provided.
CentroidElement x
x (column) coordinate of the measured position
double const getIyy() const
ImagePtr getImage(bool const noThrow=false) const
Return a (Ptr to) the MaskedImage's image.
int maxIter
"Maximum number of iterations" ;
Implementation of the WCS standard for a any projection.
bool isValid() const
Return True if the centroid key is valid.
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...
std::string join(std::string const &a, std::string const &b) const
Join strings using the field delimiter appropriate for this Schema.
Transformer transform(LinearTransform const &transform)
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...
void set(Key< T > const &key, U const &value)
Set value of a field for the given key.
float tol1
"Convergence tolerance for e1,e2" ;
Describe an exposure's calibration.
double maxShift
"Maximum centroid shift, limited to 2-10" ;
bool isValid() const
Return True if the key is valid.
ErrElement flux_yy_Cov
flux, yy term in the uncertainty covariance matrix
bool operator==(SdssShapeResultKey const &other) const
Compare the FunctorKey for equality with another, using the underlying Keys.
Shape const getShape() const
Return an afw::geom::ellipses object corresponding to xx, yy, xy.
An integer coordinate rectangle.
ShapeResultKey _shapeResult
A FunctorKey for ShapeResult.
table::Key< table::Array< Kernel::Pixel > > 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.
bool isValid() const
Return true if the key was initialized to valid offset.
void setShapeErr(ShapeCov const &matrix)
Set the struct uncertainty elements from the given matrix, with rows and columns ordered (xx...
An include file to include the header files for lsst::afw::image.
Utility class for handling flag fields that indicate the failure modes of an algorithm.
A reusable struct for moments-based shape measurements.
metadata import lsst afw display as afwDisplay n
iterator begin()
Iterator access.
virtual void set(afw::table::BaseRecord &record, ShapeResult const &value) const
Set a ShapeResult in the given record.
MaskedImageT getMaskedImage()
Return the MaskedImage.
Result object SdssShapeAlgorithm.
Custom catalog class for record/table subclasses that are guaranteed to have an ID, and should generally be sorted by that ID.
SdssShapeResult()
Constructor; initializes everything to NaN.
bool isValid() const
Return True if both the flux and fluxSigma Keys are valid.
SdssShapeAlgorithm(Control const &ctrl, std::string const &name, afw::table::Schema &schema)
Iterator class for CatalogT.
bool isValid() const
Return True if the shape key is valid.
A class to manipulate images, masks, and variance as a single object.
CentroidResultKey _centroidResult
virtual afw::geom::ellipses::Quadrupole getPsfShape(afw::table::BaseRecord const &record) const
Get a Quadrupole for the Psf from the given record.
Flux flux
Measured flux in DN.
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...
Schema getSchema() const
Return the schema associated with the catalog's table.
A C++ control class to handle SdssShapeAlgorithm's configuration.
Field< T >::Value get(Key< T > const &key) const
Return the value of a field for the given key.
void setValue(afw::table::BaseRecord &record, std::size_t i, bool value) const
Set the flag field corresponding to the given enum value.
double const getIxy() const
virtual void set(afw::table::BaseRecord &record, SdssShapeResult const &value) const
Set an SdssShapeResult in the given record.
double const getIxx() const
std::bitset< SdssShapeAlgorithm::N_FLAGS > flags
Status flags (see SdssShapeAlgorithm).
boost::shared_ptr< lsst::afw::detection::Psf > getPsf()
Return the Exposure's Psf object.
#define LSST_EXCEPT(type,...)
Create an exception with a given type and message and optionally other arguments (dependent on the ty...
virtual SdssShapeResult get(afw::table::BaseRecord const &record) const
Get an SdssShapeResult from the given record.
virtual void fail(afw::table::SourceRecord &measRecord, MeasurementError *error=NULL) const
Handle an exception thrown by the current algorithm by setting flags in the given record...
Base class for all records.
A FunctorKey that maps SdssShapeResult to afw::table Records.
Schema getSchema() const
Return the Schema that holds this record's fields and keys.
Algorithm provides no uncertainy information at all.
iterator end()
Iterator access.
A FunctorKey for CentroidResult.
CentroidElement y
y (row) coordinate of the measured position
void handleFailure(afw::table::BaseRecord &record, MeasurementError const *error=NULL) const
Handle an expected or unexpected Exception thrown by a measurement algorithm.
afw::table::QuadrupoleKey _psfShapeResult
Point< double, 2 > Point2D
Key< T > addField(Field< T > const &field, bool doReplace=false)
Add a new field to the Schema, and return the associated Key.
SchemaItem< T > find(std::string const &name) const
Find a SchemaItem in the Schema by name.
Record class that contains measurements made on a single exposure.
afw::table::Key< ErrElement > _flux_xy_Cov
double const PI
The ratio of a circle's circumference to diameter.
SdssShapeResultKey()
Default constructor; instance will not be usuable unless subsequently assigned to.
double getDeterminant() const
Return the determinant of the matrix representation.
afw::table::Key< ErrElement > _flux_xx_Cov
#define INSTANTIATE_PIXEL(PIXEL)
A polymorphic base class for representing an image's Point Spread Function.
ErrElement flux_xx_Cov
flux, xx term in the uncertainty covariance matrix
void setShape(Shape const &shape)
Set struct elements from the given Quadrupole object.
FluxErrElement fluxSigma
1-Sigma error (sqrt of variance) on flux in DN.
Eigen::Matrix< ShapeElement, 3, 3, Eigen::DontAlign > ShapeTrMatrix
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...
A FunctorKey used to get or set a geom::ellipses::Quadrupole from a tuple of constituent Keys...
ShapeCov const getShapeErr() const
Return the 3x3 symmetric covariance matrix, with rows and columns ordered (xx, yy, xy)
static FlagHandler addFields(afw::table::Schema &schema, std::string const &prefix, FlagDefinition const *begin, FlagDefinition const *end)
Add Flag fields to a schema, creating a FlagHandler object to manage them.
FluxResultKey _fluxResult
A reusable result struct for flux measurements.
ErrElement flux_xy_Cov
flux, xy term in the uncertainty covariance matrix
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.