lsst.afw g2603b601e3+b53bcbb7be
VisitInfo.cc
Go to the documentation of this file.
1// -*- LSST-C++ -*- // fixed format comment for emacs
2/*
3 * LSST Data Management System
4 * Copyright 2016 LSST Corporation.
5 *
6 * This product includes software developed by the
7 * LSST Project (http://www.lsst.org/).
8 *
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the LSST License Statement and
20 * the GNU General Public License along with this program. If not,
21 * see <http://www.lsstcorp.org/LegalNotices/>.
22 */
23#include <cmath>
24#include <limits>
25#include <sstream>
26
27#include "boost/algorithm/string/trim.hpp"
28
29#include "lsst/utils/hashCombine.h"
30#include "lsst/pex/exceptions.h"
31#include "lsst/geom/Angle.h"
33#include "lsst/afw/table/Key.h"
34#include "lsst/afw/table/aggregates.h" // for CoordKey
36#include "lsst/afw/table/misc.h" // for RecordId
39#include "lsst/afw/table/io/CatalogVector.h" // needed, but why?
42
44
45namespace lsst {
46namespace afw {
47
50
51namespace image {
52
53// the following persistence-related code emulates that in Calib.cc
54
55namespace {
56
57// Version history:
58// unversioned: original VisitInfo schema
59// 1: file versioning, instrument label
60// 2: id field
61// 3: focusZ field
62int constexpr SERIALIZATION_VERSION = 3;
63
65
74double getDouble(daf::base::PropertySet const& metadata, std::string const& key) {
75 try {
76 return metadata.exists(key) ? metadata.getAsDouble(key) : nan;
77 } catch (pex::exceptions::TypeError& err) {
78 // If an exposure has an invalid float here (often NaN)
79 // it should put NaN in the visitInfo because it's the same
80 // as it not being a valid key.
81 return nan;
82 }
83}
84
93lsst::geom::Angle getAngle(daf::base::PropertySet const& metadata, std::string const& key) {
94 return getDouble(metadata, key) * lsst::geom::degrees;
95}
96
105std::string getString(daf::base::PropertySet const& metadata, std::string const& key) {
106 return metadata.exists(key) ? metadata.getAsString(key) : "";
107}
108
117bool setDouble(daf::base::PropertySet& metadata, std::string const& key, double value,
118 std::string const& comment) {
119 if (std::isfinite(value)) {
120 metadata.set(key, value);
121 return true;
122 }
123 return false;
124}
125
134bool setAngle(daf::base::PropertySet& metadata, std::string const& key, lsst::geom::Angle const& angle,
135 std::string const& comment) {
136 return setDouble(metadata, key, angle.asDegrees(), comment);
137}
138
147bool setString(daf::base::PropertySet& metadata, std::string const& key, std::string value,
148 std::string const& comment) {
149 if (!value.empty()) {
150 metadata.set(key, value);
151 return true;
152 }
153 return false;
154}
155
161std::string rotTypeStrFromEnum(RotType rotType) {
162 switch (rotType) {
163 case RotType::UNKNOWN:
164 return "UNKNOWN";
165 case RotType::SKY:
166 return "SKY";
167 case RotType::HORIZON:
168 return "HORIZON";
169 case RotType::MOUNT:
170 return "MOUNT";
171 }
173 os << "Unknown RotType enum: " << static_cast<int>(rotType);
175}
176
182RotType rotTypeEnumFromStr(std::string const& rotTypeName) {
183 if (rotTypeName == "UNKNOWN") {
184 return RotType::UNKNOWN;
185 } else if (rotTypeName == "SKY") {
186 return RotType::SKY;
187 } else if (rotTypeName == "HORIZON") {
188 return RotType::HORIZON;
189 } else if (rotTypeName == "MOUNT") {
190 return RotType::MOUNT;
191 }
193 os << "Unknown RotType name: \"" << rotTypeName << "\"";
195}
196
197class VisitInfoSchema {
198public:
199 table::Schema schema;
200 table::Key<table::RecordId> exposureId;
201 table::Key<double> exposureTime;
202 table::Key<double> darkTime;
203 table::Key<std::int64_t> tai;
204 table::Key<double> ut1;
205 table::Key<lsst::geom::Angle> era;
206 table::CoordKey boresightRaDec;
207 table::Key<lsst::geom::Angle> boresightAzAlt_az;
208 table::Key<lsst::geom::Angle> boresightAzAlt_alt;
209 table::Key<double> boresightAirmass;
210 table::Key<lsst::geom::Angle> boresightRotAngle;
211 table::Key<int> rotType;
212 // observatory data
213 table::Key<lsst::geom::Angle> latitude;
214 table::Key<lsst::geom::Angle> longitude;
215 table::Key<double> elevation;
216 // weather data
217 table::Key<double> airTemperature;
218 table::Key<double> airPressure;
219 table::Key<double> humidity;
220
221 table::Key<std::string> instrumentLabel;
222 table::Key<int> version;
223
224 table::Key<table::RecordId> idnum;
225
226 table::Key<double> focusZ;
227
228 static std::string const VERSION_KEY;
229
230 static VisitInfoSchema const& get() {
231 static VisitInfoSchema instance;
232 return instance;
233 }
234
235 // No copying
236 VisitInfoSchema(const VisitInfoSchema&) = delete;
237 VisitInfoSchema& operator=(const VisitInfoSchema&) = delete;
238
239 // No moving
240 VisitInfoSchema(VisitInfoSchema&&) = delete;
241 VisitInfoSchema& operator=(VisitInfoSchema&&) = delete;
242
243private:
244 VisitInfoSchema()
245 : schema(),
246 exposureId(schema.addField<table::RecordId>("exposureid", "exposure ID", "")),
247 exposureTime(schema.addField<double>("exposuretime", "exposure duration", "s")),
248 darkTime(schema.addField<double>("darktime", "time from CCD flush to readout", "s")),
249 tai(schema.addField<std::int64_t>(
250 "tai", "TAI date and time at middle of exposure as nsec from unix epoch", "nsec")),
251 ut1(schema.addField<double>("ut1", "UT1 date and time at middle of exposure", "MJD")),
252 era(schema.addField<lsst::geom::Angle>("era", "earth rotation angle at middle of exposure",
253 "")),
254 boresightRaDec(table::CoordKey::addFields(schema, "boresightradec",
255 "sky position of boresight at middle of exposure")),
256 // CoordKey is intended for ICRS coordinates, so use a pair of lsst::geom::Angle fields
257 // to save boresightAzAlt
258 boresightAzAlt_az(schema.addField<lsst::geom::Angle>(
259 "boresightazalt_az",
260 "refracted apparent topocentric position of boresight at middle of exposure", "")),
261 boresightAzAlt_alt(schema.addField<lsst::geom::Angle>(
262 "boresightazalt_alt",
263 "refracted apparent topocentric position of boresight at middle of exposure", "")),
264 boresightAirmass(schema.addField<double>(
265 "boresightairmass", "airmass at boresight, relative to zenith at sea level", "")),
266 boresightRotAngle(schema.addField<lsst::geom::Angle>(
267 "boresightrotangle", "rotation angle at boresight at middle of exposure", "")),
268 rotType(schema.addField<int>("rottype", "rotation type; see VisitInfo.getRotType for details",
269 "MJD")),
270
271 // observatory data
272 latitude(schema.addField<lsst::geom::Angle>(
273 "latitude", "latitude of telescope (+ is east of Greenwich)", "")),
274 longitude(schema.addField<lsst::geom::Angle>("longitude", "longitude of telescope", "")),
275 elevation(schema.addField<double>("elevation", "elevation of telescope", "")),
276
277 // weather data
278 airTemperature(schema.addField<double>("airtemperature", "air temperature", "C")),
279 airPressure(schema.addField<double>("airpressure", "air pressure", "Pascal")),
280 humidity(schema.addField<double>("humidity", "humidity (%)", "")),
281
282 instrumentLabel(schema.addField<std::string>(
283 "instrumentlabel", "Short name of the instrument that took this data", "", 0)),
284
285 // for internal support
286 version(schema.addField<int>(VERSION_KEY, "version of this VisitInfo")),
287
288 idnum(schema.addField<table::RecordId>("idnum", "identifier of this full focal plane exposure",
289 "")),
290
291 focusZ(schema.addField<double>("focusz", "defocal distance", "mm")) {}
292};
293std::string const VisitInfoSchema::VERSION_KEY = "version";
294
295class VisitInfoFactory : public table::io::PersistableFactory {
296public:
297 std::shared_ptr<table::io::Persistable> read(InputArchive const& archive,
298 CatalogVector const& catalogs) const override {
299 VisitInfoSchema const& keys = VisitInfoSchema::get();
300 LSST_ARCHIVE_ASSERT(catalogs.size() == 1u);
301 LSST_ARCHIVE_ASSERT(catalogs.front().size() == 1u);
302 table::BaseRecord const& record = catalogs.front().front();
303 int version = getVersion(record);
304 if (version > SERIALIZATION_VERSION) {
305 throw LSST_EXCEPT(pex::exceptions::TypeError, "Cannot read VisitInfo FITS version > " +
306 std::to_string(SERIALIZATION_VERSION));
307 }
308
309 // Version-dependent fields
310 std::string instrumentLabel = version >= 1 ? record.get(keys.instrumentLabel) : "";
311 table::RecordId id = version >= 2 ? record.get(keys.idnum) : 0;
312 double focusZ = version >= 3 ? record.get(keys.focusZ) : nan;
313
315 new VisitInfo(record.get(keys.exposureId), record.get(keys.exposureTime),
316 record.get(keys.darkTime), ::DateTime(record.get(keys.tai), ::DateTime::TAI),
317 record.get(keys.ut1), record.get(keys.era), record.get(keys.boresightRaDec),
318 lsst::geom::SpherePoint(record.get(keys.boresightAzAlt_az),
319 record.get(keys.boresightAzAlt_alt)),
320 record.get(keys.boresightAirmass), record.get(keys.boresightRotAngle),
321 static_cast<RotType>(record.get(keys.rotType)),
322 coord::Observatory(record.get(keys.longitude), record.get(keys.latitude),
323 record.get(keys.elevation)),
324 coord::Weather(record.get(keys.airTemperature), record.get(keys.airPressure),
325 record.get(keys.humidity)),
326 instrumentLabel, id, focusZ));
327 return result;
328 }
329
330 explicit VisitInfoFactory(std::string const& name) : table::io::PersistableFactory(name) {}
331
332private:
333 int getVersion(table::BaseRecord const& record) const {
334 try {
335 // Don't assume version is at same index as in VisitInfoSchema
336 auto versionKey = record.getSchema().find<int>(VisitInfoSchema::VERSION_KEY);
337 return record.get(versionKey.key);
338 } catch (pex::exceptions::NotFoundError const&) {
339 // un-versioned files are implicitly version 0
340 return 0;
341 }
342 }
343};
344
345std::string getVisitInfoPersistenceName() { return "VisitInfo"; }
346
347VisitInfoFactory registration(getVisitInfoPersistenceName());
348
349} // namespace
350
351namespace detail {
352
354 int nstripped = 0;
355
356 std::vector<std::string> keyList = {"EXPID", "EXPTIME", "DARKTIME", "DATE-AVG", "TIMESYS",
357 "TIME-MID", "MJD-AVG-UT1", "AVG-ERA", "BORE-RA", "BORE-DEC",
358 "BORE-AZ", "BORE-ALT", "BORE-AIRMASS", "BORE-ROTANG", "ROTTYPE",
359 "OBS-LONG", "OBS-LAT", "OBS-ELEV", "AIRTEMP", "AIRPRESS",
360 "HUMIDITY", "INSTRUMENT", "IDNUM", "FOCUSZ"};
361 for (auto&& key : keyList) {
362 if (metadata.exists(key)) {
363 metadata.remove(key);
364 nstripped++;
365 }
366 }
367 return nstripped;
368}
369
371 if (visitInfo.getExposureId() != 0) {
372 metadata.set("EXPID", visitInfo.getExposureId());
373 }
374 setDouble(metadata, "EXPTIME", visitInfo.getExposureTime(), "Exposure time (sec)");
375 setDouble(metadata, "DARKTIME", visitInfo.getDarkTime(), "Time from CCD flush to readout (sec)");
376 if (visitInfo.getDate().isValid()) {
377 metadata.set("DATE-AVG", visitInfo.getDate().toString(::DateTime::TAI),
378 "TAI date at middle of observation");
379 metadata.set("TIMESYS", "TAI");
380 }
381 setDouble(metadata, "MJD-AVG-UT1", visitInfo.getUt1(), "UT1 MJD date at ctr of obs");
382 setAngle(metadata, "AVG-ERA", visitInfo.getEra(), "Earth rot ang at ctr of obs (deg)");
383 auto boresightRaDec = visitInfo.getBoresightRaDec();
384 setAngle(metadata, "BORE-RA", boresightRaDec[0], "ICRS RA (deg) at boresight");
385 setAngle(metadata, "BORE-DEC", boresightRaDec[1], "ICRS Dec (deg) at boresight");
386 auto boresightAzAlt = visitInfo.getBoresightAzAlt();
387 setAngle(metadata, "BORE-AZ", boresightAzAlt[0], "Refr app topo az (deg) at bore");
388 setAngle(metadata, "BORE-ALT", boresightAzAlt[1], "Refr app topo alt (deg) at bore");
389 setDouble(metadata, "BORE-AIRMASS", visitInfo.getBoresightAirmass(), "Airmass at boresight");
390 setAngle(metadata, "BORE-ROTANG", visitInfo.getBoresightRotAngle(), "Rotation angle (deg) at boresight");
391 metadata.set("ROTTYPE", rotTypeStrFromEnum(visitInfo.getRotType()), "Type of rotation angle");
392 auto observatory = visitInfo.getObservatory();
393 setAngle(metadata, "OBS-LONG", observatory.getLongitude(), "Telescope longitude (+E, deg)");
394 setAngle(metadata, "OBS-LAT", observatory.getLatitude(), "Telescope latitude (deg)");
395 setDouble(metadata, "OBS-ELEV", observatory.getElevation(), "Telescope elevation (m)");
396 auto weather = visitInfo.getWeather();
397 setDouble(metadata, "AIRTEMP", weather.getAirTemperature(), "Outside air temperature (C)");
398 setDouble(metadata, "AIRPRESS", weather.getAirPressure(), "Outdoor air pressure (P)");
399 setDouble(metadata, "HUMIDITY", weather.getHumidity(), "Relative humidity (%)");
400 setString(metadata, "INSTRUMENT", visitInfo.getInstrumentLabel(),
401 "Short name of the instrument that took this data");
402 if (visitInfo.getId() != 0) {
403 metadata.set("IDNUM", visitInfo.getId(), "identifier of this full focal plane exposure");
404 setDouble(metadata, "FOCUSZ", visitInfo.getFocusZ(), "Defocal Distance (mm)");
405 }
406}
407
408} // namespace detail
409
410VisitInfo::VisitInfo(daf::base::PropertySet const& metadata)
411 : _exposureId(0),
412 _exposureTime(nan), // don't use getDouble because str values are also accepted
413 _darkTime(getDouble(metadata, "DARKTIME")),
414 _date(),
415 _ut1(getDouble(metadata, "MJD-AVG-UT1")),
416 _era(getAngle(metadata, "AVG-ERA")),
417 _boresightRaDec(
418 lsst::geom::SpherePoint(getAngle(metadata, "BORE-RA"), getAngle(metadata, "BORE-DEC"))),
419 _boresightAzAlt(
420 lsst::geom::SpherePoint(getAngle(metadata, "BORE-AZ"), getAngle(metadata, "BORE-ALT"))),
421 _boresightAirmass(getDouble(metadata, "BORE-AIRMASS")),
422 _boresightRotAngle(getAngle(metadata, "BORE-ROTANG")),
423 _rotType(RotType::UNKNOWN),
424 _observatory(getAngle(metadata, "OBS-LONG"), getAngle(metadata, "OBS-LAT"),
425 getDouble(metadata, "OBS-ELEV")),
426 _weather(getDouble(metadata, "AIRTEMP"), getDouble(metadata, "AIRPRESS"),
427 getDouble(metadata, "HUMIDITY")),
428 _instrumentLabel(getString(metadata, "INSTRUMENT")),
429 _id(0),
430 _focusZ(getDouble(metadata, "FOCUSZ")) {
431 auto key = "EXPID";
432 if (metadata.exists(key)) {
433 _exposureId = metadata.getAsInt64(key);
434 }
435 key = "IDNUM";
436 if (metadata.exists(key)) {
437 _id = metadata.getAsInt64(key);
438 }
439
440 key = "EXPTIME";
441 if (metadata.exists(key)) {
442 try {
443 _exposureTime = metadata.getAsDouble(key);
444 } catch (lsst::pex::exceptions::TypeError& err) {
445 // some old exposures have EXPTIME stored as a string
446 std::string exptimeStr = metadata.getAsString(key);
447 _exposureTime = std::stod(exptimeStr);
448 }
449 }
450
451 key = "DATE-AVG";
452 if (metadata.exists(key)) {
453 if (metadata.exists("TIMESYS")) {
454 auto timesysName = boost::algorithm::trim_right_copy(metadata.getAsString("TIMESYS"));
455 if (timesysName != "TAI") {
456 // rather than try to deal with all the possible choices, which requires
457 // appending or deleting a "Z", depending on the time system, just give up.
458 // VisitInfo should be used on FITS headers that have been sanitized!
460 os << "TIMESYS = \"" << timesysName
461 << "\"; VisitInfo requires TIMESYS to exist and to equal \"TAI\"";
463 }
464 } else {
466 "TIMESYS not found; VistitInfo requires TIMESYS to exist and to equal \"TAI\"");
467 }
468 _date = ::DateTime(boost::algorithm::trim_right_copy(metadata.getAsString(key)), ::DateTime::TAI);
469 } else {
470 // DATE-AVG not found. For backwards compatibility look for TIME-MID, an outdated LSST keyword
471 // whose time system was UTC, despite a FITS comment claiming it was TAI. Ignore TIMESYS.
472 key = "TIME-MID";
473 if (metadata.exists(key)) {
474 _date = ::DateTime(boost::algorithm::trim_right_copy(metadata.getAsString(key)), ::DateTime::UTC);
475 }
476 }
477
478 key = "ROTTYPE";
479 if (metadata.exists(key)) {
480 _rotType = rotTypeEnumFromStr(metadata.getAsString(key));
481 }
482}
483
490bool _eqOrNan(double lhs, double rhs) noexcept { return (std::isnan(lhs) && std::isnan(rhs)) || lhs == rhs; }
491
499 return (!lhs.isFinite() && !rhs.isFinite()) || lhs == rhs;
500}
501
502bool VisitInfo::operator==(VisitInfo const& other) const {
503 return _exposureId == other.getExposureId() && _eqOrNan(_exposureTime, other.getExposureTime()) &&
504 _eqOrNan(_darkTime, other.getDarkTime()) && _date == other.getDate() &&
505 _eqOrNan(_ut1, other.getUt1()) && _eqOrNan(_era, other.getEra()) &&
506 _eqOrNonFinite(_boresightRaDec, other.getBoresightRaDec()) &&
507 _eqOrNonFinite(_boresightAzAlt, other.getBoresightAzAlt()) &&
508 _eqOrNan(_boresightAirmass, other.getBoresightAirmass()) &&
509 _eqOrNan(_boresightRotAngle, other.getBoresightRotAngle()) && _rotType == other.getRotType() &&
510 _observatory == other.getObservatory() && _weather == other.getWeather() &&
511 _instrumentLabel == other.getInstrumentLabel() && _id == other.getId() &&
512 _eqOrNan(_focusZ, other.getFocusZ());
513}
514
516 // Completely arbitrary seed
517 return utils::hashCombine(17, _exposureId, _exposureTime, _darkTime, _date, _ut1, _era, _boresightRaDec,
518 _boresightAzAlt, _boresightAirmass, _boresightRotAngle, _rotType, _observatory,
519 _weather, _instrumentLabel, _id, _focusZ);
520}
521
522std::string VisitInfo::getPersistenceName() const { return getVisitInfoPersistenceName(); }
523
525 VisitInfoSchema const& keys = VisitInfoSchema::get();
526 table::BaseCatalog cat = handle.makeCatalog(keys.schema);
528 record->set(keys.exposureId, getExposureId());
529 record->set(keys.exposureTime, getExposureTime());
530 record->set(keys.darkTime, getDarkTime());
531 record->set(keys.tai, getDate().nsecs(::DateTime::TAI));
532 record->set(keys.ut1, getUt1());
533 record->set(keys.era, getEra());
534 record->set(keys.boresightRaDec, getBoresightRaDec());
535 auto boresightAzAlt = getBoresightAzAlt();
536 record->set(keys.boresightAzAlt_az, boresightAzAlt[0]);
537 record->set(keys.boresightAzAlt_alt, boresightAzAlt[1]);
538 record->set(keys.boresightAirmass, getBoresightAirmass());
539 record->set(keys.boresightRotAngle, getBoresightRotAngle());
540 record->set(keys.rotType, static_cast<int>(getRotType()));
541 auto observatory = getObservatory();
542 record->set(keys.latitude, observatory.getLatitude());
543 record->set(keys.longitude, observatory.getLongitude());
544 record->set(keys.elevation, observatory.getElevation());
545 auto weather = getWeather();
546 record->set(keys.airTemperature, weather.getAirTemperature());
547 record->set(keys.airPressure, weather.getAirPressure());
548 record->set(keys.humidity, weather.getHumidity());
549 record->set(keys.instrumentLabel, getInstrumentLabel());
550 record->set(keys.version, SERIALIZATION_VERSION);
551 record->set(keys.idnum, getId());
552 record->set(keys.focusZ, getFocusZ());
553 handle.saveCatalog(cat);
554}
555
557
559
565 double _parallactic_y, _parallactic_x, result;
566 _parallactic_y = sin(getBoresightHourAngle().asRadians());
567 _parallactic_x =
568 cos((getBoresightRaDec()[1]).asRadians()) * tan(getObservatory().getLatitude().asRadians()) -
569 sin((getBoresightRaDec()[1]).asRadians()) * cos(getBoresightHourAngle().asRadians());
570 result = atan2(_parallactic_y, _parallactic_x);
571 return result * lsst::geom::radians;
572}
573
575 return std::make_unique<VisitInfo>(*this);
576}
577
578bool VisitInfo::equals(typehandling::Storable const& other) const noexcept {
579 return singleClassEquals(*this, other);
580}
581
583 std::stringstream buffer;
584 buffer << "VisitInfo(";
585 buffer << "exposureId=" << getExposureId() << ", ";
586 buffer << "exposureTime=" << getExposureTime() << ", ";
587 buffer << "darkTime=" << getDarkTime() << ", ";
588 buffer << "date=" << (getDate().isValid() ? getDate().toString(daf::base::DateTime::TAI) : "<invalid>")
589 << ", ";
590 buffer << "UT1=" << getUt1() << ", ";
591 buffer << "ERA=" << getEra() << ", ";
592 buffer << "boresightRaDec=" << getBoresightRaDec() << ", ";
593 buffer << "boresightAzAlt=" << getBoresightAzAlt() << ", ";
594 buffer << "boresightAirmass=" << getBoresightAirmass() << ", ";
595 buffer << "boresightRotAngle=" << getBoresightRotAngle() << ", ";
596 buffer << "rotType=" << static_cast<int>(getRotType()) << ", ";
597 buffer << "observatory=" << getObservatory() << ", ";
598 buffer << "weather=" << getWeather() << ", ";
599 buffer << "instrumentLabel='" << getInstrumentLabel() << "', ";
600 buffer << "id=" << getId() << ", ";
601 buffer << "focusZ=" << getFocusZ();
602 buffer << ")";
603 return buffer.str();
604}
605
607 os << visitInfo.toString();
608 return os;
609}
610
611} // namespace image
612} // namespace afw
613} // namespace lsst
table::Key< std::string > name
Definition: Amplifier.cc:116
#define LSST_EXCEPT(type,...)
table::Key< double > angle
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
Definition: Persistable.h:48
std::ostream * os
Definition: Schema.cc:557
table::Key< lsst::geom::Angle > longitude
Definition: VisitInfo.cc:214
table::Key< lsst::geom::Angle > latitude
Definition: VisitInfo.cc:213
table::Key< lsst::geom::Angle > boresightAzAlt_az
Definition: VisitInfo.cc:207
table::Schema schema
Definition: VisitInfo.cc:199
table::Key< double > exposureTime
Definition: VisitInfo.cc:201
table::Key< lsst::geom::Angle > era
Definition: VisitInfo.cc:205
table::Key< double > airPressure
Definition: VisitInfo.cc:218
table::Key< lsst::geom::Angle > boresightAzAlt_alt
Definition: VisitInfo.cc:208
table::Key< int > rotType
Definition: VisitInfo.cc:211
table::Key< double > darkTime
Definition: VisitInfo.cc:202
table::Key< table::RecordId > idnum
Definition: VisitInfo.cc:224
table::Key< std::string > instrumentLabel
Definition: VisitInfo.cc:221
table::CoordKey boresightRaDec
Definition: VisitInfo.cc:206
table::Key< double > boresightAirmass
Definition: VisitInfo.cc:209
table::Key< double > airTemperature
Definition: VisitInfo.cc:217
table::Key< std::int64_t > tai
Definition: VisitInfo.cc:203
table::Key< double > elevation
Definition: VisitInfo.cc:215
table::Key< double > humidity
Definition: VisitInfo.cc:219
table::Key< int > version
Definition: VisitInfo.cc:222
table::Key< double > focusZ
Definition: VisitInfo.cc:226
table::Key< lsst::geom::Angle > boresightRotAngle
Definition: VisitInfo.cc:210
table::Key< double > ut1
Definition: VisitInfo.cc:204
table::Key< table::RecordId > exposureId
Definition: VisitInfo.cc:200
lsst::geom::Angle getLongitude() const noexcept
get telescope longitude (positive values are E of Greenwich)
Definition: Observatory.cc:50
Information about a single exposure of an imaging camera.
Definition: VisitInfo.h:68
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
Definition: VisitInfo.cc:522
daf::base::DateTime getDate() const
get uniform date and time at middle of exposure
Definition: VisitInfo.h:151
coord::Weather getWeather() const
get basic weather information
Definition: VisitInfo.h:186
lsst::geom::Angle getLocalEra() const
Definition: VisitInfo.cc:556
double getUt1() const
get UT1 (universal time) MJD date at middle of exposure
Definition: VisitInfo.h:154
double getBoresightAirmass() const
get airmass at the boresight, relative to zenith at sea level (and at the middle of the exposure,...
Definition: VisitInfo.h:169
lsst::geom::Angle getBoresightHourAngle() const
Definition: VisitInfo.cc:558
lsst::geom::Angle getBoresightRotAngle() const
Get rotation angle at boresight at middle of exposure.
Definition: VisitInfo.h:177
table::RecordId getExposureId() const
get exposure ID
Definition: VisitInfo.h:140
std::size_t hash_value() const noexcept override
Return a hash of this object.
Definition: VisitInfo.cc:515
bool operator==(VisitInfo const &other) const
Definition: VisitInfo.cc:502
lsst::geom::Angle getEra() const
get earth rotation angle at middle of exposure
Definition: VisitInfo.h:157
table::RecordId getId() const
Definition: VisitInfo.h:198
double getFocusZ() const
Definition: VisitInfo.h:201
std::string toString() const override
Create a string representation of this object.
Definition: VisitInfo.cc:582
double getExposureTime() const
get exposure duration (shutter open time); (sec)
Definition: VisitInfo.h:145
RotType getRotType() const
get rotation type of boresightRotAngle
Definition: VisitInfo.h:180
bool equals(typehandling::Storable const &other) const noexcept override
Compare this object to another Storable.
Definition: VisitInfo.cc:578
lsst::geom::SpherePoint getBoresightAzAlt() const
get refracted apparent topocentric Az/Alt position at the boresight (and at the middle of the exposur...
Definition: VisitInfo.h:165
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)
Definition: VisitInfo.h:161
std::shared_ptr< typehandling::Storable > cloneStorable() const override
Create a new VisitInfo that is a copy of this one.
Definition: VisitInfo.cc:574
std::string getInstrumentLabel() const
Definition: VisitInfo.h:196
double getDarkTime() const
get time from CCD flush to exposure readout, including shutter open time (despite the name); (sec)
Definition: VisitInfo.h:148
coord::Observatory getObservatory() const
get observatory longitude, latitude and elevation
Definition: VisitInfo.h:183
lsst::geom::Angle getBoresightParAngle() const
Get parallactic angle at the boresight.
Definition: VisitInfo.cc:560
void write(OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
Definition: VisitInfo.cc:524
std::shared_ptr< RecordT > addNew()
Create a new record, add it to the end of the catalog, and return a pointer to it.
Definition: Catalog.h:490
bool isValid() const noexcept
Return true if the key was initialized to valid offset.
Definition: Key.h:97
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.
static std::shared_ptr< T > dynamicCast(std::shared_ptr< Persistable > const &ptr)
Dynamically cast a shared_ptr.
Definition: Persistable.cc:18
Interface supporting iteration over heterogenous containers.
Definition: Storable.h:58
std::string toString(Timescale scale) const
double get(DateSystem system=MJD, Timescale scale=TAI) const
void set(std::string const &name, T const &value)
std::string getAsString(std::string const &name) const
virtual void remove(std::string const &name)
int64_t getAsInt64(std::string const &name) const
bool exists(std::string const &name) const
double getAsDouble(std::string const &name) const
T empty(T... args)
T isfinite(T... args)
T isnan(T... args)
def keys(self)
int stripVisitInfoKeywords(daf::base::PropertySet &metadata)
Remove VisitInfo-related keywords from the metadata.
Definition: VisitInfo.cc:353
void setVisitInfoMetadata(daf::base::PropertyList &metadata, VisitInfo const &visitInfo)
Set FITS metadata from a VisitInfo.
Definition: VisitInfo.cc:370
bool _eqOrNonFinite(lsst::geom::SpherePoint const &lhs, lsst::geom::SpherePoint const &rhs) noexcept
Test whether two SpherePoints are exactly equal or invalid.
Definition: VisitInfo.cc:498
std::ostream & operator<<(std::ostream &os, Measurement const &measurement)
Definition: PhotoCalib.cc:47
RotType
Type of rotation.
Definition: VisitInfo.h:45
@ UNKNOWN
Rotation angle is unknown.
bool _eqOrNan(double lhs, double rhs) noexcept
Test whether two numbers are exactly equal or both NaN.
Definition: VisitInfo.cc:490
lsst::geom::Angle Angle
Definition: misc.h:33
lsst::geom::SpherePoint SpherePoint
Definition: misc.h:34
std::int64_t RecordId
Type used for unique IDs for records.
Definition: misc.h:21
AngleUnit constexpr degrees
AngleUnit constexpr radians
STL namespace.
T nan(T... args)
T quiet_NaN(T... args)
T stod(T... args)
T str(T... args)
Key< int > visitInfo
Definition: Exposure.cc:70
T to_string(T... args)
std::shared_ptr< table::io::Persistable > read(table::io::InputArchive const &archive, table::io::CatalogVector const &catalogs) const override
Definition: warpExposure.cc:0