27 #include "boost/tuple/tuple.hpp" 45 namespace lsst {
namespace meas {
namespace base {
47 FlagDefinitionList flagDefinitions;
52 FlagDefinition
const SdssShapeAlgorithm::UNWEIGHTED = flagDefinitions.add(
"flag_unweighted",
"Weighted moments converged to an invalid value; using unweighted moments");
53 FlagDefinition
const SdssShapeAlgorithm::SHIFT = flagDefinitions.add(
"flag_shift",
"centroid shifted by more than the maximum allowed amount");
58 return flagDefinitions;
64 typedef Eigen::Matrix<double,4,4,Eigen::DontAlign> Matrix4d;
74 double const Mxx = result.
xx;
75 double const Mxy = result.
xy;
76 double const Myy = result.
yy;
78 double const Muu_p_Mvv = Mxx + Myy;
79 double const Muu_m_Mvv = ::sqrt(::pow(Mxx - Myy, 2) + 4*::pow(Mxy, 2));
80 double const Muu = 0.5*(Muu_p_Mvv + Muu_m_Mvv);
81 double const Mvv = 0.5*(Muu_p_Mvv - Muu_m_Mvv);
102 float const A = shape.
flux;
103 float const sigma11W = shape.
xx;
104 float const sigma12W = shape.
xy;
105 float const sigma22W = shape.
yy;
107 double const D = sigma11W*sigma22W - sigma12W*sigma12W;
111 "Determinant is too small calculating Fisher matrix");
116 if (bkgd_var <= 0.0) {
118 (boost::format(
"Background variance must be positive (saw %g)") % bkgd_var).str());
120 double const F = afwGeom::PI*sqrt(D)/bkgd_var;
126 double fac = F*A/(4.0*D);
128 fisher(0, 1) = fac*sigma22W;
129 fisher(1, 0) = fisher(0, 1);
130 fisher(0, 2) = fac*sigma11W;
131 fisher(2, 0) = fisher(0, 2);
132 fisher(0, 3) = -fac*2*sigma12W;
133 fisher(3, 0) = fisher(0, 3);
135 fac = 3.0*F*A*A/(16.0*D*D);
136 fisher(1, 1) = fac*sigma22W*sigma22W;
137 fisher(2, 2) = fac*sigma11W*sigma11W;
138 fisher(3, 3) = fac*4.0*(sigma12W*sigma12W + D/3.0);
140 fisher(1, 2) = fisher(3, 3)/4.0;
141 fisher(2, 1) = fisher(1, 2);
142 fisher(1, 3) = fac*(-2*sigma22W*sigma12W);
143 fisher(3, 1) = fisher(1, 3);
144 fisher(2, 3) = fac*(-2*sigma11W*sigma12W);
145 fisher(3, 2) = fisher(2, 3);
152 template<
typename ImageT>
153 struct ImageAdaptor {
154 typedef ImageT Image;
156 static bool const hasVariance =
false;
158 Image
const& getImage(ImageT
const& image)
const {
162 double getVariance(ImageT
const&,
int,
int) {
168 struct ImageAdaptor<afwImage::MaskedImage<T> > {
171 static bool const hasVariance =
true;
178 return mimage.
at(ix, iy).variance();
184 getWeights(
double sigma11,
double sigma12,
double sigma22) {
189 double const det = sigma11*sigma22 - sigma12*sigma12;
197 bool shouldInterp(
double sigma11,
double sigma22,
double det) {
198 float const xinterp = 0.25;
199 return (sigma11 < xinterp || sigma22 < xinterp || det < xinterp*xinterp);
211 double maxRadius = 1000
224 template<
bool fluxOnly,
typename ImageT>
226 calcmom(ImageT
const& image,
227 float xcen,
float ycen,
231 double w11,
double w12,
double w22,
234 double *psumx,
double *psumy,
235 double *psumxx,
double *psumxy,
double *psumyy,
237 bool negative =
false 245 double sum, sumx, sumy, sumxx, sumyy, sumxy, sums4;
246 #define RECALC_W 0 // estimate sigmaXX_w within BBox? 248 double wsum, wsumxx, wsumxy, wsumyy;
250 wsum = wsumxx = wsumxy = wsumyy = 0;
254 if (fabs(w11) > 1e6 || fabs(w12) > 1e6 || fabs(w22) > 1e6) {
258 sum = sumx = sumy = sumxx = sumxy = sumyy = sums4 = 0;
260 int const ix0 = bbox.
getMinX();
261 int const ix1 = bbox.
getMaxX();
262 int const iy0 = bbox.
getMinY();
263 int const iy1 = bbox.
getMaxY();
265 if (ix0 < 0 || ix1 >= image.getWidth() || iy0 < 0 || iy1 >= image.getHeight()) {
269 for (
int i = iy0; i <= iy1; ++i) {
270 typename ImageT::x_iterator ptr = image.x_at(ix0, i);
271 float const y = i - ycen;
272 float const y2 = y*y;
273 float const yl = y - 0.375;
274 float const yh = y + 0.375;
275 for (
int j = ix0; j <= ix1; ++j, ++ptr) {
278 float const xl = x - 0.375;
279 float const xh = x + 0.375;
281 float expon = xl*xl*w11 + yl*yl*w22 + 2.0*xl*yl*w12;
282 tmp = xh*xh*w11 + yh*yh*w22 + 2.0*xh*yh*w12;
283 expon = (expon > tmp) ? expon : tmp;
284 tmp = xl*xl*w11 + yh*yh*w22 + 2.0*xl*yh*w12;
285 expon = (expon > tmp) ? expon : tmp;
286 tmp = xh*xh*w11 + yl*yl*w22 + 2.0*xh*yl*w12;
287 expon = (expon > tmp) ? expon : tmp;
291 for (Y = yl; Y <= yh; Y += 0.25) {
292 double const interpY2 = Y*Y;
293 for (X = xl; X <= xh; X += 0.25) {
294 double const interpX2 = X*X;
295 double const interpXy = X*Y;
296 expon = interpX2*w11 + 2*interpXy*w12 + interpY2*w22;
302 sumx += ymod*(X + xcen);
303 sumy += ymod*(Y + ycen);
307 tmp = interpX2*weight;
311 tmp = interpXy*weight;
315 tmp = interpY2*weight;
319 sumxx += interpX2*ymod;
320 sumxy += interpXy*ymod;
321 sumyy += interpY2*ymod;
323 sums4 += expon*expon*ymod;
331 float expon = x2*w11 + 2*xy*w12 + y2*w22;
360 sums4 += expon*expon*ymod;
369 double const detW = std::get<1>(weights)*std::get<3>(weights) -
std::pow(std::get<2>(weights), 2);
370 *pI0 = sum/(afwGeom::PI*sqrt(detW));
380 if (psums4 != NULL) {
386 if (wsum > 0 && !fluxOnly) {
387 double det = w11*w22 - w12*w12;
391 printf(
"%g %g %g %g %g %g\n", w22/det, -w12/det, w11/det, wsumxx, wsumxy, wsumyy);
396 return (fluxOnly || (sum < 0 && sumxx < 0 && sumyy < 0)) ? 0 : -1;
398 return (fluxOnly || (sum > 0 && sumxx > 0 && sumyy > 0)) ? 0 : -1;
407 template<
typename ImageT>
408 bool getAdaptiveMoments(ImageT
const& mimage,
double bkgd,
double xcen,
double ycen,
double shiftmax,
409 SdssShapeResult *shape,
int maxIter,
float tol1,
float tol2,
bool negative)
414 double sumxx, sumxy, sumyy;
416 float const xcen0 = xcen;
417 float const ycen0 = ycen;
419 double sigma11W = 1.5;
420 double sigma12W = 0.0;
421 double sigma22W = 1.5;
423 double w11 = -1, w12 = -1, w22 = -1;
424 float e1_old = 1e6, e2_old = 1e6;
425 float sigma11_ow_old = 1e6;
427 typename ImageAdaptor<ImageT>::Image
const &image = ImageAdaptor<ImageT>().getImage(mimage);
431 shape->
flags[SdssShapeAlgorithm::UNWEIGHTED_BAD.number] =
true;
435 bool interpflag =
false;
438 for (; iter < maxIter; iter++) {
440 sigma11W, sigma12W, sigma22W);
442 getWeights(sigma11W, sigma12W, sigma22W);
443 if (!std::get<0>(weights).
first) {
444 shape->
flags[SdssShapeAlgorithm::UNWEIGHTED.number] =
true;
448 double const detW = std::get<0>(weights).
second;
450 #if 0 // this form was numerically unstable on my G4 powerbook 457 const double ow11 = w11;
458 const double ow12 = w12;
459 const double ow22 = w22;
461 w11 = std::get<1>(weights);
462 w12 = std::get<2>(weights);
463 w22 = std::get<3>(weights);
465 if (shouldInterp(sigma11W, sigma22W, detW)) {
469 sigma11_ow_old = 1.e6;
479 if (calcmom<false>(image, xcen, ycen, bbox, bkgd, interpflag, w11, w12, w22,
480 &I0, &sum, &sumx, &sumy, &sumxx, &sumxy, &sumyy, &sums4, negative) < 0) {
481 shape->
flags[SdssShapeAlgorithm::UNWEIGHTED.number] =
true;
497 if (fabs(shape->
x - xcen0) > shiftmax || fabs(shape->
y - ycen0) > shiftmax) {
498 shape->
flags[SdssShapeAlgorithm::SHIFT.number] =
true;
503 float const sigma11_ow = sumxx/sum;
504 float const sigma22_ow = sumyy/sum;
505 float const sigma12_ow = sumxy/sum;
507 if (sigma11_ow <= 0 || sigma22_ow <= 0) {
508 shape->
flags[SdssShapeAlgorithm::UNWEIGHTED.number] =
true;
512 float const d = sigma11_ow + sigma22_ow;
513 float const e1 = (sigma11_ow - sigma22_ow)/d;
514 float const e2 = 2.0*sigma12_ow/d;
519 fabs(e1 - e1_old) < tol1 && fabs(e2 - e2_old) < tol1 &&
520 fabs(sigma11_ow/sigma11_ow_old - 1.0) < tol2 ) {
526 sigma11_ow_old = sigma11_ow;
551 float ow11, ow12, ow22;
553 std::tuple<std::pair<bool, double>, double, double,
double> weights =
554 getWeights(sigma11_ow, sigma12_ow, sigma22_ow);
555 if (!std::get<0>(weights).first) {
556 shape->
flags[SdssShapeAlgorithm::UNWEIGHTED.number] =
true;
560 ow11 = std::get<1>(weights);
561 ow12 = std::get<2>(weights);
562 ow22 = std::get<3>(weights);
568 weights = getWeights(n11, n12, n22);
569 if (!std::get<0>(weights).first) {
571 shape->
flags[SdssShapeAlgorithm::UNWEIGHTED.number] =
true;
575 sigma11W = std::get<1>(weights);
576 sigma12W = std::get<2>(weights);
577 sigma22W = std::get<3>(weights);
580 if (sigma11W <= 0 || sigma22W <= 0) {
581 shape->
flags[SdssShapeAlgorithm::UNWEIGHTED.number] =
true;
586 if (iter == maxIter) {
587 shape->
flags[SdssShapeAlgorithm::UNWEIGHTED.number] =
true;
588 shape->
flags[SdssShapeAlgorithm::MAXITER.number] =
true;
591 if (sumxx + sumyy == 0.0) {
592 shape->
flags[SdssShapeAlgorithm::UNWEIGHTED.number] =
true;
597 if (shape->
flags[SdssShapeAlgorithm::UNWEIGHTED.number]) {
599 if (calcmom<false>(image, xcen, ycen, bbox, bkgd, interpflag, w11, w12, w22,
600 &I0, &sum, &sumx, &sumy, &sumxx, &sumxy, &sumyy, NULL, negative) < 0 ||
601 (!negative && sum <= 0) || (negative && sum >= 0)) {
602 shape->
flags[SdssShapeAlgorithm::UNWEIGHTED.number] =
false;
603 shape->
flags[SdssShapeAlgorithm::UNWEIGHTED_BAD.number] =
true;
614 sigma11W = sumxx/sum;
615 sigma12W = sumxy/sum;
616 sigma22W = sumyy/sum;
620 shape->
xx = sigma11W;
621 shape->
xy = sigma12W;
622 shape->
yy = sigma22W;
624 if (shape->
xx + shape->
yy != 0.0) {
628 if (ix >= 0 && ix < mimage.getWidth() && iy >= 0 && iy < mimage.getHeight()) {
629 float const bkgd_var =
630 ImageAdaptor<ImageT>().getVariance(mimage, ix, iy);
632 if (bkgd_var > 0.0) {
633 if (!(shape->
flags[SdssShapeAlgorithm::UNWEIGHTED.number])) {
634 Matrix4d fisher = calc_fisher(*shape, bkgd_var);
635 Matrix4d cov = fisher.inverse();
682 r._includePsf =
true;
684 schema, schema.
join(name,
"psf"),
"adaptive moments of the PSF model at the object position");
686 r._includePsf =
false;
690 schema.
join(name,
"flux",
"xx",
"Cov"),
691 (boost::format(
"uncertainty covariance between %s and %s")
692 % schema.
join(name,
"flux") % schema.
join(name,
"xx")).str(),
696 schema.
join(name,
"flux",
"yy",
"Cov"),
697 (boost::format(
"uncertainty covariance between %s and %s")
698 % schema.
join(name,
"flux") % schema.
join(name,
"yy")).str(),
702 schema.
join(name,
"flux",
"xy",
"Cov"),
703 (boost::format(
"uncertainty covariance between %s and %s")
704 % schema.
join(name,
"flux") % schema.
join(name,
"xy")).str(),
714 {SdssShapeAlgorithm::PSF_SHAPE_BAD});
723 _flux_xx_Cov(s[
"flux"][
"xx"][
"Cov"]),
724 _flux_yy_Cov(s[
"flux"][
"yy"][
"Cov"]),
725 _flux_xy_Cov(s[
"flux"][
"xy"][
"Cov"])
747 if (n == SdssShapeAlgorithm::PSF_SHAPE_BAD.number && !_includePsf)
continue;
754 return record.
get(_psfShapeResult);
758 record.
set(_shapeResult, value);
759 record.
set(_centroidResult, value);
760 record.
set(_fluxResult, value);
765 if (n == SdssShapeAlgorithm::PSF_SHAPE_BAD.number && !_includePsf)
continue;
771 afwGeom::ellipses::Quadrupole
const & value)
const {
772 record.
set(_psfShapeResult, value);
776 return _shapeResult == other._shapeResult &&
777 _centroidResult == other._centroidResult &&
778 _fluxResult == other._fluxResult &&
779 _psfShapeResult == other._psfShapeResult &&
780 _flux_xx_Cov == other._flux_xx_Cov &&
781 _flux_yy_Cov == other._flux_yy_Cov &&
782 _flux_xy_Cov == other._flux_xy_Cov;
787 return _shapeResult.
isValid() &&
804 _centroidExtractor(schema, name)
807 template <
typename ImageT>
809 ImageT
const & image,
814 double xcen = center.getX();
815 double ycen = center.getY();
817 xcen -= image.getX0();
818 ycen -= image.getY0();
823 }
else if (shiftmax > 10) {
830 image, control.
background, xcen, ycen, shiftmax, &result,
850 "Should not get singular moments unless a flag is set");
857 double fluxScale = computeFluxScale(result);
859 result.
flux *= fluxScale;
861 result.
x += image.getX0();
862 result.
y += image.getY0();
864 if (ImageAdaptor<ImageT>::hasVariance) {
873 template <
typename ImageT>
875 ImageT
const & image,
891 if (!std::get<0>(weights).first) {
895 double const w11 = std::get<1>(weights);
896 double const w12 = std::get<2>(weights);
897 double const w22 = std::get<3>(weights);
898 bool const interp = shouldInterp(shape.
getIxx(), shape.
getIyy(), std::get<0>(weights).
second);
901 if (calcmom<true>(ImageAdaptor<ImageT>().getImage(image), localCenter.getX(), localCenter.getY(),
902 bbox, 0.0, interp, w11, w12, w22, &i0, NULL, NULL, NULL, NULL, NULL, NULL, NULL)< 0) {
908 result.flux = i0*2*wArea;
910 if (ImageAdaptor<ImageT>::hasVariance) {
911 int ix =
static_cast<int>(center.getX() - image.getX0());
912 int iy =
static_cast<int>(center.getY() - image.getY0());
915 (boost::format(
"Center (%d,%d) not in image (%dx%d)") %
916 ix % iy % image.getWidth() % image.getHeight()).str());
918 double var = ImageAdaptor<ImageT>().getVariance(image, ix, iy);
920 result.fluxSigma = i0Err*2*wArea;
930 bool negative =
false;
933 negative = measRecord.
get(measRecord.
getSchema().
find<afw::table::Flag>(
"flags_negative").key);
934 }
catch(pexExcept::Exception &e) {
963 measRecord.
set(_resultKey, result);
973 #define INSTANTIATE_IMAGE(IMAGE) \ 974 template SdssShapeResult SdssShapeAlgorithm::computeAdaptiveMoments( \ 976 afw::geom::Point2D const &, \ 980 template FluxResult SdssShapeAlgorithm::computeFixedMomentsFlux( \ 982 afw::geom::ellipses::Quadrupole const &, \ 983 afw::geom::Point2D const & \ 986 #define INSTANTIATE_PIXEL(PIXEL) \ 987 INSTANTIATE_IMAGE(lsst::afw::image::Image<PIXEL>); \ 988 INSTANTIATE_IMAGE(lsst::afw::image::MaskedImage<PIXEL>); 1000 _fluxTransform{
name, mapper},
1001 _centroidTransform{
name, mapper}
1004 _transformPsf = mapper.getInputSchema().getNames().count(
"sdssShape_flag_psf") ? true :
false;
1009 if (flag == SdssShapeAlgorithm::FAILURE)
continue;
1010 if (mapper.getInputSchema().getNames().count(
1011 mapper.getInputSchema().join(
name, flag.
name)) == 0)
continue;
1014 mapper.addMapping(key);
1019 if (_transformPsf) {
1021 "PSF shape in celestial moments",
1034 _fluxTransform(inputCatalog, outputCatalog, wcs, calib);
1035 _centroidTransform(inputCatalog, outputCatalog, wcs, calib);
1040 if (_transformPsf) {
1047 for (; inSrc != inputCatalog.
end(); ++inSrc, ++outSrc) {
1060 _outShapeKey.
set(*outSrc, outShape);
1062 if (_transformPsf) {
1063 _outPsfShapeKey.
set(*outSrc, inPsfShapeKey.get(*inSrc).transform(crdTr.
getLinear()));
iterator at(int const x, int const y) const
std::size_t size() const
return the current size (number of defined elements) of the collection
virtual void set(afw::table::BaseRecord &record, ShapeResult const &value) const
Set a ShapeResult in the given record.
bool doMeasurePsf
"Whether to also compute the shape of the PSF model" ;
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, afw::geom::Point2D const &position, bool negative=false, Control const &ctrl=Control())
Compute the adaptive Gaussian-weighted moments of an image.
ShapeTrMatrix makeShapeTransformMatrix(afw::geom::LinearTransform const &xform)
Construct a matrix suitable for transforming second moments.
virtual void set(BaseRecord &record, geom::ellipses::Quadrupole const &value) const
ErrElement yy_xy_Cov
yy,xy term in the uncertainty convariance matrix
Extent< double, 2 > Extent2D
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)
static FlagDefinition const SHIFT
AngleUnit constexpr radians
std::string join(std::string const &a, std::string const &b) const
Shape const getShape() const
Return an afw::geom::ellipses object corresponding to xx, yy, xy.
Simple class used to define and document flags The name and doc constitute the identity of the FlagDe...
Only the diagonal elements of the covariance matrix are provided.
A reusable struct for centroid measurements.
afw::geom::ellipses::Quadrupole getQuadrupole()
double background
"Additional value to add to background" ;
bool isValid() const
Return True if the centroid key is valid.
The full covariance matrix is provided.
CentroidElement x
x (column) coordinate of the measured position
virtual void fail(afw::table::SourceRecord &measRecord, MeasurementError *error=nullptr) const
Handle an exception thrown by the current algorithm by setting flags in the given record...
int maxIter
"Maximum number of iterations" ;
bool operator==(SdssShapeResultKey const &other) const
Compare the FunctorKey for equality with another, using the underlying Keys.
SchemaItem< T > find(std::string const &name) const
Transformer transform(LinearTransform const &transform)
void setValue(afw::table::BaseRecord &record, std::size_t i, bool value) const
Set the flag field corresponding to the given flag index.
Key< T > addField(Field< T > const &field, bool doReplace=false)
Exception to be thrown when a measurement algorithm experiences a known failure mode.
static FlagDefinition const UNWEIGHTED
ErrElement xySigma
1-Sigma uncertainty on xy (sqrt of variance)
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...
Field< T >::Value get(Key< T > const &key) const
float tol1
"Convergence tolerance for e1,e2" ;
bool isValid() const
Return True if the key is valid.
static FlagDefinition const UNWEIGHTED_BAD
double maxShift
"Maximum centroid shift, limited to 2-10" ;
ErrElement flux_yy_Cov
flux, yy term in the uncertainty covariance matrix
ImagePtr getImage() const
A FunctorKey for ShapeResult.
ErrElement xx_xy_Cov
xx,xy term in the uncertainty convariance matrix
void setShapeErr(ShapeCov const &matrix)
Set the struct uncertainty elements from the given matrix, with rows and columns ordered (xx...
ErrElement xx_yy_Cov
xx,yy term in the uncertainty convariance matrix
Utility class for handling flag fields that indicate the failure modes of an algorithm.
A reusable struct for moments-based shape measurements.
double const getIxy() const
double const getIyy() const
static unsigned int const N_FLAGS
MaskedImageT getMaskedImage()
static QuadrupoleKey addFields(Schema &schema, std::string const &name, std::string const &doc, CoordinateType coordType=CoordinateType::PIXEL)
Result object SdssShapeAlgorithm.
Point< double, 2 > Point2D
static FlagDefinitionList const & getFlagDefinitions()
SdssShapeResult()
Constructor; initializes everything to NaN.
SdssShapeAlgorithm(Control const &ctrl, std::string const &name, afw::table::Schema &schema)
Flux flux
Measured flux in DN.
virtual void set(afw::table::BaseRecord &record, SdssShapeResult const &value) const
Set an SdssShapeResult in the given record.
static CentroidResultKey addFields(afw::table::Schema &schema, std::string const &name, std::string const &doc, UncertaintyEnum uncertainty)
Add the appropriate fields to a Schema, and return a CentroidResultKey that manages them...
A C++ control class to handle SdssShapeAlgorithm's configuration.
bool isValid() const
Return True if the shape key is valid.
bool isValid() const
Return True if both the flux and fluxSigma Keys are valid.
static FlagHandler addFields(afw::table::Schema &schema, std::string const &prefix, FlagDefinitionList const &flagDefs, FlagDefinitionList const &exclDefs=FlagDefinitionList::getEmptyList())
Add Flag fields to a schema, creating a FlagHandler object to manage them.
std::bitset< SdssShapeAlgorithm::N_FLAGS > flags
Status flags (see SdssShapeAlgorithm).
virtual SdssShapeResult get(afw::table::BaseRecord const &record) const
Get an SdssShapeResult from the given record.
virtual afw::geom::ellipses::Quadrupole getPsfShape(afw::table::BaseRecord const &record) const
Get a Quadrupole for the Psf from the given record.
#define LSST_EXCEPT(type,...)
Base::const_iterator const_iterator
static FlagDefinition const MAXITER
std::shared_ptr< lsst::afw::detection::Psf > getPsf()
static FlagDefinition const PSF_SHAPE_BAD
A FunctorKey that maps SdssShapeResult to afw::table Records.
Algorithm provides no uncertainy information at all.
static FlagDefinition const FAILURE
void handleFailure(afw::table::BaseRecord &record, MeasurementError const *error=nullptr) const
Handle an expected or unexpected Exception thrown by a measurement algorithm.
ErrElement yySigma
1-Sigma uncertainty on yy (sqrt of variance)
A FunctorKey for CentroidResult.
void set(Key< T > const &key, U const &value)
CentroidElement y
y (row) coordinate of the measured position
AffineTransform linearizePixelToSky(SpherePoint const &coord, AngleUnit const &skyUnit) const
ErrElement xxSigma
1-Sigma uncertainty on xx (sqrt of variance)
void clip(Box2I const &other)
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.
SdssShapeResultKey()
Default constructor; instance will not be usuable unless subsequently assigned to.
FlagHandler const & getFlagHandler() const
#define INSTANTIATE_PIXEL(PIXEL)
vector-type utility class to build a collection of FlagDefinitions
double getDeterminant() const
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...
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.
A reusable result struct for flux measurements.
ErrElement flux_xy_Cov
flux, xy term in the uncertainty covariance matrix
double const getIxx() const
ShapeCov const getShapeErr() const
Return the 3x3 symmetric covariance matrix, with rows and columns ordered (xx, yy, xy)
static ShapeResultKey addFields(afw::table::Schema &schema, std::string const &name, std::string const &doc, UncertaintyEnum uncertainty, afw::table::CoordinateType coordType=afw::table::CoordinateType::PIXEL)
Add the appropriate fields to a Schema, and return a ShapeResultKey that manages them.