37int const EXPOSURE_TABLE_CURRENT_VERSION = 5;
38std::string const EXPOSURE_TABLE_VERSION_KEY =
"EXPTABLE_VER";
46std::string const PHOTOCALIB_FIELD_NAME =
"photoCalib";
47std::string const VISIT_INFO_FIELD_NAME =
"visitInfo";
48std::string const AP_CORR_MAP_FIELD_NAME =
"apCorrMap";
49std::string const VALID_POLYGON_FIELD_NAME =
"validPolygon";
50std::string const TRANSMISSION_CURVE_FIELD_NAME =
"transmissionCurve";
53int getTableVersion(daf::base::PropertySet &metadata) {
54 return metadata.exists(EXPOSURE_TABLE_VERSION_KEY) ? metadata.get<
int>(EXPOSURE_TABLE_VERSION_KEY) : 1;
62struct PersistenceHelper {
75 SchemaMapper makeWriteMapper(Schema
const &inputSchema)
const {
81 result.editOutputSchema().setAliasMap(inputSchema.getAliasMap());
86 SchemaMapper makeReadMapper(Schema
const &inputSchema)
const {
88 result.editOutputSchema().setAliasMap(inputSchema.getAliasMap());
93 template <
typename OutputArchiveIsh>
94 void writeRecord(ExposureRecord
const &input, BaseRecord &output, SchemaMapper
const &
mapper,
95 OutputArchiveIsh &archive,
bool permissive)
const {
96 output.assign(input,
mapper);
97 output.set(psf, archive.put(input.getPsf(), permissive));
98 output.set(wcs, archive.put(input.getWcs(), permissive));
99 output.set(photoCalib, archive.put(input.getPhotoCalib(), permissive));
100 output.set(apCorrMap, archive.put(input.getApCorrMap(), permissive));
101 output.set(validPolygon, archive.put(input.getValidPolygon(), permissive));
102 output.set(visitInfo, archive.put(input.getVisitInfo(), permissive));
103 output.set(transmissionCurve, archive.put(input.getTransmissionCurve(), permissive));
104 output.set(detector, archive.put(input.getDetector(), permissive));
108 void readRecord(BaseRecord
const &input, ExposureRecord &output, SchemaMapper
const &
mapper,
109 io::InputArchive
const &archive)
const {
110 output.assign(input,
mapper);
112 output.setPsf(archive.get<detection::Psf>(input.get(psf)));
115 output.setWcs(archive.get<geom::SkyWcs>(input.get(wcs)));
120 if (photoCalib.isValid()) {
127 output.setValidPolygon(archive.get<geom::polygon::Polygon>(input.get(validPolygon)));
135 if (detector.isValid()) {
136 output.setDetector(archive.get<cameraGeom::Detector>(input.get(detector)));
141 PersistenceHelper(
const PersistenceHelper &) =
delete;
142 PersistenceHelper &operator=(
const PersistenceHelper &) =
delete;
145 PersistenceHelper(PersistenceHelper &&) =
delete;
146 PersistenceHelper &operator=(PersistenceHelper &&) =
delete;
151 wcs(
schema.addField<
int>(WCS_FIELD_NAME,
"archive ID for Wcs object")),
152 psf(
schema.addField<
int>(PSF_FIELD_NAME,
"archive ID for Psf object")),
153 photoCalib(
schema.addField<
int>(PHOTOCALIB_FIELD_NAME,
"archive ID for PhotoCalib object")),
154 apCorrMap(
schema.addField<
int>(AP_CORR_MAP_FIELD_NAME,
"archive ID for ApCorrMap object")),
156 visitInfo(
schema.addField<
int>(VISIT_INFO_FIELD_NAME,
"archive ID for VisitInfo object")),
158 "archive ID for TransmissionCurve object")),
159 detector(
schema.addField<
int>(DETECTOR_FIELD_NAME,
"archive ID for Detector object")) {}
162 void addIfPresent(Schema
const &oldSchema, Key<int> &key,
std::string const &name) {
164 auto item = oldSchema.find<
int>(
name);
165 key =
schema.addField(item.field);
166 }
catch (pex::exceptions::NotFoundError &) {
171 PersistenceHelper(Schema
const &oldSchema) {
172 addIfPresent(oldSchema, wcs, WCS_FIELD_NAME);
173 addIfPresent(oldSchema, psf, PSF_FIELD_NAME);
174 addIfPresent(oldSchema, calib, CALIB_FIELD_NAME);
175 addIfPresent(oldSchema, photoCalib, PHOTOCALIB_FIELD_NAME);
176 addIfPresent(oldSchema, apCorrMap, AP_CORR_MAP_FIELD_NAME);
177 addIfPresent(oldSchema, validPolygon, VALID_POLYGON_FIELD_NAME);
178 addIfPresent(oldSchema, visitInfo, VISIT_INFO_FIELD_NAME);
179 addIfPresent(oldSchema, transmissionCurve, TRANSMISSION_CURVE_FIELD_NAME);
180 addIfPresent(oldSchema, detector, DETECTOR_FIELD_NAME);
181 assert(oldSchema.contains(schema));
197class ExposureFitsWriter :
public io::FitsWriter {
203 _archive.reset(
new io::OutputArchive());
210 void _writeRecord(BaseRecord
const &r)
override;
212 void _finish()
override {
213 if (_doWriteArchive)
_archive->writeFits(*_fits);
227 "Cannot use a ExposureFitsWriter on a non-Exposure table.");
232 outTable->setMetadata(inTable->getMetadata());
233 io::FitsWriter::_writeTable(outTable, nRows);
234 _fits->writeKey(
"AFW_TYPE",
"EXPOSURE",
"Tells lsst::afw to load this as an Exposure table.");
235 _fits->writeKey(EXPOSURE_TABLE_VERSION_KEY, EXPOSURE_TABLE_CURRENT_VERSION,
"Exposure table version");
236 _record = outTable->makeRecord();
239void ExposureFitsWriter::_writeRecord(BaseRecord
const &r) {
240 ExposureRecord
const &record =
static_cast<ExposureRecord
const &
>(
r);
242 io::FitsWriter::_writeRecord(*
_record);
254template <
typename T,
void (ExposureRecord::*Setter)(std::shared_ptr<T const>)>
260 if (
mapper.hasArchive()) {
273 fits.readTableScalar<
int>(
row, _column,
id);
285class ExposureFitsReader :
public io::FitsReader {
287 ExposureFitsReader() :
afw::table::io::FitsReader(
"EXPOSURE") {}
291 bool stripMetadata)
const override {
297 auto tableVersion = getTableVersion(*metadata);
298 PersistableObjectColumnReader<detection::Psf, &ExposureRecord::setPsf>::setup(
"psf",
mapper);
299 PersistableObjectColumnReader<geom::SkyWcs, &ExposureRecord::setWcs>::setup(
"wcs",
mapper);
300 PersistableObjectColumnReader<image::ApCorrMap, &ExposureRecord::setApCorrMap>::setup(
"apCorrMap",
302 PersistableObjectColumnReader<geom::polygon::Polygon, &ExposureRecord::setValidPolygon>::setup(
304 if (tableVersion > 1) {
305 PersistableObjectColumnReader<image::VisitInfo, &ExposureRecord::setVisitInfo>::setup(
"visitInfo",
308 if (tableVersion > 2) {
310 &ExposureRecord::setTransmissionCurve>::setup(
"transmissionCurve",
313 if (tableVersion > 3) {
314 PersistableObjectColumnReader<cameraGeom::Detector, &ExposureRecord::setDetector>::setup(
318 if (tableVersion <= 4) {
319 PersistableObjectColumnReader<image::PhotoCalib, &ExposureRecord::setPhotoCalib>::setup(
"calib",
322 PersistableObjectColumnReader<image::PhotoCalib, &ExposureRecord::setPhotoCalib>::setup(
328 table->setMetadata(metadata);
332 bool usesArchive(
int ioFlags)
const override {
return true; }
335static ExposureFitsReader
const exposureFitsReader;
352 "ExposureRecord does not have a Wcs; cannot call contains()");
363 return (
lsst::geom::Box2D(getBBox()).contains(point) && getValidPolygon()->contains(point));
384 _photoCalib = s._photoCalib;
385 _apCorrMap = s._apCorrMap;
386 _validPolygon = s._validPolygon;
387 _visitInfo = s._visitInfo;
388 _transmissionCurve = s._transmissionCurve;
389 _detector = s._detector;
395 if (!checkSchema(
schema)) {
398 "Schema for Exposure must contain at least the keys defined by makeMinimalSchema().");
401 table->getSchema().getAliasMap()->setTable(table);
411ExposureTable::MinimalSchema::MinimalSchema() {
416ExposureTable::MinimalSchema &ExposureTable::getMinimalSchema() {
417 static MinimalSchema it;
428 return std::make_shared<ExposureFitsWriter>(
fitsfile, archive, flags);
433 table->getSchema().getAliasMap()->setTable(table);
445template <
typename RecordT>
447 PersistenceHelper
helper{};
450 outputCat.
reserve(this->size());
457template <
typename RecordT>
462 PersistenceHelper
helper{catalog.getSchema()};
465 result.reserve(catalog.size());
472template <
typename RecordT>
484template <
typename RecordT>
486 geom::SkyWcs
const &wcs,
table::Key< std::string > name
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Implementation of the Photometric Calibration class.
A simple struct that combines the two arguments that must be passed to most cfitsio routines and cont...
A thin wrapper around std::map to allow aperture corrections to be attached to Exposures.
The photometric calibration of an exposure.
A spatially-varying transmission curve as a function of wavelength.
Information about a single exposure of an imaging camera.
Tag types used to declare specialized field types.
Base class for all records.
Base class for all tables.
Schema getSchema() const
Return the table's schema.
static BoxKey addFields(Schema &schema, std::string const &name, std::string const &doc, std::string const &unit)
Add _min_x, _min_y, _max_x, _max_y fields to a Schema, and return a BoxKey that points to them.
std::shared_ptr< RecordT > addNew()
Create a new record, add it to the end of the catalog, and return a pointer to it.
void reserve(size_type n)
Increase the capacity of the catalog to the given size.
Custom catalog class for ExposureRecord/Table.
typename Base::const_iterator const_iterator
static ExposureCatalogT readFromArchive(io::InputArchive const &archive, BaseCatalog const &catalog)
Convenience input function for Persistables that contain an ExposureCatalog.
void writeToArchive(io::OutputArchiveHandle &handle, bool ignoreUnpersistable=true) const
Convenience output function for Persistables that contain an ExposureCatalog.
ExposureCatalogT subsetContaining(lsst::geom::SpherePoint const &coord, bool includeValidPolygon=false) const
Return a shallow subset of the catalog with only those records that contain the given point.
Record class used to store exposure metadata.
bool contains(lsst::geom::SpherePoint const &coord, bool includeValidPolygon=false) const
Return true if the bounding box contains the given celestial coordinate point, taking into account th...
lsst::geom::Box2I getBBox() const
~ExposureRecord() override
void setBBox(lsst::geom::Box2I const &bbox)
void _assign(BaseRecord const &other) override
Called by assign() after transferring fields to allow subclass data members to be copied.
Table class used to store exposure metadata.
std::shared_ptr< BaseRecord > _makeRecord() override
Default-construct an associated record (protected implementation).
std::shared_ptr< io::FitsWriter > makeFitsWriter(fits::Fits *fitsfile, int flags) const override
static Box2IKey getBBoxKey()
Key for the full bbox.
~ExposureTable() override
ExposureTable(Schema const &schema)
std::shared_ptr< BaseTable > _clone() const override
Clone implementation with noncovariant return types.
static std::shared_ptr< ExposureTable > make(Schema const &schema)
Construct a new table.
bool isValid() const noexcept
Return true if the key was initialized to valid offset.
PersistableObjectColumnReader(int column)
static void setup(std::string const &name, io::FitsSchemaInputMapper &mapper)
void readCell(BaseRecord &record, std::size_t row, fits::Fits &fits, std::shared_ptr< io::InputArchive > const &archive) const override
Read values from a single row.
Defines the fields and offsets for a table.
A mapping between the keys of two Schemas, used to copy data between them.
static SchemaMapper removeMinimalSchema(Schema const &input, Schema const &minimal)
Create a mapper by removing fields from the front of a schema.
static std::vector< SchemaMapper > join(std::vector< Schema > const &inputs, std::vector< std::string > const &prefixes=std::vector< std::string >())
Combine a sequence of schemas into one, creating a SchemaMapper for each.
Polymorphic reader interface used to read different kinds of objects from one or more FITS binary tab...
An object passed to Persistable::write to allow it to persist itself.
void saveCatalog(BaseCatalog const &catalog)
Save a catalog in the archive.
BaseCatalog makeCatalog(Schema const &schema)
Return a new, empty catalog with the given schema.
A floating-point coordinate rectangle geometry.
bool contains(Point2D const &point) const noexcept
Return true if the box contains the point.
An integer coordinate rectangle.
Point in an unspecified spherical coordinate system.
Reports arguments outside the domain of an operation.
Reports invalid arguments.
Reports errors in the logical structure of the program.
daf::base::PropertySet * set
std::shared_ptr< BaseRecord > _record
Key< int > transmissionCurve
std::shared_ptr< io::OutputArchive > _archive
PersistenceHelper _helper