LSST Applications  21.0.0-172-gfb10e10a+18fedfabac,22.0.0+297cba6710,22.0.0+80564b0ff1,22.0.0+8d77f4f51a,22.0.0+a28f4c53b1,22.0.0+dcf3732eb2,22.0.1-1-g7d6de66+2a20fdde0d,22.0.1-1-g8e32f31+297cba6710,22.0.1-1-geca5380+7fa3b7d9b6,22.0.1-12-g44dc1dc+2a20fdde0d,22.0.1-15-g6a90155+515f58c32b,22.0.1-16-g9282f48+790f5f2caa,22.0.1-2-g92698f7+dcf3732eb2,22.0.1-2-ga9b0f51+7fa3b7d9b6,22.0.1-2-gd1925c9+bf4f0e694f,22.0.1-24-g1ad7a390+a9625a72a8,22.0.1-25-g5bf6245+3ad8ecd50b,22.0.1-25-gb120d7b+8b5510f75f,22.0.1-27-g97737f7+2a20fdde0d,22.0.1-32-gf62ce7b1+aa4237961e,22.0.1-4-g0b3f228+2a20fdde0d,22.0.1-4-g243d05b+871c1b8305,22.0.1-4-g3a563be+32dcf1063f,22.0.1-4-g44f2e3d+9e4ab0f4fa,22.0.1-42-gca6935d93+ba5e5ca3eb,22.0.1-5-g15c806e+85460ae5f3,22.0.1-5-g58711c4+611d128589,22.0.1-5-g75bb458+99c117b92f,22.0.1-6-g1c63a23+7fa3b7d9b6,22.0.1-6-g50866e6+84ff5a128b,22.0.1-6-g8d3140d+720564cf76,22.0.1-6-gd805d02+cc5644f571,22.0.1-8-ge5750ce+85460ae5f3,master-g6e05de7fdc+babf819c66,master-g99da0e417a+8d77f4f51a,w.2021.48
LSST Data Management Base Package
Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Attributes | List of all members
lsst::meas::base::SdssShapeAlgorithm Class Reference

Measure the image moments of source using adaptive Gaussian weights. More...

#include <SdssShape.h>

Inheritance diagram for lsst::meas::base::SdssShapeAlgorithm:
lsst::meas::base::SimpleAlgorithm lsst::meas::base::SingleFrameAlgorithm lsst::meas::base::ForcedAlgorithm lsst::meas::base::BaseAlgorithm lsst::meas::base::BaseAlgorithm

Public Types

typedef SdssShapeControl Control
 
typedef SdssShapeResult Result
 
typedef SdssShapeResultKey ResultKey
 

Public Member Functions

 SdssShapeAlgorithm (Control const &ctrl, std::string const &name, afw::table::Schema &schema)
 
virtual void measure (afw::table::SourceRecord &measRecord, afw::image::Exposure< float > const &exposure) const
 Called to measure a single child source in an image. More...
 
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. More...
 
template<typename ImageT >
SdssShapeResult computeAdaptiveMoments (ImageT const &image, geom::Point2D const &center, bool negative, Control const &control)
 
virtual void measureForced (afw::table::SourceRecord &measRecord, afw::image::Exposure< float > const &exposure, afw::table::SourceRecord const &refRecord, afw::geom::SkyWcs const &refWcs) const
 Called to measure a single child source in an image. More...
 
virtual void measureNForced (afw::table::SourceCatalog const &measCat, afw::image::Exposure< float > const &exposure, afw::table::SourceCatalog const &refRecord, afw::geom::SkyWcs const &refWcs) const
 Called to simultaneously measure all children in a deblend family, in a single image. More...
 
virtual void measureN (afw::table::SourceCatalog const &measCat, afw::image::Exposure< float > const &exposure) const
 Called to simultaneously measure all children in a deblend family, in a single image. More...
 
std::string getLogName () const
 

Static Public Member Functions

static FlagDefinitionList const & getFlagDefinitions ()
 
template<typename ImageT >
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. More...
 
template<typename ImageT >
static FluxResult computeFixedMomentsFlux (ImageT const &image, afw::geom::ellipses::Quadrupole const &shape, geom::Point2D const &position)
 Compute the instFlux within a fixed Gaussian aperture. More...
 

Static Public Attributes

static unsigned int const N_FLAGS = 6
 
static FlagDefinition const FAILURE = flagDefinitions.addFailureFlag()
 
static FlagDefinition const UNWEIGHTED_BAD
 
static FlagDefinition const UNWEIGHTED
 
static FlagDefinition const SHIFT
 
static FlagDefinition const MAXITER
 
static FlagDefinition const PSF_SHAPE_BAD
 

Protected Attributes

std::string _logName
 

Detailed Description

Measure the image moments of source using adaptive Gaussian weights.

This algorithm measures the weighted second moments of an image using a Gaussian weight function, which is iteratively updated to match the current weights. If this iteration does not converge, it can fall back to using unweighted moments, which can be significantly noisier.

See Bernstein & Jarvis, 2002, for more information on this type of algorithm. Note that the code here makes no attempt to correct for the PSF; for PSF corrected ellipticities using weighted moments please use the shapeHSM package.

Definition at line 150 of file SdssShape.h.

Member Typedef Documentation

◆ Control

Definition at line 162 of file SdssShape.h.

◆ Result

Definition at line 163 of file SdssShape.h.

◆ ResultKey

Definition at line 164 of file SdssShape.h.

Constructor & Destructor Documentation

◆ SdssShapeAlgorithm()

lsst::meas::base::SdssShapeAlgorithm::SdssShapeAlgorithm ( Control const &  ctrl,
std::string const &  name,
afw::table::Schema schema 
)

Definition at line 744 of file SdssShape.cc.

746  : _ctrl(ctrl),
747  _resultKey(ResultKey::addFields(schema, name, ctrl.doMeasurePsf)),
748  _centroidExtractor(schema, name) {}
table::Key< std::string > name
Definition: Amplifier.cc:116
table::Schema schema
Definition: python.h:134
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.
Definition: SdssShape.cc:626

Member Function Documentation

◆ computeAdaptiveMoments() [1/2]

template<typename ImageT >
SdssShapeResult lsst::meas::base::SdssShapeAlgorithm::computeAdaptiveMoments ( ImageT const &  image,
geom::Point2D const &  center,
bool  negative,
Control const &  control 
)

Definition at line 751 of file SdssShape.cc.

752  {
753  double xcen = center.getX(); // object's column position
754  double ycen = center.getY(); // object's row position
755 
756  xcen -= image.getX0(); // work in image Pixel coordinates
757  ycen -= image.getY0();
758 
759  float shiftmax = control.maxShift; // Max allowed centroid shift
760  if (shiftmax < 2) {
761  shiftmax = 2;
762  } else if (shiftmax > 10) {
763  shiftmax = 10;
764  }
765 
766  SdssShapeResult result;
767  try {
768  result.flags[FAILURE.number] =
769  !getAdaptiveMoments(image, control.background, xcen, ycen, shiftmax, &result, control.maxIter,
770  control.tol1, control.tol2, negative);
771  } catch (pex::exceptions::Exception &err) {
772  result.flags[FAILURE.number] = true;
773  }
774  if (result.flags[UNWEIGHTED.number] || result.flags[SHIFT.number]) {
775  // These are also considered fatal errors in terms of the quality of the results,
776  // even though they do produce some results.
777  result.flags[FAILURE.number] = true;
778  }
779  double IxxIyy = result.getQuadrupole().getIxx() * result.getQuadrupole().getIyy();
780  double Ixy_sq = result.getQuadrupole().getIxy();
781  Ixy_sq *= Ixy_sq;
782  double epsilon = 1.0e-6;
783  if (IxxIyy < (1.0 + epsilon) * Ixy_sq)
784  // We are checking that Ixx*Iyy > (1 + epsilon)*Ixy*Ixy where epsilon is suitably small. The
785  // value of epsilon used here is a magic number subject to future review (DM-5801 was marked won't fix).
786  {
787  if (!result.flags[FAILURE.number]) {
788  throw LSST_EXCEPT(pex::exceptions::LogicError,
789  (boost::format("computeAdaptiveMoments IxxIxy %d < (1 + eps=%d)*(Ixy^2=%d);"
790  " implying singular moments without any flag set")
791  % IxxIyy % epsilon % Ixy_sq).str());
792  }
793  }
794 
795  // getAdaptiveMoments() just computes the zeroth moment in result.instFlux (and its error in
796  // result.instFluxErr, result.instFlux_xx_Cov, etc.) That's related to the instFlux by some geometric
797  // factors, which we apply here.
798  // This scale factor is just the inverse of the normalization constant in a bivariate normal distribution:
799  // 2*pi*sigma_x*sigma_y*sqrt(1-rho^2), where rho is the correlation.
800  // This happens to be twice the ellipse area pi*sigma_maj*sigma_min, which is identically equal to:
801  // pi*sqrt(I_xx*I_yy - I_xy^2); i.e. pi*sqrt(determinant(I))
802  double instFluxScale = geom::TWOPI * std::sqrt(IxxIyy - Ixy_sq);
803 
804  result.instFlux *= instFluxScale;
805  result.instFluxErr *= instFluxScale;
806  result.x += image.getX0();
807  result.y += image.getY0();
808 
809  if (ImageAdaptor<ImageT>::hasVariance) {
810  result.instFlux_xx_Cov *= instFluxScale;
811  result.instFlux_yy_Cov *= instFluxScale;
812  result.instFlux_xy_Cov *= instFluxScale;
813  }
814 
815  return result;
816 }
py::object result
Definition: _schema.cc:429
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
static FlagDefinition const SHIFT
Definition: SdssShape.h:158
static FlagDefinition const FAILURE
Definition: SdssShape.h:155
static FlagDefinition const UNWEIGHTED
Definition: SdssShape.h:157
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
constexpr double TWOPI
Definition: Angle.h:40
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:174
T sqrt(T... args)

◆ computeAdaptiveMoments() [2/2]

template<typename ImageT >
static Result lsst::meas::base::SdssShapeAlgorithm::computeAdaptiveMoments ( ImageT const &  image,
geom::Point2D const &  position,
bool  negative = false,
Control const &  ctrl = Control() 
)
static

Compute the adaptive Gaussian-weighted moments of an image.

Parameters
[in]imageAn Image or MaskedImage instance with int, float, or double pixels. This need not be a small postage stamp (the pixel region actually used in the fit will be a subset of this image determined automatically).
[in]positionCenter position of the object to be measured, in the image's PARENT coordinates.
[in]negativeBoolean, specify if the source is in negative instFlux space
[in]ctrlControl object specifying the details of how the object is to be measured.

◆ computeFixedMomentsFlux()

template<typename ImageT >
template FluxResult lsst::meas::base::SdssShapeAlgorithm::computeFixedMomentsFlux ( ImageT const &  image,
afw::geom::ellipses::Quadrupole const &  shape,
geom::Point2D const &  position 
)
static

Compute the instFlux within a fixed Gaussian aperture.

Parameters
[in]imageAn Image or MaskedImage instance with int, float, or double pixels. This need not be a small postage stamp (the pixel region actually used in the fit will be a subset of this image determined automatically).
[in]shapeEllipse object specifying the 1-sigma contour of the Gaussian.
[in]positionCenter position of the object to be measured, in the image's PARENT coordinates.

Definition at line 819 of file SdssShape.cc.

821  {
822  // while arguments to computeFixedMomentsFlux are in PARENT coordinates, the implementation is LOCAL.
823  geom::Point2D localCenter = center - geom::Extent2D(image.getXY0());
824 
825  geom::BoxI const bbox = computeAdaptiveMomentsBBox(image.getBBox(afw::image::LOCAL), localCenter,
826  shape.getIxx(), shape.getIxy(), shape.getIyy());
827 
828  std::tuple<std::pair<bool, double>, double, double, double> weights =
829  getWeights(shape.getIxx(), shape.getIxy(), shape.getIyy());
830 
831  FluxResult result;
832 
833  if (!std::get<0>(weights).first) {
834  throw pex::exceptions::InvalidParameterError("Input shape is singular");
835  }
836 
837  double const w11 = std::get<1>(weights);
838  double const w12 = std::get<2>(weights);
839  double const w22 = std::get<3>(weights);
840  bool const interp = shouldInterp(shape.getIxx(), shape.getIyy(), std::get<0>(weights).second);
841 
842  double sum0 = 0; // sum of pixel values weighted by a Gaussian
843  if (calcmom<true>(ImageAdaptor<ImageT>().getImage(image), localCenter.getX(), localCenter.getY(), bbox,
844  0.0, interp, w11, w12, w22, NULL, &sum0, NULL, NULL, NULL, NULL, NULL, NULL) < 0) {
845  throw LSST_EXCEPT(pex::exceptions::RuntimeError, "Error from calcmom");
846  }
847 
848  result.instFlux = sum0 * 2.0;
849 
850  if (ImageAdaptor<ImageT>::hasVariance) {
851  int ix = static_cast<int>(center.getX() - image.getX0());
852  int iy = static_cast<int>(center.getY() - image.getY0());
853  if (!image.getBBox(afw::image::LOCAL).contains(geom::Point2I(ix, iy))) {
854  throw LSST_EXCEPT(pex::exceptions::RuntimeError,
855  (boost::format("Center (%d,%d) not in image (%dx%d)") % ix % iy %
856  image.getWidth() % image.getHeight())
857  .str());
858  }
859  double var = ImageAdaptor<ImageT>().getVariance(image, ix, iy);
860  // 0th moment (i0) error = sqrt(var / wArea); instFlux (error) = 2 * wArea * i0 (error)
861  double const wArea = geom::PI * std::sqrt(shape.getDeterminant());
862  result.instFluxErr = 2 * std::sqrt(var * wArea);
863  }
864 
865  return result;
866 }
AmpInfoBoxKey bbox
Definition: Amplifier.cc:117
An integer coordinate rectangle.
Definition: Box.h:55
constexpr double PI
The ratio of a circle's circumference to diameter.
Definition: Angle.h:39
Extent< double, 2 > Extent2D
Definition: Extent.h:400

◆ fail()

void lsst::meas::base::SdssShapeAlgorithm::fail ( afw::table::SourceRecord measRecord,
MeasurementError error = nullptr 
) const
virtual

Handle an exception thrown by the current algorithm by setting flags in the given record.

fail() is called by the measurement framework when an exception is allowed to propagate out of one the algorithm's measure() methods. It should generally set both a general failure flag for the algorithm as well as a specific flag indicating the error condition, if possible. To aid in this, if the exception was an instance of MeasurementError, it will be passed in, carrying information about what flag to set.

An algorithm can also to chose to set flags within its own measure() methods, and then just return, rather than throw an exception. However, fail() should be implemented even when all known failure modes do not throw exceptions, to ensure that unexpected exceptions thrown in lower-level code are properly handled.

Implements lsst::meas::base::BaseAlgorithm.

Definition at line 903 of file SdssShape.cc.

903  {
904  _resultKey.getFlagHandler().handleFailure(measRecord, error);
905 }
void handleFailure(afw::table::BaseRecord &record, MeasurementError const *error=nullptr) const
Handle an expected or unexpected Exception thrown by a measurement algorithm.
Definition: FlagHandler.cc:76
FlagHandler const & getFlagHandler() const
Definition: SdssShape.h:125

◆ getFlagDefinitions()

FlagDefinitionList const & lsst::meas::base::SdssShapeAlgorithm::getFlagDefinitions ( )
static

Definition at line 58 of file SdssShape.cc.

58 { return flagDefinitions; }

◆ getLogName()

std::string lsst::meas::base::BaseAlgorithm::getLogName ( ) const
inlineinherited

Definition at line 66 of file Algorithm.h.

66 { return _logName; }

◆ measure()

void lsst::meas::base::SdssShapeAlgorithm::measure ( afw::table::SourceRecord measRecord,
afw::image::Exposure< float > const &  exposure 
) const
virtual

Called to measure a single child source in an image.

Before this method is called, all neighbors will be replaced with noise, using the outputs of the deblender. Outputs should be saved in the given SourceRecord, which can also be used to obtain centroid (see SafeCentroidExtractor) and shape (see SafeShapeExtractor) information.

Implements lsst::meas::base::SingleFrameAlgorithm.

Definition at line 868 of file SdssShape.cc.

869  {
870  bool negative = false;
871 
872  try {
873  negative = measRecord.get(measRecord.getSchema().find<afw::table::Flag>("flags_negative").key);
874  } catch (pexExcept::Exception &e) {
875  }
876  SdssShapeResult result = computeAdaptiveMoments(
877  exposure.getMaskedImage(), _centroidExtractor(measRecord, _resultKey.getFlagHandler()), negative,
878  _ctrl);
879 
880  if (_ctrl.doMeasurePsf) {
881  // Compute moments of Psf model. In the interest of implementing this quickly, we're just
882  // calling Psf::computeShape(), which delegates to SdssShapeResult::computeAdaptiveMoments
883  // for all nontrivial Psf classes. But this could in theory save the results of a shape
884  // computed some other way as part of base_SdssShape, which might be confusing. We should
885  // fix this eventually either by making Psf shape measurement not part of base_SdssShape, or
886  // by making the measurements stored with shape.sdss always computed via the
887  // SdssShapeAlgorithm instead of delegating to the Psf class.
888  try {
890  if (!psf) {
891  result.flags[PSF_SHAPE_BAD.number] = true;
892  } else {
893  _resultKey.setPsfShape(measRecord, psf->computeShape(geom::Point2D(result.x, result.y)));
894  }
895  } catch (pex::exceptions::Exception &err) {
896  result.flags[PSF_SHAPE_BAD.number] = true;
897  }
898  }
899 
900  measRecord.set(_resultKey, result);
901 }
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 PSF_SHAPE_BAD
Definition: SdssShape.h:160
bool doMeasurePsf
"Whether to also compute the shape of the PSF model" ;
Definition: SdssShape.h:59
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.
Definition: SdssShape.cc:724
Provides consistent interface for LSST exceptions.
Definition: Exception.h:107
Key< int > psf
Definition: Exposure.cc:65

◆ measureForced()

virtual void lsst::meas::base::SimpleAlgorithm::measureForced ( afw::table::SourceRecord measRecord,
afw::image::Exposure< float > const &  exposure,
afw::table::SourceRecord const &  refRecord,
afw::geom::SkyWcs const &  refWcs 
) const
inlinevirtualinherited

Called to measure a single child source in an image.

Before this method is called, all neighbors will be replaced with noise, using the outputs of the deblender. Outputs should be saved in the given SourceRecord, which can also be used to obtain centroid (see SafeCentroidExtractor) and shape (see SafeShapeExtractor) information.

Implements lsst::meas::base::ForcedAlgorithm.

Reimplemented in lsst::meas::extensions::photometryKron::KronFluxAlgorithm.

Definition at line 172 of file Algorithm.h.

175  {
176  measure(measRecord, exposure);
177  }
virtual void measure(afw::table::SourceRecord &measRecord, afw::image::Exposure< float > const &exposure) const =0
Called to measure a single child source in an image.

◆ measureN()

void lsst::meas::base::SingleFrameAlgorithm::measureN ( afw::table::SourceCatalog const &  measCat,
afw::image::Exposure< float > const &  exposure 
) const
virtualinherited

Called to simultaneously measure all children in a deblend family, in a single image.

Outputs should be saved in the given SourceCatalog, which can also be used to obtain centroid (see SafeCentroidExtractor) and shape (see SafeShapeExtractor) information.

The default implementation simply throws an exception, indicating that simultaneous measurement is not supported.

Definition at line 31 of file Algorithm.cc.

32  {
33  throw LSST_EXCEPT(pex::exceptions::LogicError, "measureN not implemented for this algorithm");
34 }

◆ measureNForced()

virtual void lsst::meas::base::SimpleAlgorithm::measureNForced ( afw::table::SourceCatalog const &  measCat,
afw::image::Exposure< float > const &  exposure,
afw::table::SourceCatalog const &  refRecord,
afw::geom::SkyWcs const &  refWcs 
) const
inlinevirtualinherited

Called to simultaneously measure all children in a deblend family, in a single image.

Outputs should be saved in the given SourceCatalog, which can also be used to obtain centroid (see SafeCentroidExtractor) and shape (see SafeShapeExtractor) information.

The default implementation simply throws an exception, indicating that simultaneous measurement is not supported.

Reimplemented from lsst::meas::base::ForcedAlgorithm.

Definition at line 179 of file Algorithm.h.

182  {
183  measureN(measCat, exposure);
184  }
virtual void measureN(afw::table::SourceCatalog const &measCat, afw::image::Exposure< float > const &exposure) const
Called to simultaneously measure all children in a deblend family, in a single image.
Definition: Algorithm.cc:31

Member Data Documentation

◆ _logName

std::string lsst::meas::base::BaseAlgorithm::_logName
protectedinherited

Definition at line 69 of file Algorithm.h.

◆ FAILURE

FlagDefinition const lsst::meas::base::SdssShapeAlgorithm::FAILURE = flagDefinitions.addFailureFlag()
static

Definition at line 155 of file SdssShape.h.

◆ MAXITER

FlagDefinition const lsst::meas::base::SdssShapeAlgorithm::MAXITER
static
Initial value:
=
flagDefinitions.add("flag_maxIter", "Too many iterations in adaptive moments")

Definition at line 159 of file SdssShape.h.

◆ N_FLAGS

unsigned int const lsst::meas::base::SdssShapeAlgorithm::N_FLAGS = 6
static

Definition at line 154 of file SdssShape.h.

◆ PSF_SHAPE_BAD

FlagDefinition const lsst::meas::base::SdssShapeAlgorithm::PSF_SHAPE_BAD
static
Initial value:
=
flagDefinitions.add("flag_psf", "Failure in measuring PSF model shape")

Definition at line 160 of file SdssShape.h.

◆ SHIFT

FlagDefinition const lsst::meas::base::SdssShapeAlgorithm::SHIFT
static
Initial value:
=
flagDefinitions.add("flag_shift", "centroid shifted by more than the maximum allowed amount")

Definition at line 158 of file SdssShape.h.

◆ UNWEIGHTED

FlagDefinition const lsst::meas::base::SdssShapeAlgorithm::UNWEIGHTED
static
Initial value:
= flagDefinitions.add(
"flag_unweighted", "Weighted moments converged to an invalid value; using unweighted moments")

Definition at line 157 of file SdssShape.h.

◆ UNWEIGHTED_BAD

FlagDefinition const lsst::meas::base::SdssShapeAlgorithm::UNWEIGHTED_BAD
static
Initial value:
=
flagDefinitions.add("flag_unweightedBad", "Both weighted and unweighted moments were invalid")

Definition at line 156 of file SdssShape.h.


The documentation for this class was generated from the following files: