LSSTApplications
20.0.0
LSSTDataManagementBasePackage
|
Go to the documentation of this file.
28 #include "boost/algorithm/string/trim.hpp"
68 double getDouble(daf::base::PropertySet
const& metadata,
std::string const&
key) {
69 return metadata.exists(
key) ? metadata.getAsDouble(
key) :
nan;
92 bool setDouble(daf::base::PropertySet& metadata,
std::string const&
key,
double value,
95 metadata.set(
key, value);
111 return setDouble(metadata,
key,
angle.asDegrees(), comment);
121 case RotType::UNKNOWN:
125 case RotType::HORIZON:
131 os <<
"Unknown RotType enum: " <<
static_cast<int>(
rotType);
141 if (rotTypeName ==
"UNKNOWN") {
142 return RotType::UNKNOWN;
143 }
else if (rotTypeName ==
"SKY") {
145 }
else if (rotTypeName ==
"HORIZON") {
146 return RotType::HORIZON;
147 }
else if (rotTypeName ==
"MOUNT") {
148 return RotType::MOUNT;
151 os <<
"Unknown RotType name: \"" << rotTypeName <<
"\"";
155 class VisitInfoSchema {
161 table::Key<std::int64_t>
tai;
163 table::Key<lsst::geom::Angle>
era;
179 static VisitInfoSchema
const& get() {
180 static VisitInfoSchema instance;
185 VisitInfoSchema(
const VisitInfoSchema&) =
delete;
186 VisitInfoSchema& operator=(
const VisitInfoSchema&) =
delete;
189 VisitInfoSchema(VisitInfoSchema&&) =
delete;
190 VisitInfoSchema& operator=(VisitInfoSchema&&) =
delete;
197 darkTime(
schema.addField<double>(
"darktime",
"time from CCD flush to readout",
"s")),
199 "tai",
"TAI date and time at middle of exposure as nsec from unix epoch",
"nsec")),
200 ut1(
schema.addField<double>(
"ut1",
"UT1 date and time at middle of exposure",
"MJD")),
204 "sky position of boresight at middle of exposure")),
209 "refracted apparent topocentric position of boresight at middle of exposure",
"")),
211 "boresightazalt_alt",
212 "refracted apparent topocentric position of boresight at middle of exposure",
"")),
214 "boresightairmass",
"airmass at boresight, relative to zenith at sea level",
"")),
216 "boresightrotangle",
"rotation angle at boresight at middle of exposure",
"")),
217 rotType(
schema.addField<int>(
"rottype",
"rotation type; see VisitInfo.getRotType for details",
221 "latitude",
"latitude of telescope (+ is east of Greenwich)",
"")),
223 elevation(
schema.addField<double>(
"elevation",
"elevation of telescope",
"")),
227 humidity(
schema.addField<double>(
"humidity",
"humidity (%)",
"")) {}
230 class VisitInfoFactory :
public table::io::PersistableFactory {
233 CatalogVector
const& catalogs)
const override {
234 VisitInfoSchema
const&
keys = VisitInfoSchema::get();
238 table::BaseRecord
const& record = catalogs.front().front();
240 new VisitInfo(record.get(
keys.exposureId), record.get(
keys.exposureTime),
241 record.get(
keys.darkTime), ::
DateTime(record.get(
keys.tai), ::DateTime::TAI),
242 record.
get(
keys.ut1), record.get(
keys.era), record.get(
keys.boresightRaDec),
244 record.get(
keys.boresightAzAlt_alt)),
245 record.get(
keys.boresightAirmass), record.get(
keys.boresightRotAngle),
247 coord::Observatory(record.get(
keys.longitude), record.get(
keys.latitude),
248 record.get(
keys.elevation)),
249 coord::Weather(record.get(
keys.airTemperature), record.get(
keys.airPressure),
250 record.get(
keys.humidity))));
254 explicit VisitInfoFactory(
std::string const&
name) : table::io::PersistableFactory(
name) {}
257 std::string getVisitInfoPersistenceName() {
return "VisitInfo"; }
259 VisitInfoFactory registration(getVisitInfoPersistenceName());
269 "EXPID",
"EXPTIME",
"DARKTIME",
"DATE-AVG",
"TIMESYS",
"TIME-MID",
"MJD-AVG-UT1",
270 "AVG-ERA",
"BORE-RA",
"BORE-DEC",
"BORE-AZ",
"BORE-ALT",
"BORE-AIRMASS",
"BORE-ROTANG",
271 "ROTTYPE",
"OBS-LONG",
"OBS-LAT",
"OBS-ELEV",
"AIRTEMP",
"AIRPRESS",
"HUMIDITY"};
272 for (
auto&&
key : keyList) {
285 setDouble(metadata,
"EXPTIME",
visitInfo.getExposureTime(),
"Exposure time (sec)");
286 setDouble(metadata,
"DARKTIME",
visitInfo.getDarkTime(),
"Time from CCD flush to readout (sec)");
288 metadata.
set(
"DATE-AVG",
visitInfo.getDate().toString(::DateTime::TAI),
289 "TAI date at middle of observation");
290 metadata.
set(
"TIMESYS",
"TAI");
292 setDouble(metadata,
"MJD-AVG-UT1",
visitInfo.getUt1(),
"UT1 MJD date at ctr of obs");
293 setAngle(metadata,
"AVG-ERA",
visitInfo.getEra(),
"Earth rot ang at ctr of obs (deg)");
295 setAngle(metadata,
"BORE-RA",
boresightRaDec[0],
"ICRS RA (deg) at boresight");
296 setAngle(metadata,
"BORE-DEC",
boresightRaDec[1],
"ICRS Dec (deg) at boresight");
297 auto boresightAzAlt =
visitInfo.getBoresightAzAlt();
298 setAngle(metadata,
"BORE-AZ", boresightAzAlt[0],
"Refr app topo az (deg) at bore");
299 setAngle(metadata,
"BORE-ALT", boresightAzAlt[1],
"Refr app topo alt (deg) at bore");
300 setDouble(metadata,
"BORE-AIRMASS",
visitInfo.getBoresightAirmass(),
"Airmass at boresight");
301 setAngle(metadata,
"BORE-ROTANG",
visitInfo.getBoresightRotAngle(),
"Rotation angle (deg) at boresight");
302 metadata.
set(
"ROTTYPE", rotTypeStrFromEnum(
visitInfo.getRotType()),
"Type of rotation angle");
303 auto observatory =
visitInfo.getObservatory();
304 setAngle(metadata,
"OBS-LONG", observatory.getLongitude(),
"Telescope longitude (+E, deg)");
305 setAngle(metadata,
"OBS-LAT", observatory.getLatitude(),
"Telescope latitude (deg)");
306 setDouble(metadata,
"OBS-ELEV", observatory.getElevation(),
"Telescope elevation (m)");
308 setDouble(metadata,
"AIRTEMP", weather.getAirTemperature(),
"Outside air temperature (C)");
309 setDouble(metadata,
"AIRPRESS", weather.getAirPressure(),
"Outdoor air pressure (P)");
310 setDouble(metadata,
"HUMIDITY", weather.getHumidity(),
"Relative humidity (%)");
318 _darkTime(getDouble(metadata,
"DARKTIME")),
320 _ut1(getDouble(metadata,
"MJD-AVG-UT1")),
321 _era(getAngle(metadata,
"AVG-ERA")),
326 _boresightAirmass(getDouble(metadata,
"BORE-AIRMASS")),
327 _boresightRotAngle(getAngle(metadata,
"BORE-ROTANG")),
329 _observatory(getAngle(metadata,
"OBS-LONG"), getAngle(metadata,
"OBS-LAT"),
330 getDouble(metadata,
"OBS-ELEV")),
331 _weather(getDouble(metadata,
"AIRTEMP"), getDouble(metadata,
"AIRPRESS"),
332 getDouble(metadata,
"HUMIDITY")) {
351 if (metadata.
exists(
"TIMESYS")) {
352 auto timesysName = boost::algorithm::trim_right_copy(metadata.
getAsString(
"TIMESYS"));
353 if (timesysName !=
"TAI") {
358 os <<
"TIMESYS = \"" << timesysName
359 <<
"\"; VisitInfo requires TIMESYS to exist and to equal \"TAI\"";
364 "TIMESYS not found; VistitInfo requires TIMESYS to exist and to equal \"TAI\"");
383 return _exposureId ==
other.getExposureId() && _exposureTime ==
other.getExposureTime() &&
384 _darkTime ==
other.getDarkTime() && _date ==
other.getDate() && _ut1 ==
other.getUt1() &&
385 _era ==
other.getEra() && _boresightRaDec ==
other.getBoresightRaDec() &&
386 _boresightAzAlt ==
other.getBoresightAzAlt() && _boresightAirmass ==
other.getBoresightAirmass() &&
387 _boresightRotAngle ==
other.getBoresightRotAngle() && _rotType ==
other.getRotType() &&
388 _observatory ==
other.getObservatory() && _weather ==
other.getWeather();
393 return utils::hashCombine(17, _exposureId, _exposureTime, _darkTime, _date, _ut1, _era, _boresightRaDec,
394 _boresightAzAlt, _boresightAirmass, _boresightRotAngle, _rotType, _observatory,
401 VisitInfoSchema
const&
keys = VisitInfoSchema::get();
407 record->set(
keys.tai,
getDate().nsecs(::DateTime::TAI));
412 record->set(
keys.boresightAzAlt_az, boresightAzAlt[0]);
413 record->set(
keys.boresightAzAlt_alt, boresightAzAlt[1]);
418 record->set(
keys.latitude, observatory.getLatitude());
419 record->set(
keys.longitude, observatory.getLongitude());
420 record->set(
keys.elevation, observatory.getElevation());
422 record->set(
keys.airTemperature, weather.getAirTemperature());
423 record->set(
keys.airPressure, weather.getAirPressure());
424 record->set(
keys.humidity, weather.getHumidity());
437 double _parallactic_y, _parallactic_x,
result;
442 result = atan2(_parallactic_y, _parallactic_x);
447 return std::make_unique<VisitInfo>(*
this);
451 return singleClassEquals(*
this,
other);
456 buffer <<
"VisitInfo(";
461 buffer <<
"UT1=" <<
getUt1() <<
", ";
462 buffer <<
"ERA=" <<
getEra() <<
", ";
467 buffer <<
"rotType=" <<
static_cast<int>(
getRotType()) <<
", ";
constexpr AngleUnit degrees
constant with units of degrees
lsst::geom::Angle getLongitude() const noexcept
get telescope longitude (positive values are E of Greenwich)
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
daf::base::DateTime getDate() const
get uniform date and time at middle of exposure
std::int64_t RecordId
Type used for unique IDs for records.
double sin(Angle const &a)
double getUt1() const
get UT1 (universal time) MJD date at middle of exposure
table::RecordId getExposureId() const
get exposure ID
lsst::geom::SpherePoint SpherePoint
table::Key< double > boresightAirmass
table::Key< lsst::geom::Angle > era
bool equals(typehandling::Storable const &other) const noexcept override
Compare this object to another Storable.
RotType getRotType() const
get rotation type of boresightRotAngle
An object passed to Persistable::write to allow it to persist itself.
void setVisitInfoMetadata(daf::base::PropertyList &metadata, VisitInfo const &visitInfo)
Set FITS metadata from a VisitInfo.
void saveCatalog(BaseCatalog const &catalog)
Save a catalog in the archive.
lsst::geom::Angle getBoresightParAngle() const
Get parallactic angle at the boresight.
lsst::geom::Angle getEra() const
get earth rotation angle at middle of exposure
@ UNKNOWN
Rotation angle is unknown.
double getExposureTime() const
get exposure duration (shutter open time); (sec)
Class for storing ordered metadata with comments.
std::string toString(Timescale scale) const
Get date as an ISO8601-formatted string.
bool exists(std::string const &name) const
Determine if a name (possibly hierarchical) exists.
std::ostream & operator<<(std::ostream &os, Measurement const &measurement)
lsst::geom::SpherePoint getBoresightRaDec() const
get ICRS RA/Dec position at the boresight (and at the middle of the exposure, if it varies with time)
std::size_t hash_value() const noexcept override
Return a hash of this object.
table::Key< double > airPressure
Interface supporting iteration over heterogenous containers.
Class for handling dates/times, including MJD, UTC, and TAI.
table::Key< double > angle
table::Key< double > airTemperature
table::Key< int > rotType
coord::Weather getWeather() const
get basic weather information
table::Key< double > elevation
BaseCatalog makeCatalog(Schema const &schema)
Return a new, empty catalog with the given schema.
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
table::Key< lsst::geom::Angle > boresightAzAlt_az
Information about a single exposure of an imaging camera.
double get(DateSystem system=MJD, Timescale scale=TAI) const
Get date as a double in a specified representation, such as MJD.
table::Key< double > humidity
int64_t getAsInt64(std::string const &name) const
Get the last value for a bool/char/short/int/int64_t property name (possibly hierarchical).
std::string getAsString(std::string const &name) const
Get the last value for a string property name (possibly hierarchical).
double tan(Angle const &a)
lsst::geom::SpherePoint getBoresightAzAlt() const
get refracted apparent topocentric Az/Alt position at the boresight (and at the middle of the exposur...
void set(std::string const &name, T const &value)
Replace all values for a property name (possibly hierarchical) with a new scalar value.
ItemVariant const * other
lsst::geom::Angle getBoresightRotAngle() const
Get rotation angle at boresight at middle of exposure.
table::Key< table::RecordId > exposureId
table::Key< lsst::geom::Angle > boresightRotAngle
bool isValid() const noexcept
Return true if the key was initialized to valid offset.
lsst::geom::Angle getBoresightHourAngle() const
table::Key< double > exposureTime
table::CoordKey boresightRaDec
table::Key< double > darkTime
A base class for image defects.
virtual void remove(std::string const &name)
Remove all values for a property name (possibly hierarchical).
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
double getAsDouble(std::string const &name) const
Get the last value for any arithmetic property name (possibly hierarchical).
double getBoresightAirmass() const
get airmass at the boresight, relative to zenith at sea level (and at the middle of the exposure,...
bool operator==(VisitInfo const &other) const
void write(OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
std::size_t hashCombine(std::size_t seed) noexcept
Combine hashes.
std::string toString() const override
Create a string representation of this object.
table::Key< std::int64_t > tai
table::Key< lsst::geom::Angle > boresightAzAlt_alt
static std::shared_ptr< T > dynamicCast(std::shared_ptr< Persistable > const &ptr)
Dynamically cast a shared_ptr.
lsst::geom::Angle getLocalEra() const
A class representing an angle.
Class for storing generic metadata.
double getDarkTime() const
get time from CCD flush to exposure readout, including shutter open time (despite the name); (sec)
constexpr AngleUnit radians
constant with units of radians
Reports errors from accepting an object of an unexpected or inappropriate type.
table::Key< lsst::geom::Angle > longitude
Point in an unspecified spherical coordinate system.
std::shared_ptr< RecordT > addNew()
Create a new record, add it to the end of the catalog, and return a pointer to it.
table::Key< lsst::geom::Angle > latitude
int stripVisitInfoKeywords(daf::base::PropertySet &metadata)
Remove VisitInfo-related keywords from the metadata.
coord::Observatory getObservatory() const
get observatory longitude, latitude and elevation
double cos(Angle const &a)
std::shared_ptr< typehandling::Storable > cloneStorable() const override
Create a new VisitInfo that is a copy of this one.
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
Reports errors that are due to events beyond the control of the program.