lsst.afw 23.0.0+60ce4897b0
ExposureFitsReader.cc
Go to the documentation of this file.
1/*
2 * Developed for the LSST Data Management System.
3 * This product includes software developed by the LSST Project
4 * (https://www.lsst.org).
5 * See the COPYRIGHT file at the top-level directory of this distribution
6 * for details of code ownership.
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22#include <map>
23#include <regex>
24#include <set>
25
26#include "lsst/log/Log.h"
27
36
37namespace lsst {
38namespace afw {
39namespace image {
40
41namespace {
42
43LOG_LOGGER _log = LOG_GET("afw.image.fits.ExposureFitsReader");
44
45template <typename T, std::size_t N>
46bool _contains(std::array<T, N> const& array, T const& value) {
47 for (T const& element : array) {
48 if (element == value) {
49 return true;
50 }
51 }
52 return false;
53}
54
55// Map from compatibility "afw name" to correct filter label
56std::map<std::string, FilterLabel> const _AFW_NAMES = {
59 std::make_pair("SOLID", FilterLabel::fromPhysical("solid plate 0.0 0.0")),
60};
61
67bool _isBand(std::string const& name) {
68 static std::set<std::string> const BANDS = {"u", "g", "r", "i", "z", "y", "SH", "PH", "VR", "white"};
69 // Standard band
70 if (BANDS.count(name) > 0) {
71 return true;
72 }
73 // Looks like a narrow-band band
74 if (std::regex_match(name, std::regex("N\\d+"))) {
75 return true;
76 }
77 // Looks like an intermediate-band band; exclude "I2"
78 if (std::regex_match(name, std::regex("I\\d{2,}"))) {
79 return true;
80 }
81 return false;
82}
83
84} // namespace
85
95 static Filter const DEFAULT;
96 // Avoid turning dummy filters into real FilterLabels.
97 if (name == DEFAULT.getName()) {
98 return nullptr;
99 }
100
101 // FilterLabel::from* returns a statically allocated object, so only way
102 // to get it into shared_ptr is to copy it.
103 if (_isBand(name)) {
104 return std::make_shared<FilterLabel>(FilterLabel::fromBand(name));
105 } else {
106 return std::make_shared<FilterLabel>(FilterLabel::fromPhysical(name));
107 }
108}
109
120// TODO: compatibility code to be removed in DM-27177
122 static Filter const DEFAULT;
123 // Avoid turning dummy filters into real FilterLabels.
124 // Default filter has id=UNKNOWN, but others do too.
125 if (filter.getId() == DEFAULT.getId() && filter.getName() == DEFAULT.getName()) {
126 return nullptr;
127 }
128
129 // Filter has no self-consistency guarantees whatsoever, and most methods
130 // are unsafe. Program extremely defensively.
131 if (filter.getId() == Filter::UNKNOWN) {
132 // Not a registered filter; guarantees on canonical name do not apply
133 return makeFilterLabelDirect(filter.getName());
134 }
135
136 // obs.base.FilterDefinition ensures the canonical name is the first defined
137 // of afwname, band name, physical filter name.
138 std::string canonical;
139 try {
140 canonical = filter.getCanonicalName();
141 } catch (pex::exceptions::NotFoundError const&) {
142 // Not a registered filter; guarantees on canonical name do not apply
143 return makeFilterLabelDirect(filter.getName());
144 }
145
146 if (_AFW_NAMES.count(canonical) > 0) {
147 return std::make_shared<FilterLabel>(_AFW_NAMES.at(canonical));
148 } else if (_isBand(canonical)) {
149 // physical filter is one of the aliases, but can't tell which one
150 // (FilterDefinition helpfully sorts them). Safer to leave it blank.
152 try {
153 aliases = filter.getAliases();
154 } catch (pex::exceptions::NotFoundError const&) {
155 // No aliases; leave the vector empty
156 }
157 if (aliases.size() == 1) {
158 return std::make_shared<FilterLabel>(FilterLabel::fromBandPhysical(canonical, aliases.front()));
159 } else {
160 return std::make_shared<FilterLabel>(FilterLabel::fromBand(canonical));
161 }
162 } else {
163 return std::make_shared<FilterLabel>(FilterLabel::fromPhysical(canonical));
164 }
165}
166
178 if (_AFW_NAMES.count(name) > 0) {
179 return std::make_shared<FilterLabel>(_AFW_NAMES.at(name));
180 }
181 // else name is either a band, a physical filter, or a deprecated alias
182
183 try {
184 // To ease the transition to FilterLabel, use Filter to get all the names
185 // TODO: after DM-27177, leave only the catch block
186 Filter filter(name, false);
188 // Make use of the extra information that `name` is a preferred name
189 // If name is not a band, it is likely the physical filter
190 if (converted && !converted->hasPhysicalLabel() && converted->hasBandLabel() &&
191 name != converted->getBandLabel()) {
192 return std::make_shared<FilterLabel>(
193 FilterLabel::fromBandPhysical(converted->getBandLabel(), name));
194 } else {
195 return converted;
196 }
197 } catch (pex::exceptions::NotFoundError const&) {
198 // Unknown filter, no extra info to be gained
200 }
201}
202
211 // Filters still have standard aliases, so can use almost any name to define them.
212 // Prefer afw_name or band because that's what most code assumes is Filter.getName().
213 for (auto const& keyValue : _AFW_NAMES) {
214 std::string const& afwName = keyValue.first;
215 FilterLabel const& afwFilter = keyValue.second;
216 if (label == afwFilter) {
217 return Filter(afwName);
218 }
219 }
220
221 if (label.hasBandLabel()) {
222 return Filter(label.getBandLabel(), true);
223 } else {
224 // FilterLabel guarantees at least one of band or physical is defined.
225 return Filter(label.getPhysicalLabel(), true);
226 }
227}
228
230public:
234 if (primaryMetadata->exists(versionName)) {
235 version = primaryMetadata->getAsInt(versionName);
236 primaryMetadata->remove(versionName);
237 } else {
238 version = 0; // unversioned files are implicitly version 0
239 }
242 str(boost::format("Cannot read Exposure FITS version > %i") %
244 }
245
246 // Try to read WCS from image metadata, and if found, strip the keywords used
247 try {
248 wcs = afw::geom::makeSkyWcs(*imageMetadata, true);
249 } catch (lsst::pex::exceptions::TypeError const&) {
250 LOGLS_DEBUG(_log, "No WCS found in FITS metadata");
251 }
252 if (wcs && any(xy0.ne(lsst::geom::Point2I(0, 0)))) {
253 wcs = wcs->copyAtShiftedPixelOrigin(lsst::geom::Extent2D(xy0));
254 }
255
256 // Strip LTV1, LTV2 from imageMetadata, because we don't use it internally
257 imageMetadata->remove("LTV1");
258 imageMetadata->remove("LTV2");
259
260 if (!imageMetadata->exists("INHERIT")) {
261 // New-style exposures put everything but the Wcs in the primary HDU, use
262 // INHERIT keyword in the others. For backwards compatibility, if we don't
263 // find the INHERIT keyword, we ignore the primary HDU metadata and expect
264 // everything to be in the image HDU metadata. Note that we can't merge them,
265 // because they're probably duplicates.
266 metadata = imageMetadata;
267 } else {
268 metadata = primaryMetadata;
269 }
270
271 // Earlier versions persisted Filter as header keyword, version 2 persists FilterLabel as a Storable
272 if (version < 2) {
273 std::string key = "FILTER";
274 if (metadata->exists(key)) {
275 // Original Filter code depended on Boost for string trimming.
276 // DIY to avoid making this module depend on Boost.
277 std::string name = metadata->getAsString(key);
278 size_t end = name.find_last_not_of(' ');
279 filterLabel = makeFilterLabel(name.substr(0, end + 1));
280 }
281 }
282
283 visitInfo = std::make_shared<VisitInfo>(*metadata);
285
286 // Version 0 persisted Calib FLUXMAG0 in the metadata, >=1 persisted PhotoCalib as a binary table.
287 if (version == 0) {
289 }
290
291 // Strip MJD-OBS and DATE-OBS from metadata; those may be read by
292 // either SkyWcs or VisitInfo or both, so neither can strip them.
293 metadata->remove("MJD-OBS");
294 metadata->remove("DATE-OBS");
295
296 // Strip DETSER, DETNAME; these are added when writing an Exposure
297 // with a Detector
298 metadata->remove("DETNAME");
299 metadata->remove("DETSER");
300 }
301
308};
309
311public:
313 PSF = 0,
322 };
323
325 auto popInt = [&metadata](std::string const& name) {
326 // The default of zero will cause archive.get to return a
327 // null/empty pointer, just as if a null/empty pointer was
328 // originally written to the archive.
329 int r = 0;
330 if (metadata.exists(name)) {
331 r = metadata.get<int>(name);
332 // We remove metadata entries to maintaing our practice
333 // of stripped metadata entries that have been used to
334 // construct more structured components.
335 metadata.remove(name);
336 }
337 return r;
338 };
339 _hdu = popInt("AR_HDU");
340 if (_hdu == 0) {
341 _state = ArchiveState::MISSING;
342 } else {
343 --_hdu; // Switch from FITS 1-indexed convention to LSST 0-indexed convention.
344 _state = ArchiveState::PRESENT;
345 }
346 // Read in traditional components using old-style IDs, for backwards compatibility
347 _ids[PSF] = popInt("PSF_ID");
348 _ids[WCS] = popInt("SKYWCS_ID");
349 _ids[COADD_INPUTS] = popInt("COADD_INPUTS_ID");
350 _ids[AP_CORR_MAP] = popInt("AP_CORR_MAP_ID");
351 _ids[VALID_POLYGON] = popInt("VALID_POLYGON_ID");
352 _ids[TRANSMISSION_CURVE] = popInt("TRANSMISSION_CURVE_ID");
353 _ids[DETECTOR] = popInt("DETECTOR_ID");
354 _ids[PHOTOCALIB] = popInt("PHOTOCALIB_ID");
355
356 // "Extra" components use a different keyword convention to avoid collisions with non-persistence IDs
358 for (std::string const& headerKey : metadata) {
359 static std::string const PREFIX = "ARCHIVE_ID_";
360 if (headerKey.substr(0, PREFIX.size()) == PREFIX) {
361 std::string componentName = headerKey.substr(PREFIX.size());
362 int archiveId = metadata.get<int>(headerKey);
363 _genericIds.emplace(componentName, archiveId);
364 if (!_contains(_ids, archiveId)) {
365 _extraIds.emplace(componentName);
366 }
367 toStrip.push_back(headerKey);
368 toStrip.push_back(componentName + "_ID"); // strip corresponding old-style ID, if it exists
369 }
370 }
371 for (std::string const& key : toStrip) {
372 metadata.remove(key);
373 }
374 }
375
385 template <typename T>
387 if (!_ensureLoaded(fitsFile)) {
388 return nullptr;
389 }
390 return _archive.get<T>(_ids[c]);
391 }
392
409 // This method takes a string instead of a strongly typed Key because
410 // readExtraComponents() gets its keys from the FITS metadata.
411 // Using a Key would make the calling code more complicated.
412 template <typename T>
414 if (!_ensureLoaded(fitsFile)) {
415 return nullptr;
416 }
417
418 if (_genericIds.count(c) > 0) {
419 int archiveId = _genericIds.at(c);
420 return _archive.get<T>(archiveId);
421 } else {
422 return nullptr;
423 }
424 }
425
436 afw::fits::Fits* fitsFile) {
438
439 if (!_ensureLoaded(fitsFile)) {
440 return result;
441 }
442
443 // Not safe to call getAll if a component cannot be unpersisted
444 // Instead, look for the archives registered in the metadata
445 for (std::string const& componentName : _extraIds) {
446 try {
447 result.emplace(componentName, readComponent<table::io::Persistable>(fitsFile, componentName));
448 } catch (pex::exceptions::NotFoundError const& err) {
449 LOGLS_WARN(_log,
450 "Could not read component " << componentName << "; skipping: " << err.what());
451 }
452 }
453 return result;
454 }
455
456private:
457 bool _ensureLoaded(afw::fits::Fits* fitsFile) {
458 if (_state == ArchiveState::MISSING) {
459 return false;
460 }
461 if (_state == ArchiveState::PRESENT) {
462 afw::fits::HduMoveGuard guard(*fitsFile, _hdu);
463 _archive = table::io::InputArchive::readFits(*fitsFile);
464 _state = ArchiveState::LOADED;
465 }
466 assert(_state == ArchiveState::LOADED); // constructor body should guarantee it's not UNKNOWN
467 return true;
468 }
469
470 enum class ArchiveState { UNKNOWN, MISSING, PRESENT, LOADED };
471
472 int _hdu = 0;
473 ArchiveState _state = ArchiveState::UNKNOWN;
474 table::io::InputArchive _archive;
476 std::map<std::string, int> _genericIds;
477 std::set<std::string> _extraIds; // _genericIds not included in _ids
478};
479
480ExposureFitsReader::ExposureFitsReader(std::string const& fileName) : _maskedImageReader(fileName) {}
481
482ExposureFitsReader::ExposureFitsReader(fits::MemFileManager& manager) : _maskedImageReader(manager) {}
483
484ExposureFitsReader::ExposureFitsReader(fits::Fits* fitsFile) : _maskedImageReader(fitsFile) {}
485
486ExposureFitsReader::~ExposureFitsReader() noexcept = default;
487
488lsst::geom::Box2I ExposureFitsReader::readBBox(ImageOrigin origin) {
489 return _maskedImageReader.readBBox(origin);
490}
491
493 return _maskedImageReader.readXY0(bbox, origin);
494}
495
497 _ensureReaders();
498 return _metadataReader->version;
499}
500
501std::string ExposureFitsReader::readImageDType() const { return _maskedImageReader.readImageDType(); }
502
503std::string ExposureFitsReader::readMaskDType() const { return _maskedImageReader.readMaskDType(); }
504
506
508 _ensureReaders();
509 return _metadataReader->metadata;
510}
511
513 _ensureReaders();
514 auto r = _archiveReader->readComponent<afw::geom::SkyWcs>(_getFitsFile(), ArchiveReader::WCS);
515 if (!r) {
516 r = _metadataReader->wcs;
517 }
518 return r;
519}
520
523 if (label) {
524 return makeFilter(*label);
525 } else {
526 // Old exposures always had a Filter, even if only the default
527 return Filter();
528 }
529}
530
532 _ensureReaders();
533 if (_metadataReader->version < 2) {
534 return _metadataReader->filterLabel;
535 } else {
536 return _archiveReader->readComponent<FilterLabel>(_getFitsFile(), ExposureInfo::KEY_FILTER.getId());
537 }
538}
539
541 _ensureReaders();
542 if (_metadataReader->version == 0) {
543 return _metadataReader->photoCalib;
544 } else {
545 return _archiveReader->readComponent<image::PhotoCalib>(_getFitsFile(), ArchiveReader::PHOTOCALIB);
546 }
547}
548
550 _ensureReaders();
551 return _archiveReader->readComponent<detection::Psf>(_getFitsFile(), ArchiveReader::PSF);
552}
553
555 _ensureReaders();
556 return _archiveReader->readComponent<afw::geom::polygon::Polygon>(_getFitsFile(),
558}
559
561 _ensureReaders();
562 return _archiveReader->readComponent<ApCorrMap>(_getFitsFile(), ArchiveReader::AP_CORR_MAP);
563}
564
566 _ensureReaders();
567 return _archiveReader->readComponent<CoaddInputs>(_getFitsFile(), ArchiveReader::COADD_INPUTS);
568}
569
571 _ensureReaders();
572 return _metadataReader->visitInfo;
573}
574
576 _ensureReaders();
577 return _archiveReader->readComponent<TransmissionCurve>(_getFitsFile(),
579}
580
582 _ensureReaders();
583 return _archiveReader->readComponent<cameraGeom::Detector>(_getFitsFile(), ArchiveReader::DETECTOR);
584}
585
587 _ensureReaders();
588 return _archiveReader->readComponent<typehandling::Storable>(_getFitsFile(), componentName);
589}
590
592 _ensureReaders();
593 return _archiveReader->readExtraComponents(_getFitsFile());
594}
595
597 auto result = std::make_shared<ExposureInfo>();
598 result->setMetadata(readMetadata());
599 result->setPhotoCalib(readPhotoCalib());
600 result->setVisitInfo(readVisitInfo());
601 // When reading an ExposureInfo (as opposed to reading individual
602 // components), we warn and try to proceed when a component is present
603 // but can't be read due its serialization factory not being set up
604 // (that's what throws the NotFoundErrors caught below).
605 try {
606 result->setPsf(readPsf());
607 } catch (pex::exceptions::NotFoundError& err) {
608 LOGLS_WARN(_log, "Could not read PSF; setting to null: " << err.what());
609 }
610 try {
611 result->setCoaddInputs(readCoaddInputs());
612 } catch (pex::exceptions::NotFoundError& err) {
613 LOGLS_WARN(_log, "Could not read CoaddInputs; setting to null: " << err.what());
614 }
615 try {
616 result->setApCorrMap(readApCorrMap());
617 } catch (pex::exceptions::NotFoundError& err) {
618 LOGLS_WARN(_log, "Could not read ApCorrMap; setting to null: " << err.what());
619 }
620 try {
621 result->setValidPolygon(readValidPolygon());
622 } catch (pex::exceptions::NotFoundError& err) {
623 LOGLS_WARN(_log, "Could not read ValidPolygon; setting to null: " << err.what());
624 }
625 try {
626 result->setTransmissionCurve(readTransmissionCurve());
627 } catch (pex::exceptions::NotFoundError& err) {
628 LOGLS_WARN(_log, "Could not read TransmissionCurve; setting to null: " << err.what());
629 }
630 try {
631 result->setDetector(readDetector());
632 } catch (pex::exceptions::NotFoundError& err) {
633 LOGLS_WARN(_log, "Could not read Detector; setting to null: " << err.what());
634 }
635 // In the case of WCS, we fall back to the metadata WCS if the one from
636 // the archive can't be read.
637 _ensureReaders();
638 result->setWcs(_metadataReader->wcs);
639 try {
640 auto wcs = _archiveReader->readComponent<afw::geom::SkyWcs>(_getFitsFile(), ArchiveReader::WCS);
641 if (!wcs) {
642 LOGLS_DEBUG(_log, "No WCS found in binary table");
643 } else {
644 result->setWcs(wcs);
645 }
646 } catch (pex::exceptions::NotFoundError& err) {
647 auto msg = str(boost::format("Could not read WCS extension; setting to null: %s") % err.what());
648 if (result->hasWcs()) {
649 msg += " ; using WCS from FITS header";
650 }
651 LOGLS_WARN(_log, msg);
652 }
653 for (const auto& keyValue : readExtraComponents()) {
655 std::string key = keyValue.first;
656 StorablePtr object = std::dynamic_pointer_cast<StorablePtr::element_type>(keyValue.second);
657
658 if (object.use_count() > 0) { // Failed cast guarantees empty pointer, but not a null one
659 result->setComponent(typehandling::makeKey<StorablePtr>(key), object);
660 } else {
661 LOGLS_WARN(_log, "Data corruption: generic component " << key << " is not a Storable; skipping.");
662 }
663 }
664 // Convert old-style Filter to new-style FilterLabel
665 // In newer versions this is handled by readExtraComponents()
666 if (_metadataReader->version < 2 && !result->hasFilterLabel()) {
667 result->setFilterLabel(readFilterLabel());
668 }
669 return result;
670} // namespace image
671
672template <typename ImagePixelT>
674 bool allowUnsafe) {
675 return _maskedImageReader.readImage<ImagePixelT>(bbox, origin, allowUnsafe);
676}
677
678template <typename ImagePixelT>
679ndarray::Array<ImagePixelT, 2, 2> ExposureFitsReader::readImageArray(lsst::geom::Box2I const& bbox,
680 ImageOrigin origin, bool allowUnsafe) {
681 return _maskedImageReader.readImageArray<ImagePixelT>(bbox, origin, allowUnsafe);
682}
683
684template <typename MaskPixelT>
686 bool conformMasks, bool allowUnsafe) {
687 return _maskedImageReader.readMask<MaskPixelT>(bbox, origin, conformMasks, allowUnsafe);
688}
689
690template <typename MaskPixelT>
691ndarray::Array<MaskPixelT, 2, 2> ExposureFitsReader::readMaskArray(lsst::geom::Box2I const& bbox,
692 ImageOrigin origin, bool allowUnsafe) {
693 return _maskedImageReader.readMaskArray<MaskPixelT>(bbox, origin, allowUnsafe);
694}
695
696template <typename VariancePixelT>
698 bool allowUnsafe) {
699 return _maskedImageReader.readVariance<VariancePixelT>(bbox, origin, allowUnsafe);
700}
701
702template <typename VariancePixelT>
703ndarray::Array<VariancePixelT, 2, 2> ExposureFitsReader::readVarianceArray(lsst::geom::Box2I const& bbox,
704 ImageOrigin origin,
705 bool allowUnsafe) {
706 return _maskedImageReader.readVarianceArray<VariancePixelT>(bbox, origin, allowUnsafe);
707}
708
709template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
711 lsst::geom::Box2I const& bbox, ImageOrigin origin, bool conformMasks, bool allowUnsafe) {
712 return _maskedImageReader.read<ImagePixelT, MaskPixelT, VariancePixelT>(bbox, origin, conformMasks,
713 /* needAllHdus= */ false,
714 allowUnsafe);
715}
716
717template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
719 ImageOrigin origin,
720 bool conformMasks,
721 bool allowUnsafe) {
722 auto mi =
723 readMaskedImage<ImagePixelT, MaskPixelT, VariancePixelT>(bbox, origin, conformMasks, allowUnsafe);
725}
726
727void ExposureFitsReader::_ensureReaders() {
728 if (!_metadataReader) {
729 auto metadataReader = std::make_unique<MetadataReader>(_maskedImageReader.readPrimaryMetadata(),
730 _maskedImageReader.readImageMetadata(),
731 _maskedImageReader.readXY0());
732 _archiveReader = std::make_unique<ArchiveReader>(*metadataReader->metadata);
733 _metadataReader = std::move(metadataReader); // deferred for exception safety
734 }
735 assert(_archiveReader); // should always be initialized with _metadataReader.
736}
737
738#define INSTANTIATE(ImagePixelT) \
739 template Exposure<ImagePixelT, MaskPixel, VariancePixel> ExposureFitsReader::read( \
740 lsst::geom::Box2I const&, ImageOrigin, bool, bool); \
741 template Image<ImagePixelT> ExposureFitsReader::readImage(lsst::geom::Box2I const&, ImageOrigin, bool); \
742 template ndarray::Array<ImagePixelT, 2, 2> ExposureFitsReader::readImageArray(lsst::geom::Box2I const&, \
743 ImageOrigin, bool); \
744 template MaskedImage<ImagePixelT, MaskPixel, VariancePixel> ExposureFitsReader::readMaskedImage( \
745 lsst::geom::Box2I const&, ImageOrigin, bool, bool)
746
748INSTANTIATE(int);
749INSTANTIATE(float);
750INSTANTIATE(double);
752
753template Mask<MaskPixel> ExposureFitsReader::readMask(lsst::geom::Box2I const&, ImageOrigin, bool, bool);
754template ndarray::Array<MaskPixel, 2, 2> ExposureFitsReader::readMaskArray(lsst::geom::Box2I const&,
755 ImageOrigin, bool);
756
757template Image<VariancePixel> ExposureFitsReader::readVariance(lsst::geom::Box2I const&, ImageOrigin, bool);
758template ndarray::Array<VariancePixel, 2, 2> ExposureFitsReader::readVarianceArray(lsst::geom::Box2I const&,
759 ImageOrigin, bool);
760
761} // namespace image
762} // namespace afw
763} // namespace lsst
table::Key< std::string > name
Definition: Amplifier.cc:116
AmpInfoBoxKey bbox
Definition: Amplifier.cc:117
double element[2]
Definition: BaseTable.cc:90
int end
#define LSST_EXCEPT(type,...)
#define INSTANTIATE(ImagePixelT)
#define LOGLS_WARN(logger, message)
#define LOG_GET(logger)
#define LOGLS_DEBUG(logger, message)
Implementation of the Photometric Calibration class.
table::Key< table::Array< std::uint8_t > > wcs
Definition: SkyWcs.cc:66
T at(T... args)
A representation of a detector in a mosaic camera.
Definition: Detector.h:185
A polymorphic base class for representing an image's Point Spread Function.
Definition: Psf.h:76
A simple struct that combines the two arguments that must be passed to most cfitsio routines and cont...
Definition: fits.h:297
RAII scoped guard for moving the HDU in a Fits object.
Definition: fits.h:724
Lifetime-management for memory that goes into FITS memory files.
Definition: fits.h:121
A 2-dimensional celestial WCS that transform pixels to ICRS RA/Dec, using the LSST standard for pixel...
Definition: SkyWcs.h:117
Cartesian polygons.
Definition: Polygon.h:59
A thin wrapper around std::map to allow aperture corrections to be attached to Exposures.
Definition: ApCorrMap.h:45
A simple Persistable struct containing ExposureCatalogs that record the inputs to a coadd.
Definition: CoaddInputs.h:49
std::shared_ptr< T > readComponent(afw::fits::Fits *fitsFile, std::string c)
Read an arbitrary component, if available.
std::map< std::string, std::shared_ptr< table::io::Persistable > > readExtraComponents(afw::fits::Fits *fitsFile)
Read the components that are stored using arbitrary-component support.
std::shared_ptr< T > readComponent(afw::fits::Fits *fitsFile, Component c)
Read a known component, if available.
std::shared_ptr< daf::base::PropertyList > metadata
MetadataReader(std::shared_ptr< daf::base::PropertyList > primaryMetadata, std::shared_ptr< daf::base::PropertyList > imageMetadata, lsst::geom::Point2I const &xy0)
A FITS reader class for Exposures and their components.
std::shared_ptr< TransmissionCurve > readTransmissionCurve()
Read the Exposure's transmission curve.
std::string readMaskDType() const
Read a string describing the pixel type of the on-disk image plane.
Exposure< ImagePixelT, MaskPixelT, VariancePixelT > read(lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT, bool conformMasks=false, bool allowUnsafe=false)
Read the full Exposure.
std::shared_ptr< typehandling::Storable > readComponent(std::string const &componentName)
Read an arbitrary non-standard component by name.
std::shared_ptr< afw::geom::SkyWcs > readWcs()
Read the Exposure's world coordinate system.
std::shared_ptr< FilterLabel > readFilterLabel()
Read the Exposure's filter information.
MaskedImage< ImagePixelT, MaskPixelT, VariancePixelT > readMaskedImage(lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT, bool conformMasks=false, bool allowUnsafe=false)
Read the MaskedImage.
std::map< std::string, std::shared_ptr< table::io::Persistable > > readExtraComponents()
Read the Exposure's non-standard components.
lsst::geom::Point2I readXY0(lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT)
Read the image origin from the on-disk image or a subimage thereof.
ndarray::Array< VariancePixelT, 2, 2 > readVarianceArray(lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT, bool allowUnsafe=false)
Read the variance plane.
int readSerializationVersion()
Read the serialization version number from the header.
ExposureFitsReader(std::string const &fileName)
Construct a FITS reader object.
std::shared_ptr< detection::Psf > readPsf()
Read the Exposure's point-spread function.
std::shared_ptr< afw::geom::polygon::Polygon > readValidPolygon()
Read the polygon describing the region of validity for the Exposure.
Filter readFilter()
Read the Exposure's filter.
Image< ImagePixelT > readImage(lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT, bool allowUnsafe=false)
Read the image plane.
std::string readVarianceDType() const
Read a string describing the pixel type of the on-disk image plane.
ndarray::Array< ImagePixelT, 2, 2 > readImageArray(lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT, bool allowUnsafe=false)
Read the image plane.
lsst::geom::Box2I readBBox(ImageOrigin origin=PARENT)
Read the bounding box of the on-disk image.
Image< VariancePixelT > readVariance(lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT, bool allowUnsafe=false)
Read the variance plane.
std::shared_ptr< daf::base::PropertyList > readMetadata()
Read the flexible metadata associated with the Exposure.
std::shared_ptr< PhotoCalib > readPhotoCalib()
Read the Exposure's photometric calibration.
std::shared_ptr< ApCorrMap > readApCorrMap()
Read the Exposure's aperture correction map.
ndarray::Array< MaskPixelT, 2, 2 > readMaskArray(lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT, bool allowUnsafe=false)
Read the mask plane.
std::string readImageDType() const
Read a string describing the pixel type of the on-disk image plane.
std::shared_ptr< CoaddInputs > readCoaddInputs()
Read the Exposure's coadd input catalogs.
std::shared_ptr< cameraGeom::Detector > readDetector()
Read the Exposure's detector.
std::shared_ptr< ExposureInfo > readExposureInfo()
Read the ExposureInfo containing all non-image components.
std::shared_ptr< VisitInfo > readVisitInfo()
Read the Exposure's visit metadata.
Mask< MaskPixelT > readMask(lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT, bool conformMasks=false, bool allowUnsafe=false)
Read the mask plane.
A class to contain the data, WCS, and other information needed to describe an image of the sky.
Definition: Exposure.h:72
static int getFitsSerializationVersion()
Get the version of FITS serialization that this ExposureInfo understands.
static std::string const & getFitsSerializationVersionName()
Get the version of FITS serialization version info name.
static typehandling::Key< std::string, std::shared_ptr< FilterLabel const > > const KEY_FILTER
Standard key for looking up filter information.
Definition: ExposureInfo.h:107
A group of labels for a filter in an exposure or coadd.
Definition: FilterLabel.h:58
std::string getBandLabel() const
Return the band label.
Definition: FilterLabel.cc:87
bool hasBandLabel() const noexcept
Return whether the filter label names a band.
Definition: FilterLabel.cc:85
static FilterLabel fromBand(std::string const &band)
Construct a FilterLabel from specific inputs.
Definition: FilterLabel.cc:72
std::string getPhysicalLabel() const
Return the physical filter label.
Definition: FilterLabel.cc:98
static FilterLabel fromBandPhysical(std::string const &band, std::string const &physical)
Construct a FilterLabel from specific inputs.
Definition: FilterLabel.cc:68
static FilterLabel fromPhysical(std::string const &physical)
Construct a FilterLabel from specific inputs.
Definition: FilterLabel.cc:74
A class to represent a 2-dimensional array of pixels.
Definition: Image.h:51
Represent a 2-dimensional array of bitmask pixels.
Definition: Mask.h:77
std::string readMaskDType() const
Read a string describing the pixel type of the on-disk image plane.
std::shared_ptr< daf::base::PropertyList > readImageMetadata()
Read the FITS header of one of the HDUs.
std::shared_ptr< daf::base::PropertyList > readPrimaryMetadata()
Read the FITS header of one of the HDUs.
std::string readVarianceDType() const
Read a string describing the pixel type of the on-disk image plane.
ndarray::Array< MaskPixelT, 2, 2 > readMaskArray(lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT, bool allowUnsafe=false)
Read the mask plane.
std::string readImageDType() const
Read a string describing the pixel type of the on-disk image plane.
ndarray::Array< ImagePixelT, 2, 2 > readImageArray(lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT, bool allowUnsafe=false)
Read the image plane.
ndarray::Array< VariancePixelT, 2, 2 > readVarianceArray(lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT, bool allowUnsafe=false)
Read the variance plane.
Mask< MaskPixelT > readMask(lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT, bool conformMasks=false, bool allowUnsafe=false)
Read the mask plane.
MaskedImage< ImagePixelT, MaskPixelT, VariancePixelT > read(lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT, bool conformMasks=false, bool needAllHdus=false, bool allowUnsafe=false)
Read the full MaskedImage.
Image< ImagePixelT > readImage(lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT, bool allowUnsafe=false)
Read the image plane.
Image< VariancePixelT > readVariance(lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT, bool allowUnsafe=false)
Read the variance plane.
lsst::geom::Point2I readXY0(lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT)
Read the image origin from the on-disk image or a subimage thereof.
A class to manipulate images, masks, and variance as a single object.
Definition: MaskedImage.h:73
The photometric calibration of an exposure.
Definition: PhotoCalib.h:114
A spatially-varying transmission curve as a function of wavelength.
static InputArchive readFits(fits::Fits &fitsfile)
Read an object from an already open FITS object.
std::shared_ptr< Persistable > get(int id) const
Load the Persistable with the given ID and return it.
Interface supporting iteration over heterogenous containers.
Definition: Storable.h:58
T get(std::string const &name) const
virtual void remove(std::string const &name)
bool exists(std::string const &name) const
CoordinateExpr< N > ne(Point< T, N > const &other) const noexcept
virtual char const * what(void) const noexcept
T count(T... args)
T emplace(T... args)
T front(T... args)
T make_pair(T... args)
T move(T... args)
std::shared_ptr< SkyWcs > makeSkyWcs(daf::base::PropertySet &metadata, bool strip=false)
Construct a SkyWcs from FITS keywords.
Definition: SkyWcs.cc:521
int stripVisitInfoKeywords(daf::base::PropertySet &metadata)
Remove VisitInfo-related keywords from the metadata.
Definition: VisitInfo.cc:339
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
Filter makeFilter(FilterLabel const &label)
Convert a FilterLabel back to an old-style Filter.
std::shared_ptr< PhotoCalib > makePhotoCalibFromMetadata(daf::base::PropertySet &metadata, bool strip=false)
Construct a PhotoCalib from FITS FLUXMAG0/FLUXMAG0ERR keywords.
Definition: PhotoCalib.cc:595
std::shared_ptr< FilterLabel > makeFilterLabel(Filter const &filter)
Convert an old-style Filter to a FilterLabel.
std::shared_ptr< FilterLabel > makeFilterLabelDirect(std::string const &name)
Convert an old-style filter name to a FilterLabel without external information.
bool any(CoordinateExpr< N > const &expr) noexcept
A base class for image defects.
T push_back(T... args)
T regex_match(T... args)
T size(T... args)
T substr(T... args)