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::extensions::simpleShape::SimpleShape Class Reference

#include <simpleShape.h>

Inheritance diagram for lsst::meas::extensions::simpleShape::SimpleShape:
lsst::meas::base::SimpleAlgorithm lsst::meas::base::SingleFrameAlgorithm lsst::meas::base::ForcedAlgorithm lsst::meas::base::BaseAlgorithm lsst::meas::base::BaseAlgorithm

Public Types

typedef SimpleShapeControl Control
 

Public Member Functions

 SimpleShape (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, lsst::meas::base::MeasurementError *error=NULL) const
 Handle an exception thrown by the current algorithm by setting flags in the given record. More...
 
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 base::FlagDefinitionList const & getFlagDefinitions ()
 
template<typename T >
static SimpleShapeResult computeMoments (afw::geom::ellipses::Ellipse const &weight, afw::image::MaskedImage< T > const &image, double nSigmaRegion=3.0)
 Compute the Gaussian-weighted moments of an image. More...
 
static Eigen::Matrix< double, 5, 6 > convertRawMoments (Eigen::Matrix< double, 6, 1 > const &q, afw::geom::ellipses::Quadrupole &quadrupole, geom::Point2D &center)
 Convert linear raw moments into an ellipse and centroid, and return the derivative of the conversion. More...
 
static Eigen::Matrix< double, 5, 5 > correctWeightedMoments (afw::geom::ellipses::Quadrupole const &weight, afw::geom::ellipses::Quadrupole &ellipse, geom::Point2D &center)
 Correct moments measured with a Gaussian weight function by assuming the data was also an elliptical Gaussian, and return the derivative of the correction. More...
 

Static Public Attributes

static unsigned int const N_FLAGS = 1
 
static base::FlagDefinition const FAILURE = flagDefinitions.addFailureFlag()
 

Protected Attributes

std::string _logName
 

Detailed Description

Definition at line 95 of file simpleShape.h.

Member Typedef Documentation

◆ Control

Definition at line 103 of file simpleShape.h.

Constructor & Destructor Documentation

◆ SimpleShape()

lsst::meas::extensions::simpleShape::SimpleShape::SimpleShape ( Control const &  ctrl,
std::string const &  name,
afw::table::Schema schema 
)

Definition at line 378 of file simpleShape.cc.

383  : _ctrl(ctrl),
385  _centroidExtractor(schema, name)
386  {}
table::Schema schema
Definition: python.h:134
static SimpleShapeResultKey addFields(afw::table::Schema &schema, std::string const &name)
Definition: simpleShape.cc:319

Member Function Documentation

◆ computeMoments()

template<typename T >
template SimpleShapeResult lsst::meas::extensions::simpleShape::SimpleShape::computeMoments ( afw::geom::ellipses::Ellipse const &  weight,
afw::image::MaskedImage< T > const &  image,
double  nSigmaRegion = 3.0 
)
static

Compute the Gaussian-weighted moments of an image.

Parameters
[in]weightAn ellipse object of Gaussian weights to apply to the measurement.
[in]imageA Masked image instance with int float or double pixels.
[in]nSigmaRegionMaximum radius for pixels to include, in units of sigma

Definition at line 161 of file simpleShape.cc.

165  {
166  // Define the pixel region we want to accumulate over.
167  afw::geom::ellipses::Ellipse regionEllipse(weight);
168  regionEllipse.getCore().scale(nSigmaRegion);
169  afw::geom::ellipses::PixelRegion region(regionEllipse);
170  SimpleShapeResult result;
171 
172  // We work in the coordinate system where the origin is the center of the weight function.
173  // This will make things easier in the various transformations we'll have to apply to the raw
174  // moments.
175 
176  // All the pixel operations take place in the next two lines, when we use the above machinery
177  // to accumulate the raw moments in a single pass.
178  RawMomentAccumulator functor(weight);
179  iterateRegion(functor, image, region);
180 
181  // Then we convert the raw moments to an ellipse and centroid, and propagate the uncertainty
182  // through the covariance matrix.
183  MatrixMQ dm_dq = convertRawMoments(functor.moments, result.ellipse, result.center);
184  MatrixM mCov = dm_dq * functor.covariance.selfadjointView<Eigen::Lower>() * dm_dq.adjoint();
185 
186  // Next, we correct the measured moments for the fact that what we just measured was the
187  // moments of the product of the weight function and the data, and we want just the moments
188  // of the data.
189  MatrixM dc_dm = correctWeightedMoments(
190  weight.getCore().as<afw::geom::ellipses::Quadrupole>(),
191  result.ellipse,
192  result.center
193  );
194  result.covariance = dc_dm * mCov.selfadjointView<Eigen::Lower>() * dc_dm.adjoint();
195 
196  // Finally, we switch back to the native image coordinate system.
197  result.center += geom::Extent2D(weight.getCenter());
198 
199  return result;
200 }
py::object result
Definition: _schema.cc:429
static Eigen::Matrix< double, 5, 5 > correctWeightedMoments(afw::geom::ellipses::Quadrupole const &weight, afw::geom::ellipses::Quadrupole &ellipse, geom::Point2D &center)
Correct moments measured with a Gaussian weight function by assuming the data was also an elliptical ...
Definition: simpleShape.cc:234
static Eigen::Matrix< double, 5, 6 > convertRawMoments(Eigen::Matrix< double, 6, 1 > const &q, afw::geom::ellipses::Quadrupole &quadrupole, geom::Point2D &center)
Convert linear raw moments into an ellipse and centroid, and return the derivative of the conversion.
Definition: simpleShape.cc:203
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
Extent< double, 2 > Extent2D
Definition: Extent.h:400
afw::table::Key< double > weight

◆ convertRawMoments()

MatrixMQ lsst::meas::extensions::simpleShape::SimpleShape::convertRawMoments ( Eigen::Matrix< double, 6, 1 > const &  q,
afw::geom::ellipses::Quadrupole quadrupole,
geom::Point2D center 
)
static

Convert linear raw moments into an ellipse and centroid, and return the derivative of the conversion.

Note
This function is mainly intended for internal use, and is only exposed publically so it can be unit-tested in Python.

For weight function \(w\) and data \(p\), the "raw" moments \(Q\) are defined as:

\begin{eqnarray*} Q_0 &=& \sum_n w(x_n, y_n) p_n \\ Q_{xx} &=& \sum_n w(x_n, y_n) x_n^2 p_n \\ Q_{yy} &=& \sum_n w(x_n, y_n) y_n^2 p_n \\ Q_{xy} &=& \sum_n w(x_n, y_n) x_n y_n p_n \\ Q_x &=& \sum_n w(x_n, y_n) x_n p_n \\ Q_y &=& \sum_n w(x_n, y_n) y_n p_n \end{eqnarray*}

whereas the converted ellipse and centroid moments are:

\begin{eqnarray*} M_{xx} &=& Q_{xx} / Q_0 - Q_x^2 \\ M_{xx} &=& Q_{yy} / Q_0 - Q_y^2 \\ M_{xx} &=& Q_{xy} / Q_0 - Q_x Q_y \\ M_x &=& Q_x / Q_0 \\ M_y &=& Q_y / Q_0 \end{eqnarray*}

Note the slightly unusual ordering; this is for consistency with afw::geom::ellipses::Ellipse.

Definition at line 203 of file simpleShape.cc.

207  {
208  VectorM m = q.segment<N_M>(1) / q[Q0];
209  MatrixMQ dm_dq = MatrixMQ::Zero();;
210  dm_dq.block<N_M,N_M>(0,1) = MatrixM::Identity() / q[Q0];
211  dm_dq.col(Q0) = -m / q[Q0];
212  // now we account for the centroid^2 terms in the second moments
213  m[MXX] -= m[MX] * m[MX];
214  m[MYY] -= m[MY] * m[MY];
215  m[MXY] -= m[MX] * m[MY];
216  dm_dq(MXX, QX) = -2.0 * m[MX] / q[Q0];
217  dm_dq(MYY, QY) = -2.0 * m[MY] / q[Q0];
218  dm_dq(MXY, QX) = m[MY] / q[Q0];
219  dm_dq(MXY, QY) = m[MX] / q[Q0];
220  double tmp = 2.0 / (q[Q0] * q[Q0] * q[Q0]); // == d(-Q_0^{-2})/d(Q_0)
221  dm_dq(MXX, Q0) += tmp * q[QX] * q[QX];
222  dm_dq(MYY, Q0) += tmp * q[QY] * q[QY];
223  dm_dq(MXY, Q0) += tmp * q[QX] * q[QY];
224 
225  ellipse.setIxx(m[MXX]);
226  ellipse.setIyy(m[MYY]);
227  ellipse.setIxy(m[MXY]);
228  center.setX(m[MX]);
229  center.setY(m[MY]);
230 
231  return dm_dq;
232 }
int m
Definition: SpanSet.cc:48

◆ correctWeightedMoments()

MatrixM lsst::meas::extensions::simpleShape::SimpleShape::correctWeightedMoments ( afw::geom::ellipses::Quadrupole const &  weight,
afw::geom::ellipses::Quadrupole ellipse,
geom::Point2D center 
)
static

Correct moments measured with a Gaussian weight function by assuming the data was also an elliptical Gaussian, and return the derivative of the correction.

Note
This function is mainly intended for internal use, and is only exposed publically so it can be unit-tested in Python.

If we naively measure Gaussian-weighted moments, we'll measure the moments of the product of the weight function and the data. What we want is the moments of the data, as if we had measured them with no weight function (but without sacrificing the S/N benefit that comes from using a weight function). To do that, we assume the data is also an elliptical Gaussian, and "divide" the weight function from the measured moments to compute it.

If \(W\) and \(M\) are the quadruple matrices of the weight function and measurement, and \(\eta\) is the measured centroid (we work in a coordinate system where the weight function is centered at the origin), then the corrected quadrupole matrix \(C\) and centroid are \(\nu\) are:

\begin{eqnarray*} C &=& \left(M^{-1} - W^{-1}\right)^{-1} \\ \nu &=& C M^{-1} \eta \end{eqnarray*}

Definition at line 234 of file simpleShape.cc.

238  {
239  Eigen::Matrix2d wMat = weight.getMatrix();
240  Eigen::Vector2d mVec = center.asEigen();
241  Eigen::Matrix2d mMat = ellipse.getMatrix();
242  if (wMat.determinant() <= 0.0) {
243  throw LSST_EXCEPT(
244  base::MeasurementError,
245  "Weight moments matrix is singular",
247  );
248  }
249  if (mMat.determinant() <= 0.0) {
250  throw LSST_EXCEPT(
251  base::MeasurementError,
252  "Measured moments matrix is singular",
254  );
255  }
256  Eigen::Matrix2d mInv = mMat.inverse();
257  Eigen::Matrix2d cInv = mInv - wMat.inverse();
258  if (cInv.determinant() <= 0.0) {
259  throw LSST_EXCEPT(
260  base::MeasurementError,
261  "Corrected moments matrix is singular",
263  );
264  }
265  Eigen::Matrix2d cMat = cInv.inverse();
266  ellipse.setIxx(cMat(0, 0));
267  ellipse.setIyy(cMat(1, 1));
268  ellipse.setIxy(cMat(0, 1));
269  Eigen::Matrix2d cMat_mInv = cMat * mInv;
270  Eigen::Vector2d mInv_mVec = mInv * mVec;
271  Eigen::Vector2d cVec = cMat_mInv * mVec;
272  center.setX(cVec[0]);
273  center.setY(cVec[1]);
274  Eigen::Matrix2d dcMat_dmxx = cMat_mInv.col(0) * cMat_mInv.col(0).adjoint();
275  Eigen::Matrix2d dcMat_dmyy = cMat_mInv.col(1) * cMat_mInv.col(1).adjoint();
276  Eigen::Matrix2d dcMat_dmxy = cMat_mInv.col(0) * cMat_mInv.col(1).adjoint()
277  + cMat_mInv.col(1) * cMat_mInv.col(0).adjoint();
278  Eigen::Vector2d dcVec_dmxx = cMat_mInv.col(0) * mInv_mVec[0];
279  Eigen::Vector2d dcVec_dmyy = cMat_mInv.col(1) * mInv_mVec[1];
280  Eigen::Vector2d dcVec_dmxy = cMat_mInv.col(0) * mInv_mVec[1] + cMat_mInv.col(1) * mInv_mVec[0];
281  Eigen::Matrix2d const & dcVec_dmVec = cMat_mInv;
282 
283  // calculations done - now we just need to put these elements back into a 5x5 matrix to return
284 
285  MatrixM dc_dm = MatrixM::Zero();
286  dc_dm(MXX, MXX) = dcMat_dmxx(0, 0);
287  dc_dm(MYY, MXX) = dcMat_dmxx(1, 1);
288  dc_dm(MXY, MXX) = dcMat_dmxx(0, 1);
289  dc_dm(MXX, MYY) = dcMat_dmyy(0, 0);
290  dc_dm(MYY, MYY) = dcMat_dmyy(1, 1);
291  dc_dm(MXY, MYY) = dcMat_dmyy(0, 1);
292  dc_dm(MXX, MXY) = dcMat_dmxy(0, 0);
293  dc_dm(MYY, MXY) = dcMat_dmxy(1, 1);
294  dc_dm(MXY, MXY) = dcMat_dmxy(0, 1);
295  dc_dm(MX, MXX) = dcVec_dmxx[0];
296  dc_dm(MY, MXX) = dcVec_dmxx[1];
297  dc_dm(MX, MYY) = dcVec_dmyy[0];
298  dc_dm(MY, MYY) = dcVec_dmyy[1];
299  dc_dm(MX, MXY) = dcVec_dmxy[0];
300  dc_dm(MY, MXY) = dcVec_dmxy[1];
301  dc_dm(MX, MX) = dcVec_dmVec(0, 0);
302  dc_dm(MX, MY) = dcVec_dmVec(0, 1);
303  dc_dm(MY, MX) = dcVec_dmVec(1, 0);
304  dc_dm(MY, MY) = dcVec_dmVec(1, 1);
305 
306  return dc_dm;
307 }
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
EigenVector const & asEigen() const noexcept(IS_ELEMENT_NOTHROW_COPYABLE)
Return a fixed-size Eigen representation of the coordinate object.
static base::FlagDefinition const FAILURE
Definition: simpleShape.h:101

◆ fail()

void lsst::meas::extensions::simpleShape::SimpleShape::fail ( afw::table::SourceRecord measRecord,
lsst::meas::base::MeasurementError error = NULL 
) 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 399 of file simpleShape.cc.

402  {
403  _resultKey.getFlagHandler().handleFailure(measRecord, error);
404 }
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
lsst::meas::base::FlagHandler const & getFlagHandler() const
Definition: simpleShape.h:85

◆ getFlagDefinitions()

base::FlagDefinitionList const & lsst::meas::extensions::simpleShape::SimpleShape::getFlagDefinitions ( )
static

Definition at line 37 of file simpleShape.cc.

37  {
38  return flagDefinitions;
39 }

◆ 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::extensions::simpleShape::SimpleShape::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 388 of file simpleShape.cc.

391  {
392  geom::Point2D center = _centroidExtractor(source, _resultKey.getFlagHandler());
393  afw::geom::ellipses::Ellipse weight(afw::geom::ellipses::Axes(_ctrl.sigma), center);
394  // set flags so an exception throw produces a flagged source
395  SimpleShapeResult result = computeMoments(weight, exposure.getMaskedImage(), _ctrl.nSigmaRegion);
396  source.set(_resultKey, result);
397 }
double sigma
"Sigma of circular Gaussian used as weight function, in pixels" ;
Definition: simpleShape.h:46
double nSigmaRegion
"Maximum radius for pixels to include, in units of sigma" ;
Definition: simpleShape.h:47
static SimpleShapeResult computeMoments(afw::geom::ellipses::Ellipse const &weight, afw::image::MaskedImage< T > const &image, double nSigmaRegion=3.0)
Compute the Gaussian-weighted moments of an image.
Definition: simpleShape.cc:161
const char * source()
Source function that allows astChannel to source from a Stream.
Definition: Stream.h:224

◆ 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

base::FlagDefinition const lsst::meas::extensions::simpleShape::SimpleShape::FAILURE = flagDefinitions.addFailureFlag()
static

Definition at line 101 of file simpleShape.h.

◆ N_FLAGS

unsigned int const lsst::meas::extensions::simpleShape::SimpleShape::N_FLAGS = 1
static

Definition at line 100 of file simpleShape.h.


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