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-28368: Fix id check so that all components can use readComponent. #558

Merged
merged 3 commits into from
Jan 19, 2021
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 include/lsst/afw/image/TransmissionCurve.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ namespace image {
* at each position it is evaluated at). Other classes and functions using
* TransmissionCurves should of course document the flux units and/or
* normalization expected/provided.
*
* @note TransmissionCurve is an interface to various C++-only implementation
* classes. Because these classes are not mapped to Python, some references to
* a TransmissionCurve object may appear in Python as a table::io::Persistable
* or typehandling::Storable instead. The best way to avoid this at present is
* to call functions that, in C++, explicitly return a TransmissionCurve.
*/
class TransmissionCurve : public table::io::PersistableFacade<TransmissionCurve>,
public typehandling::Storable,
Expand Down
6 changes: 5 additions & 1 deletion src/image/ExposureFitsReader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,10 @@ class ExposureFitsReader::ArchiveReader {
*
* @throws pex::exceptions::NotFoundError Thrown if the component is
* registered in the file metadata but could not be found.
*
* @note When accessing from python, components with derived subclasses, such
* as ``TransmissionCurve``, are not properly type converted and thus
* the specialized reader must be used instead of ``readComponent``.
*/
// This method takes a string instead of a strongly typed Key because
// readExtraComponents() gets its keys from the FITS metadata.
Expand All @@ -411,7 +415,7 @@ class ExposureFitsReader::ArchiveReader {
return nullptr;
}

if (_extraIds.count(c) > 0) {
if (_genericIds.count(c) > 0) {
int archiveId = _genericIds.at(c);
return _archive.get<T>(archiveId);
} else {
Expand Down
19 changes: 18 additions & 1 deletion tests/test_readers.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from lsst.afw.image import (Image, Mask, Exposure, LOCAL, PARENT, MaskPixel, VariancePixel,
ImageFitsReader, MaskFitsReader, MaskedImageFitsReader, ExposureFitsReader,
Filter, FilterLabel, PhotoCalib, ApCorrMap, VisitInfo, TransmissionCurve,
CoaddInputs)
CoaddInputs, ExposureInfo)
from lsst.afw.image.utils import defineFilter
from lsst.afw.detection import GaussianPsf
from lsst.afw.cameraGeom.testUtils import DetectorWrapper
Expand Down Expand Up @@ -182,18 +182,35 @@ def checkExposureFitsReader(self, exposureIn, fileName, dtypesOut):
self.assertEqual(exposureIn.getMetadata().toDict(), reader.readMetadata().toDict())
self.assertWcsAlmostEqualOverBBox(exposureIn.getWcs(), reader.readWcs(), self.bbox,
maxDiffPix=0, maxDiffSky=0*degrees)
self.assertWcsAlmostEqualOverBBox(exposureIn.getWcs(),
reader.readComponent(ExposureInfo.KEY_WCS),
self.bbox,
maxDiffPix=0, maxDiffSky=0*degrees)
self.assertEqual(exposureIn.getFilter(), reader.readFilter())
self.assertEqual(exposureIn.getFilterLabel(), reader.readFilterLabel())
self.assertEqual(exposureIn.getFilterLabel(),
reader.readComponent(ExposureInfo.KEY_FILTER))
self.assertEqual(exposureIn.getPhotoCalib(), reader.readPhotoCalib())
self.assertEqual(exposureIn.getPhotoCalib(),
reader.readComponent(ExposureInfo.KEY_PHOTO_CALIB))
self.assertImagesEqual(exposureIn.getPsf().computeImage(), reader.readPsf().computeImage())
self.assertImagesEqual(exposureIn.getPsf().computeImage(),
reader.readComponent('PSF').computeImage())
self.assertEqual(exposureIn.getInfo().getValidPolygon(), reader.readValidPolygon())
self.assertEqual(exposureIn.getInfo().getValidPolygon(),
reader.readComponent(ExposureInfo.KEY_VALID_POLYGON))
self.assertCountEqual(exposureIn.getInfo().getApCorrMap(), reader.readApCorrMap())
self.assertCountEqual(exposureIn.getInfo().getApCorrMap(),
reader.readComponent(ExposureInfo.KEY_AP_CORR_MAP))
self.assertEqual(exposureIn.getInfo().getVisitInfo().getExposureTime(),
reader.readVisitInfo().getExposureTime())
point = Point2D(2.3, 3.1)
wavelengths = np.linspace(4000, 5000, 5)
self.assertFloatsEqual(exposureIn.getInfo().getTransmissionCurve().sampleAt(point, wavelengths),
reader.readTransmissionCurve().sampleAt(point, wavelengths))
# Note: readComponent(ExposureInfo.KEY_TRANSMISSION_CURVE) returns a generic Storable
# rather than a TransmissionCurve object.

# Because we persisted the same instances, we should get back the same
# instances for *archive* components, and hence equality comparisons
# should work even if it just amounts to C++ pointer equality.
Expand Down