Skip to content

Commit

Permalink
Merge pull request #725 from lsst/tickets/DM-42467
Browse files Browse the repository at this point in the history
DM-42467: add properties for ExposureCatalog objects
  • Loading branch information
parejkoj committed Jan 17, 2024
2 parents 8c70369 + 76007f5 commit f11f554
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 24 deletions.
29 changes: 15 additions & 14 deletions python/lsst/afw/table/_exposure.cc
Original file line number Diff line number Diff line change
Expand Up @@ -68,46 +68,47 @@ PyExposureRecord declareExposureRecord(WrapperCollection &wrappers) {
return wrappers.wrapType(PyExposureRecord(wrappers.module, "ExposureRecord"), [](auto &mod, auto &cls) {
cls.def("getId", &ExposureRecord::getId);
cls.def("setId", &ExposureRecord::setId, "id"_a);
cls.def_property("id", &ExposureRecord::getId, &ExposureRecord::setId);
cls.def("getBBox", &ExposureRecord::getBBox);
cls.def("setBBox", &ExposureRecord::setBBox, "bbox"_a);
// No property for bbox, as it returns by value.
cls.def("getTable", &ExposureRecord::getTable);
// table has no setter
cls.def_property_readonly("table", &ExposureRecord::getTable);
cls.def("contains",
(bool (ExposureRecord::*)(lsst::geom::SpherePoint const &, bool) const) &
(bool(ExposureRecord::*)(lsst::geom::SpherePoint const &, bool) const) &
ExposureRecord::contains,
"coord"_a, "includeValidPolygon"_a = false);
cls.def("contains",
(bool (ExposureRecord::*)(lsst::geom::Point2D const &, geom::SkyWcs const &, bool) const) &
(bool(ExposureRecord::*)(lsst::geom::Point2D const &, geom::SkyWcs const &, bool) const) &
ExposureRecord::contains,
"point"_a, "wcs"_a, "includeValidPolygon"_a = false);
cls.def("getWcs", &ExposureRecord::getWcs);
cls.def("setWcs", &ExposureRecord::setWcs, "wcs"_a);
cls.def_property("wcs", &ExposureRecord::getWcs, &ExposureRecord::setWcs);
cls.def("getPsf", &ExposureRecord::getPsf);
cls.def("setPsf", &ExposureRecord::setPsf, "psf"_a);
cls.def_property("psf", &ExposureRecord::getPsf, &ExposureRecord::setPsf);

cls.def("getPhotoCalib", &ExposureRecord::getPhotoCalib);
cls.def("setPhotoCalib", &ExposureRecord::setPhotoCalib, "photoCalib"_a);
cls.def_property("photoCalib", &ExposureRecord::getPhotoCalib, &ExposureRecord::setPhotoCalib);
cls.def("getApCorrMap", &ExposureRecord::getApCorrMap);
cls.def("setApCorrMap", &ExposureRecord::setApCorrMap, "apCorrMap"_a);
cls.def_property("apCorrMap", &ExposureRecord::getApCorrMap, &ExposureRecord::setApCorrMap);
cls.def("getValidPolygon", &ExposureRecord::getValidPolygon);

// Workaround for DM-10289.
cls.def("setValidPolygon",
[](ExposureRecord &self, py::object polygon) {
if (polygon.is(py::none())) {
self.setValidPolygon(nullptr);
} else {
self.setValidPolygon(py::cast<std::shared_ptr<afw::geom::polygon::Polygon>>(polygon));
}
},
"polygon"_a);

cls.def("setValidPolygon", &ExposureRecord::setValidPolygon);
cls.def_property("validPolygon", &ExposureRecord::getValidPolygon, &ExposureRecord::setValidPolygon);
cls.def("getVisitInfo", &ExposureRecord::getVisitInfo);
cls.def("setVisitInfo", &ExposureRecord::setVisitInfo, "visitInfo"_a);
cls.def_property("visitInfo", &ExposureRecord::getVisitInfo, &ExposureRecord::setVisitInfo);
cls.def("getTransmissionCurve", &ExposureRecord::getTransmissionCurve);
cls.def("setTransmissionCurve", &ExposureRecord::setTransmissionCurve, "transmissionCurve"_a);
cls.def_property("transmissionCurve", &ExposureRecord::getTransmissionCurve,
&ExposureRecord::setTransmissionCurve);
cls.def("getDetector", &ExposureRecord::getDetector);
cls.def("setDetector", &ExposureRecord::setDetector, "detector"_a);
cls.def_property("detector", &ExposureRecord::getDetector, &ExposureRecord::setDetector);
});
}

Expand Down
62 changes: 52 additions & 10 deletions tests/test_exposureTable.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,6 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

"""
Tests for lsst.afw.table.ExposureTable
Run with:
python test_exposureTable.py
or
pytest test_exposureTable.py
"""

import os.path
import unittest

Expand Down Expand Up @@ -121,6 +112,8 @@ def setUp(self):
self.wcs.getPixelOrigin() + lsst.geom.Extent2D(3.0, 6.0)
)
)
self.apCorrMap = lsst.afw.image.ApCorrMap()
self.transmissionCurve = lsst.afw.image.TransmissionCurve.makeIdentity()
# these numbers are what were persisted as `Calib` objects in the files.
self.photoCalib = lsst.afw.image.makePhotoCalibFromCalibZeroPoint(56.0, 2.2)
self.visitInfo = self.createVisitInfo()
Expand All @@ -144,6 +137,8 @@ def setUp(self):
record1.setBBox(self.bbox1)
record1.setValidPolygon(self.makePolygon())
record1.setDetector(self.detector)
record1.setApCorrMap(self.apCorrMap)
record1.setTransmissionCurve(self.transmissionCurve)

def tearDown(self):
del self.cat
Expand All @@ -168,10 +163,57 @@ def testAccessors(self):
self.assertIsNone(record1.getPhotoCalib())
self.assertEqual(record0.getVisitInfo(), self.visitInfo)
self.assertIsNone(record1.getVisitInfo())
self.assertEqual(record0.getValidPolygon(), None)
self.assertIsNone(record0.getValidPolygon())
self.assertEqual(record1.getValidPolygon(), self.makePolygon())
self.assertIsNone(record0.getDetector())
self.assertDetectorsEqual(record1.getDetector(), self.detector)
self.assertEqual(record1.getApCorrMap(), self.apCorrMap)
self.assertEqual(record1.getTransmissionCurve(), self.transmissionCurve)

def testProperties(self):
"""Test that we can get/set with the properties; some of them are
readonly, so check that those raise if set.
"""
# getters
record = self.cat[1]
self.assertEqual(record.id, 2)
self.assertEqual(record.wcs, self.wcs)
self.assertIsNone(record.psf)
self.assertIsNone(record.photoCalib)
self.assertIsNone(record.visitInfo)
self.assertEqual(record.validPolygon, self.makePolygon())
self.assertDetectorsEqual(record.detector, self.detector)
self.assertEqual(record.apCorrMap, self.apCorrMap)
self.assertEqual(record.transmissionCurve, self.transmissionCurve)
self.assertEqual(record.table, record.getTable())

# no property for bbox: it is returned by value, but is mutable.
with self.assertRaises(AttributeError):
record.bbox

# table has no setter
with self.assertRaises(AttributeError):
record.table = None

# read/write properties
record.id = 10
self.assertEqual(record.id, 10)
record.wcs = None
self.assertIsNone(record.wcs)
record.psf = self.psf
self.assertEqual(record.psf, self.psf)
record.photoCalib = self.photoCalib
self.assertEqual(record.photoCalib, self.photoCalib)
record.visitInfo = self.visitInfo
self.assertEqual(record.visitInfo, self.visitInfo)
record.validPolygon = None
self.assertIsNone(record.validPolygon)
record.detector = None
self.assertIsNone(record.detector)
record.apCorrMap = None
self.assertIsNone(record.apCorrMap)
record.transmissionCurve = None
self.assertIsNone(record.transmissionCurve)

def testPersistence(self):
with lsst.utils.tests.getTempFilePath(".fits") as tmpFile:
Expand Down

0 comments on commit f11f554

Please sign in to comment.