Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DM-35007: Make schema documentation of HSM moments useful #38

Merged
merged 6 commits into from
Oct 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,10 @@ meas_extensions_shapeHSM
``meas_extensions_shapeHSM`` is a package in the `LSST Science Pipelines <https://pipelines.lsst.io>`_.

The ``lsst.meas.extensions.shapeHSM`` Python module provides algorithms for HSM shape measurement.
The algorithm was initially described in https://ui.adsabs.harvard.edu/abs/2003MNRAS.343..459H/abstract,
and was modified later in https://ui.adsabs.harvard.edu/abs/2005MNRAS.361.1287M/abstract.
HSM is named after the primary authors: i) Hirata, Christopher, ii) Seljak, Uros and iii) Mandelbaum, Rachel.
Their implementation of this algorithm lives within `GalSim <https://github.com/GalSim-developers/GalSim>`_,
and this package interacts directly with the C++ layer of GalSim to make the measurements.

Documentation is available at https://pipelines.lsst.io/modules/lsst.meas.extensions.shapeHSM/index.html.
30 changes: 21 additions & 9 deletions include/lsst/meas/extensions/shapeHSM/HsmMomentsControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,9 @@ class HsmMomentsAlgorithm : public base::SimpleAlgorithm {
HsmMomentsAlgorithm(std::string const & name, afw::table::Schema & schema, char const* doc) :
_doc(doc),
_centroidResultKey(
base::CentroidResultKey::addFields(schema, name, "HSM Centroid", base::NO_UNCERTAINTY)),
base::CentroidResultKey::addFields(schema, name, doc, base::NO_UNCERTAINTY)),
_momentsKey(
base::ShapeResultKey::addFields(schema, name, "HSM moments", base::NO_UNCERTAINTY)
base::ShapeResultKey::addFields(schema, name, doc, base::NO_UNCERTAINTY)
),
_centroidExtractor(schema, name)
{
Expand Down Expand Up @@ -183,8 +183,9 @@ class HsmSourceMomentsAlgorithm : public HsmMomentsAlgorithm {
typedef HsmSourceMomentsControl Control;

/// @brief Initialize with standard field names and customized documentation.
HsmSourceMomentsAlgorithm(Control const & ctrl, std::string const & name, afw::table::Schema & schema) :
HsmMomentsAlgorithm(name, schema, "Source adaptive moments algorithm from HSM"), _ctrl(ctrl)
HsmSourceMomentsAlgorithm(Control const & ctrl, std::string const & name, afw::table::Schema & schema,
char const* doc = "Adaptive moments of the source via the HSM shape algorithm") : ///< Docstring is exposed for HsmSourceMomentsRoundAlgorithm
HsmMomentsAlgorithm(name, schema, doc), _ctrl(ctrl)
{
if (ctrl.addFlux) {
_fluxKey = schema.addField<float>(name + "_Flux", "HSM flux");
Expand All @@ -201,6 +202,15 @@ class HsmSourceMomentsAlgorithm : public HsmMomentsAlgorithm {
};


class HsmSourceMomentsRoundAlgorithm : public HsmSourceMomentsAlgorithm {
public:
/// @brief Initialize with standard field names and customized documentation.
HsmSourceMomentsRoundAlgorithm(Control const & ctrl, std::string const & name, afw::table::Schema & schema,
char const* doc = "Adaptive moments of the source via the HSM shape algorithm, with circular weight function") :
HsmSourceMomentsAlgorithm(ctrl, name, schema, doc) {}
};


/// Class to measure HSM adaptive moments of PSF
class HsmPsfMomentsAlgorithm : public HsmMomentsAlgorithm {
public:
Expand All @@ -209,9 +219,10 @@ class HsmPsfMomentsAlgorithm : public HsmMomentsAlgorithm {
typedef std::shared_ptr<const HsmPsfMomentsControl> Control;

/// @brief Initialize with standard field names and customized documentation.
HsmPsfMomentsAlgorithm(Control const & ctrl, std::string const & name, afw::table::Schema & schema) :
HsmMomentsAlgorithm(name, schema, "Psf adaptive moments algorithm from HSM"), _ctrl(ctrl) {}

HsmPsfMomentsAlgorithm(Control const & ctrl, std::string const & name, afw::table::Schema & schema,
char const* doc = "Adaptive moments of the PSF via the HSM shape algorithm" ///< Docstring is exposed for debiased PSF algorithm
) :
HsmMomentsAlgorithm(name, schema, doc), _ctrl(ctrl) {}
void measure(
afw::table::SourceRecord & measRecord,
afw::image::Exposure<float> const & exposure
Expand Down Expand Up @@ -246,8 +257,9 @@ class HsmPsfMomentsDebiasedAlgorithm : public HsmPsfMomentsAlgorithm {

typedef std::shared_ptr<const HsmPsfMomentsDebiasedControl> Control;

HsmPsfMomentsDebiasedAlgorithm(Control const & ctrl, std::string const & name, afw::table::Schema & schema) :
HsmPsfMomentsAlgorithm(ctrl, name, schema) {
HsmPsfMomentsDebiasedAlgorithm(Control const & ctrl, std::string const & name, afw::table::Schema & schema,
char const* doc = "Debiased adaptive moments of the PSF via the HSM shape algorithm") :
HsmPsfMomentsAlgorithm(ctrl, name, schema, doc) {
auto thisCtrl = std::static_pointer_cast<Control::element_type>(_ctrl);
if ((thisCtrl->noiseSource != "meta") && (thisCtrl->noiseSource != "variance")) {
throw LSST_EXCEPT(base::MeasurementError, "invalid noiseSorce", FAILURE.number);
Expand Down
2 changes: 1 addition & 1 deletion python/lsst/meas/extensions/shapeHSM/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
Control=HsmShapeRegaussControl, executionOrder=BasePlugin.SHAPE_ORDER)
wrapSimpleAlgorithm(HsmSourceMomentsAlgorithm, name="ext_shapeHSM_HsmSourceMoments",
Control=HsmSourceMomentsControl, executionOrder=BasePlugin.SHAPE_ORDER)
wrapSimpleAlgorithm(HsmSourceMomentsAlgorithm, name="ext_shapeHSM_HsmSourceMomentsRound",
wrapSimpleAlgorithm(HsmSourceMomentsRoundAlgorithm, name="ext_shapeHSM_HsmSourceMomentsRound",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, that's definitely a bug! Good catch.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: It wasn't a bug, since whether round moments are calculated or not, was entiredly determined with the Control class. HsmSourceMomentsRoundAlgorithm is defined in this ticket, and is subclassed solely to have a different docstring.

Control=HsmSourceMomentsRoundControl, executionOrder=BasePlugin.SHAPE_ORDER)
wrapSimpleAlgorithm(HsmPsfMomentsAlgorithm, name="ext_shapeHSM_HsmPsfMoments",
Control=HsmPsfMomentsControl, executionOrder=BasePlugin.SHAPE_ORDER)
Expand Down
6 changes: 6 additions & 0 deletions python/lsst/meas/extensions/shapeHSM/hsmMomentsControl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ PYBIND11_MODULE(hsmMomentsControl, mod) {
py::class_<HsmSourceMomentsAlgorithm, std::shared_ptr<HsmSourceMomentsAlgorithm>, HsmMomentsAlgorithm>
clsHsmSourceMomentsAlgorithm(mod, "HsmSourceMomentsAlgorithm");
py::class_<HsmSourceMomentsControl> clsHsmSourceMomentsControl(mod, "HsmSourceMomentsControl");

py::class_<HsmSourceMomentsRoundAlgorithm, std::shared_ptr<HsmSourceMomentsRoundAlgorithm>, HsmSourceMomentsAlgorithm, HsmMomentsAlgorithm>
clsHsmSourceMomentsRoundAlgorithm(mod, "HsmSourceMomentsRoundAlgorithm");
py::class_<HsmSourceMomentsRoundControl, HsmSourceMomentsControl>
clsHsmSourceMomentsRoundControl(mod, "HsmSourceMomentsRoundControl");

Expand All @@ -63,6 +66,9 @@ PYBIND11_MODULE(hsmMomentsControl, mod) {
py::init<HsmSourceMomentsAlgorithm::Control const &, std::string const &, afw::table::Schema &>(),
"ctrl"_a, "name"_a, "schema"_a);
clsHsmSourceMomentsControl.def(py::init<>());
clsHsmSourceMomentsRoundAlgorithm.def(
py::init<HsmSourceMomentsRoundAlgorithm::Control const &, std::string const &, afw::table::Schema &>(),
"ctrl"_a, "name"_a, "schema"_a);
clsHsmSourceMomentsRoundControl.def(py::init<>());

clsHsmPsfMomentsAlgorithm.def(
Expand Down
10 changes: 10 additions & 0 deletions tests/test_hsm.py
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,11 @@ def testHsmPsfMoments(
self.assertAlmostEqual(xy, expected.getIxy(), SHAPE_DECIMALS)
self.assertAlmostEqual(yy, expected.getIyy(), SHAPE_DECIMALS)

# Test schema documentation
for fieldName in cat.schema.extract("*HsmPsfMoments_[xy]*"):
self.assertEqual(cat.schema[fieldName].asField().getDoc(),
"Adaptive moments of the PSF via the HSM shape algorithm")

@lsst.utils.tests.methodParameters(
# Make Cartesian product of settings to feed to methodParameters
**dict(list(zip(
Expand Down Expand Up @@ -598,6 +603,11 @@ def testHsmPsfMomentsDebiased(
self.assertAlmostEqual(xy, xy2, 5)
self.assertAlmostEqual(yy, yy2, 5)

# Test schema documentation
for fieldName in cat.schema.extract("*HsmPsfMomentsDebiased_[xy]*"):
self.assertEqual(cat.schema[fieldName].asField().getDoc(),
"Debiased adaptive moments of the PSF via the HSM shape algorithm")

testHsmPsfMomentsDebiasedEdgeArgs = dict(
width=(2.0, 3.0, 4.0),
useSourceCentroidOffset=(True, False),
Expand Down