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) {
bool isValid() const
Return true if the key was initialized to valid offset.
An ellipse core with quadrupole moments as parameters.
Defines the fields and offsets for a table.
Eigen::Matrix< ShapeElement, 3, 3, Eigen::DontAlign > ShapeTrMatrix
bool getValue(afw::table::BaseRecord const &record, std::size_t i) const
afw::table::QuadrupoleKey _psfShapeResult
CentroidElement y
y (row) coordinate of the measured position
A proxy type for name lookups in a Schema.
ShapeTrMatrix makeShapeTransformMatrix(afw::geom::LinearTransform const &xform)
Construct a matrix suitable for transforming second moments.
table::Key< std::string > name
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 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.
int positionToIndex(double pos)
Convert image position to nearest integer index.
CentroidResultKey _centroidResult
virtual void fail(afw::table::SourceRecord &measRecord, MeasurementError *error=NULL) const
A custom container class for records, based on std::vector.
afw::table::Schema schema
A mapping between the keys of two Schemas, used to copy data between them.
bool operator==(SdssShapeResultKey const &other) const
Compare the FunctorKey for equality with another, using the underlying Keys.
A reusable struct for centroid measurements.
float tol2
"Convergence tolerance for FWHM" ;
iterator at(int const x, int const y) const
Return an iterator at the point (x, y)
bool isValid() const
Return True if all the constituent Keys are valid.
SafeCentroidExtractor _centroidExtractor
Point< double, 2 > Point2D
double const getIxx() const
Flux flux
Measured flux in DN.
ImagePtr getImage(bool const noThrow=false) const
Return a (Ptr to) the MaskedImage's image.
Implementation of the WCS standard for a any projection.
ErrElement flux_xy_Cov
flux, xy term in the uncertainty covariance matrix
static FluxResult computeFixedMomentsFlux(ImageT const &image, afw::geom::ellipses::Quadrupole const &shape, afw::geom::Point2D const &position)
virtual void set(afw::table::BaseRecord &record, SdssShapeResult const &value) const
Set an SdssShapeResult in the given record.
static Result computeAdaptiveMoments(ImageT const &image, afw::geom::Point2D const &position, bool negative=false, Control const &ctrl=Control())
Algorithm provides no uncertainy information at all.
Key< T > addField(Field< T > const &field, bool doReplace=false)
Add a new field to the Schema, and return the associated Key.
Exception to be thrown when a measurement algorithm experiences a known failure mode.
afw::geom::ellipses::Quadrupole getQuadrupole()
bool isValid() const
Return True if the shape key is valid.
void handleFailure(afw::table::BaseRecord &record, MeasurementError const *error=NULL) const
double const getIyy() const
An integer coordinate rectangle.
FluxErrElement fluxSigma
1-Sigma error (sqrt of variance) on flux in DN.
virtual void set(afw::table::BaseRecord &record, ShapeResult const &value) const
Set a ShapeResult in the given record.
A FunctorKey for ShapeResult.
table::Key< table::Array< Kernel::Pixel > > image
double background
"Additional value to add to background" ;
afw::table::Key< ErrElement > _flux_yy_Cov
Shape const getShape() const
Return an afw::geom::ellipses object corresponding to xx, yy, xy.
An include file to include the header files for lsst::afw::image.
A reusable struct for moments-based shape measurements.
FlagHandler const & getFlagHandler() const
double const getIxy() const
void setShapeErr(ShapeCov const &matrix)
Set the struct uncertainty elements from the given matrix, with rows and columns ordered (xx...
double const PI
The ratio of a circle's circumference to diameter.
MaskedImageT getMaskedImage()
Return the MaskedImage.
Result object SdssShapeAlgorithm.
static QuadrupoleKey addFields(Schema &schema, std::string const &name, std::string const &doc, CoordinateType coordType=CoordinateType::PIXEL)
virtual SdssShapeResult get(afw::table::BaseRecord const &record) const
Get an SdssShapeResult from the given record.
Custom catalog class for record/table subclasses that are guaranteed to have an ID, and should generally be sorted by that ID.
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...
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 both the flux and fluxSigma Keys are valid.
The full covariance matrix is provided.
AngleUnit const radians
constant with units of radians
Iterator class for CatalogT.
A class to manipulate images, masks, and variance as a single object.
SdssShapeResultKey()
Default constructor; instance will not be usuable unless subsequently assigned to.
double maxShift
"Maximum centroid shift, limited to 2-10" ;
afw::table::Key< ErrElement > _flux_xy_Cov
A C++ control class to handle SdssShapeAlgorithm's configuration.
Transformer transform(LinearTransform const &transform)
virtual void set(BaseRecord &record, geom::ellipses::Quadrupole const &value) const
Set a Quadrupole in the given record.
static FluxResultKey addFields(afw::table::Schema &schema, std::string const &name, std::string const &doc)
void setShape(Shape const &shape)
Set struct elements from the given Quadrupole object.
boost::shared_ptr< lsst::afw::detection::Psf > getPsf()
Return the Exposure's Psf object.
bool doMeasurePsf
"Whether to also compute the shape of the PSF model" ;
#define LSST_EXCEPT(type,...)
Base class for all records.
SdssShapeAlgorithm(Control const &ctrl, std::string const &name, afw::table::Schema &schema)
static FlagHandler addFields(afw::table::Schema &schema, std::string const &prefix, FlagDefinition const *begin, FlagDefinition const *end)
ShapeResultKey _shapeResult
A FunctorKey that maps SdssShapeResult to afw::table Records.
std::string join(std::string const &a, std::string const &b) const
Join strings using the field delimiter appropriate for this Schema.
CentroidElement x
x (column) coordinate of the measured position
void setValue(afw::table::BaseRecord &record, std::size_t i, bool value) const
A FunctorKey for CentroidResult.
std::bitset< SdssShapeAlgorithm::N_FLAGS > flags
Status flags (see SdssShapeAlgorithm).
void set(Key< T > const &key, U const &value)
Set value of a field for the given key.
Field< T >::Value get(Key< T > const &key) const
Return the value of a field for the given key.
Record class that contains measurements made on a single exposure.
Extent< double, 2 > Extent2D
SchemaItem< T > find(std::string const &name) const
Find a SchemaItem in the Schema by name.
#define INSTANTIATE_PIXEL(PIXEL)
ShapeCov const getShapeErr() const
Return the 3x3 symmetric covariance matrix, with rows and columns ordered (xx, yy, xy)
A polymorphic base class for representing an image's Point Spread Function.
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.
ErrElement flux_xx_Cov
flux, xx term in the uncertainty covariance matrix
double getDeterminant() const
Return the determinant of the matrix representation.
Only the diagonal elements of the covariance matrix are provided.
float tol1
"Convergence tolerance for e1,e2" ;
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...
bool isValid() const
Return True if the key is valid.
Schema getSchema() const
Return the schema associated with the catalog's table.
A reusable result struct for flux measurements.
virtual void measure(afw::table::SourceRecord &measRecord, afw::image::Exposure< float > const &exposure) const
Schema getSchema() const
Return the Schema that holds this record's fields and keys.
SdssShapeResult()
Constructor; initializes everything to NaN.
int maxIter
"Maximum number of iterations" ;
FluxResultKey _fluxResult
bool isValid() const
Return True if the centroid key is valid.
afw::table::Key< ErrElement > _flux_xx_Cov
ErrElement flux_yy_Cov
flux, yy term in the uncertainty covariance matrix