LSST Applications g0b6bd0c080+a72a5dd7e6,g1182afd7b4+2a019aa3bb,g17e5ecfddb+2b8207f7de,g1d67935e3f+06cf436103,g38293774b4+ac198e9f13,g396055baef+6a2097e274,g3b44f30a73+6611e0205b,g480783c3b1+98f8679e14,g48ccf36440+89c08d0516,g4b93dc025c+98f8679e14,g5c4744a4d9+a302e8c7f0,g613e996a0d+e1c447f2e0,g6c8d09e9e7+25247a063c,g7271f0639c+98f8679e14,g7a9cd813b8+124095ede6,g9d27549199+a302e8c7f0,ga1cf026fa3+ac198e9f13,ga32aa97882+7403ac30ac,ga786bb30fb+7a139211af,gaa63f70f4e+9994eb9896,gabf319e997+ade567573c,gba47b54d5d+94dc90c3ea,gbec6a3398f+06cf436103,gc6308e37c7+07dd123edb,gc655b1545f+ade567573c,gcc9029db3c+ab229f5caf,gd01420fc67+06cf436103,gd877ba84e5+06cf436103,gdb4cecd868+6f279b5b48,ge2d134c3d5+cc4dbb2e3f,ge448b5faa6+86d1ceac1d,gecc7e12556+98f8679e14,gf3ee170dca+25247a063c,gf4ac96e456+ade567573c,gf9f5ea5b4d+ac198e9f13,gff490e6085+8c2580be5c,w.2022.27
LSST Data Management Base Package
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
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
61int constexpr SERIALIZATION_VERSION = 2;
62
64
73double getDouble(daf::base::PropertySet const& metadata, std::string const& key) {
74 try {
75 return metadata.exists(key) ? metadata.getAsDouble(key) : nan;
76 } catch (pex::exceptions::TypeError& err) {
77 // If an exposure has an invalid float here (often NaN)
78 // it should put NaN in the visitInfo because it's the same
79 // as it not being a valid key.
80 return nan;
81 }
82}
83
92lsst::geom::Angle getAngle(daf::base::PropertySet const& metadata, std::string const& key) {
93 return getDouble(metadata, key) * lsst::geom::degrees;
94}
95
104std::string getString(daf::base::PropertySet const& metadata, std::string const& key) {
105 return metadata.exists(key) ? metadata.getAsString(key) : "";
106}
107
116bool setDouble(daf::base::PropertySet& metadata, std::string const& key, double value,
117 std::string const& comment) {
118 if (std::isfinite(value)) {
119 metadata.set(key, value);
120 return true;
121 }
122 return false;
123}
124
133bool setAngle(daf::base::PropertySet& metadata, std::string const& key, lsst::geom::Angle const& angle,
134 std::string const& comment) {
135 return setDouble(metadata, key, angle.asDegrees(), comment);
136}
137
146bool setString(daf::base::PropertySet& metadata, std::string const& key, std::string value,
147 std::string const& comment) {
148 if (!value.empty()) {
149 metadata.set(key, value);
150 return true;
151 }
152 return false;
153}
154
160std::string rotTypeStrFromEnum(RotType rotType) {
161 switch (rotType) {
162 case RotType::UNKNOWN:
163 return "UNKNOWN";
164 case RotType::SKY:
165 return "SKY";
166 case RotType::HORIZON:
167 return "HORIZON";
168 case RotType::MOUNT:
169 return "MOUNT";
170 }
172 os << "Unknown RotType enum: " << static_cast<int>(rotType);
174}
175
181RotType rotTypeEnumFromStr(std::string const& rotTypeName) {
182 if (rotTypeName == "UNKNOWN") {
183 return RotType::UNKNOWN;
184 } else if (rotTypeName == "SKY") {
185 return RotType::SKY;
186 } else if (rotTypeName == "HORIZON") {
187 return RotType::HORIZON;
188 } else if (rotTypeName == "MOUNT") {
189 return RotType::MOUNT;
190 }
192 os << "Unknown RotType name: \"" << rotTypeName << "\"";
194}
195
196class VisitInfoSchema {
197public:
198 table::Schema schema;
199 table::Key<table::RecordId> exposureId;
200 table::Key<double> exposureTime;
201 table::Key<double> darkTime;
202 table::Key<std::int64_t> tai;
203 table::Key<double> ut1;
204 table::Key<lsst::geom::Angle> era;
205 table::CoordKey boresightRaDec;
206 table::Key<lsst::geom::Angle> boresightAzAlt_az;
207 table::Key<lsst::geom::Angle> boresightAzAlt_alt;
208 table::Key<double> boresightAirmass;
209 table::Key<lsst::geom::Angle> boresightRotAngle;
210 table::Key<int> rotType;
211 // observatory data
212 table::Key<lsst::geom::Angle> latitude;
213 table::Key<lsst::geom::Angle> longitude;
214 table::Key<double> elevation;
215 // weather data
216 table::Key<double> airTemperature;
217 table::Key<double> airPressure;
218 table::Key<double> humidity;
219
220 table::Key<std::string> instrumentLabel;
221 table::Key<int> version;
222
223 table::Key<table::RecordId> idnum;
224
225 static std::string const VERSION_KEY;
226
227 static VisitInfoSchema const& get() {
228 static VisitInfoSchema instance;
229 return instance;
230 }
231
232 // No copying
233 VisitInfoSchema(const VisitInfoSchema&) = delete;
234 VisitInfoSchema& operator=(const VisitInfoSchema&) = delete;
235
236 // No moving
237 VisitInfoSchema(VisitInfoSchema&&) = delete;
238 VisitInfoSchema& operator=(VisitInfoSchema&&) = delete;
239
240private:
241 VisitInfoSchema()
242 : schema(),
243 exposureId(schema.addField<table::RecordId>("exposureid", "exposure ID", "")),
244 exposureTime(schema.addField<double>("exposuretime", "exposure duration", "s")),
245 darkTime(schema.addField<double>("darktime", "time from CCD flush to readout", "s")),
246 tai(schema.addField<std::int64_t>(
247 "tai", "TAI date and time at middle of exposure as nsec from unix epoch", "nsec")),
248 ut1(schema.addField<double>("ut1", "UT1 date and time at middle of exposure", "MJD")),
249 era(schema.addField<lsst::geom::Angle>("era", "earth rotation angle at middle of exposure",
250 "")),
251 boresightRaDec(table::CoordKey::addFields(schema, "boresightradec",
252 "sky position of boresight at middle of exposure")),
253 // CoordKey is intended for ICRS coordinates, so use a pair of lsst::geom::Angle fields
254 // to save boresightAzAlt
256 "boresightazalt_az",
257 "refracted apparent topocentric position of boresight at middle of exposure", "")),
259 "boresightazalt_alt",
260 "refracted apparent topocentric position of boresight at middle of exposure", "")),
262 "boresightairmass", "airmass at boresight, relative to zenith at sea level", "")),
264 "boresightrotangle", "rotation angle at boresight at middle of exposure", "")),
265 rotType(schema.addField<int>("rottype", "rotation type; see VisitInfo.getRotType for details",
266 "MJD")),
267 // observatory data
268 latitude(schema.addField<lsst::geom::Angle>(
269 "latitude", "latitude of telescope (+ is east of Greenwich)", "")),
270 longitude(schema.addField<lsst::geom::Angle>("longitude", "longitude of telescope", "")),
271 elevation(schema.addField<double>("elevation", "elevation of telescope", "")),
272
273 // weather data
274 airTemperature(schema.addField<double>("airtemperature", "air temperature", "C")),
275 airPressure(schema.addField<double>("airpressure", "air pressure", "Pascal")),
276 humidity(schema.addField<double>("humidity", "humidity (%)", "")),
277
278 instrumentLabel(schema.addField<std::string>(
279 "instrumentlabel", "Short name of the instrument that took this data", "", 0)),
280
281 // for internal support
282 version(schema.addField<int>(VERSION_KEY, "version of this VisitInfo")),
283
284 idnum(schema.addField<table::RecordId>("idnum", "identifier of this full focal plane exposure",
285 "")) {}
286};
287std::string const VisitInfoSchema::VERSION_KEY = "version";
288
289class VisitInfoFactory : public table::io::PersistableFactory {
290public:
291 std::shared_ptr<table::io::Persistable> read(InputArchive const& archive,
292 CatalogVector const& catalogs) const override {
293 VisitInfoSchema const& keys = VisitInfoSchema::get();
294 LSST_ARCHIVE_ASSERT(catalogs.size() == 1u);
295 LSST_ARCHIVE_ASSERT(catalogs.front().size() == 1u);
296 table::BaseRecord const& record = catalogs.front().front();
297 int version = getVersion(record);
298 if (version > SERIALIZATION_VERSION) {
299 throw LSST_EXCEPT(pex::exceptions::TypeError, "Cannot read VisitInfo FITS version > " +
300 std::to_string(SERIALIZATION_VERSION));
301 }
302
303 // Version-dependent fields
304 std::string instrumentLabel = version >= 1 ? record.get(keys.instrumentLabel) : "";
305 table::RecordId id = version >= 2 ? record.get(keys.idnum) : 0;
306
308 new VisitInfo(record.get(keys.exposureId), record.get(keys.exposureTime),
309 record.get(keys.darkTime), ::DateTime(record.get(keys.tai), ::DateTime::TAI),
310 record.get(keys.ut1), record.get(keys.era), record.get(keys.boresightRaDec),
311 lsst::geom::SpherePoint(record.get(keys.boresightAzAlt_az),
312 record.get(keys.boresightAzAlt_alt)),
313 record.get(keys.boresightAirmass), record.get(keys.boresightRotAngle),
314 static_cast<RotType>(record.get(keys.rotType)),
315 coord::Observatory(record.get(keys.longitude), record.get(keys.latitude),
316 record.get(keys.elevation)),
317 coord::Weather(record.get(keys.airTemperature), record.get(keys.airPressure),
318 record.get(keys.humidity)),
319 instrumentLabel, id));
320 return result;
321 }
322
323 explicit VisitInfoFactory(std::string const& name) : table::io::PersistableFactory(name) {}
324
325private:
326 int getVersion(table::BaseRecord const& record) const {
327 try {
328 // Don't assume version is at same index as in VisitInfoSchema
329 auto versionKey = record.getSchema().find<int>(VisitInfoSchema::VERSION_KEY);
330 return record.get(versionKey.key);
331 } catch (pex::exceptions::NotFoundError const&) {
332 // un-versioned files are implicitly version 0
333 return 0;
334 }
335 }
336};
337
338std::string getVisitInfoPersistenceName() { return "VisitInfo"; }
339
340VisitInfoFactory registration(getVisitInfoPersistenceName());
341
342} // namespace
343
344namespace detail {
345
347 int nstripped = 0;
348
349 std::vector<std::string> keyList = {"EXPID", "EXPTIME", "DARKTIME", "DATE-AVG", "TIMESYS",
350 "TIME-MID", "MJD-AVG-UT1", "AVG-ERA", "BORE-RA", "BORE-DEC",
351 "BORE-AZ", "BORE-ALT", "BORE-AIRMASS", "BORE-ROTANG", "ROTTYPE",
352 "OBS-LONG", "OBS-LAT", "OBS-ELEV", "AIRTEMP", "AIRPRESS",
353 "HUMIDITY", "INSTRUMENT", "IDNUM"};
354 for (auto&& key : keyList) {
355 if (metadata.exists(key)) {
356 metadata.remove(key);
357 nstripped++;
358 }
359 }
360 return nstripped;
361}
362
364 if (visitInfo.getExposureId() != 0) {
365 metadata.set("EXPID", visitInfo.getExposureId());
366 }
367 setDouble(metadata, "EXPTIME", visitInfo.getExposureTime(), "Exposure time (sec)");
368 setDouble(metadata, "DARKTIME", visitInfo.getDarkTime(), "Time from CCD flush to readout (sec)");
369 if (visitInfo.getDate().isValid()) {
370 metadata.set("DATE-AVG", visitInfo.getDate().toString(::DateTime::TAI),
371 "TAI date at middle of observation");
372 metadata.set("TIMESYS", "TAI");
373 }
374 setDouble(metadata, "MJD-AVG-UT1", visitInfo.getUt1(), "UT1 MJD date at ctr of obs");
375 setAngle(metadata, "AVG-ERA", visitInfo.getEra(), "Earth rot ang at ctr of obs (deg)");
376 auto boresightRaDec = visitInfo.getBoresightRaDec();
377 setAngle(metadata, "BORE-RA", boresightRaDec[0], "ICRS RA (deg) at boresight");
378 setAngle(metadata, "BORE-DEC", boresightRaDec[1], "ICRS Dec (deg) at boresight");
379 auto boresightAzAlt = visitInfo.getBoresightAzAlt();
380 setAngle(metadata, "BORE-AZ", boresightAzAlt[0], "Refr app topo az (deg) at bore");
381 setAngle(metadata, "BORE-ALT", boresightAzAlt[1], "Refr app topo alt (deg) at bore");
382 setDouble(metadata, "BORE-AIRMASS", visitInfo.getBoresightAirmass(), "Airmass at boresight");
383 setAngle(metadata, "BORE-ROTANG", visitInfo.getBoresightRotAngle(), "Rotation angle (deg) at boresight");
384 metadata.set("ROTTYPE", rotTypeStrFromEnum(visitInfo.getRotType()), "Type of rotation angle");
385 auto observatory = visitInfo.getObservatory();
386 setAngle(metadata, "OBS-LONG", observatory.getLongitude(), "Telescope longitude (+E, deg)");
387 setAngle(metadata, "OBS-LAT", observatory.getLatitude(), "Telescope latitude (deg)");
388 setDouble(metadata, "OBS-ELEV", observatory.getElevation(), "Telescope elevation (m)");
389 auto weather = visitInfo.getWeather();
390 setDouble(metadata, "AIRTEMP", weather.getAirTemperature(), "Outside air temperature (C)");
391 setDouble(metadata, "AIRPRESS", weather.getAirPressure(), "Outdoor air pressure (P)");
392 setDouble(metadata, "HUMIDITY", weather.getHumidity(), "Relative humidity (%)");
393 setString(metadata, "INSTRUMENT", visitInfo.getInstrumentLabel(),
394 "Short name of the instrument that took this data");
395 if (visitInfo.getId() != 0) {
396 metadata.set("IDNUM", visitInfo.getId(), "identifier of this full focal plane exposure");
397 }
398}
399
400} // namespace detail
401
402VisitInfo::VisitInfo(daf::base::PropertySet const& metadata)
403 : _exposureId(0),
404 _exposureTime(nan), // don't use getDouble because str values are also accepted
405 _darkTime(getDouble(metadata, "DARKTIME")),
406 _date(),
407 _ut1(getDouble(metadata, "MJD-AVG-UT1")),
408 _era(getAngle(metadata, "AVG-ERA")),
409 _boresightRaDec(
410 lsst::geom::SpherePoint(getAngle(metadata, "BORE-RA"), getAngle(metadata, "BORE-DEC"))),
411 _boresightAzAlt(
412 lsst::geom::SpherePoint(getAngle(metadata, "BORE-AZ"), getAngle(metadata, "BORE-ALT"))),
413 _boresightAirmass(getDouble(metadata, "BORE-AIRMASS")),
414 _boresightRotAngle(getAngle(metadata, "BORE-ROTANG")),
415 _rotType(RotType::UNKNOWN),
416 _observatory(getAngle(metadata, "OBS-LONG"), getAngle(metadata, "OBS-LAT"),
417 getDouble(metadata, "OBS-ELEV")),
418 _weather(getDouble(metadata, "AIRTEMP"), getDouble(metadata, "AIRPRESS"),
419 getDouble(metadata, "HUMIDITY")),
420 _instrumentLabel(getString(metadata, "INSTRUMENT")),
421 _id(0) {
422 auto key = "EXPID";
423 if (metadata.exists(key)) {
424 _exposureId = metadata.getAsInt64(key);
425 }
426 key = "IDNUM";
427 if (metadata.exists(key)) {
428 _id = metadata.getAsInt64(key);
429 }
430
431 key = "EXPTIME";
432 if (metadata.exists(key)) {
433 try {
434 _exposureTime = metadata.getAsDouble(key);
435 } catch (lsst::pex::exceptions::TypeError& err) {
436 // some old exposures have EXPTIME stored as a string
437 std::string exptimeStr = metadata.getAsString(key);
438 _exposureTime = std::stod(exptimeStr);
439 }
440 }
441
442 key = "DATE-AVG";
443 if (metadata.exists(key)) {
444 if (metadata.exists("TIMESYS")) {
445 auto timesysName = boost::algorithm::trim_right_copy(metadata.getAsString("TIMESYS"));
446 if (timesysName != "TAI") {
447 // rather than try to deal with all the possible choices, which requires
448 // appending or deleting a "Z", depending on the time system, just give up.
449 // VisitInfo should be used on FITS headers that have been sanitized!
451 os << "TIMESYS = \"" << timesysName
452 << "\"; VisitInfo requires TIMESYS to exist and to equal \"TAI\"";
454 }
455 } else {
457 "TIMESYS not found; VistitInfo requires TIMESYS to exist and to equal \"TAI\"");
458 }
459 _date = ::DateTime(boost::algorithm::trim_right_copy(metadata.getAsString(key)), ::DateTime::TAI);
460 } else {
461 // DATE-AVG not found. For backwards compatibility look for TIME-MID, an outdated LSST keyword
462 // whose time system was UTC, despite a FITS comment claiming it was TAI. Ignore TIMESYS.
463 key = "TIME-MID";
464 if (metadata.exists(key)) {
465 _date = ::DateTime(boost::algorithm::trim_right_copy(metadata.getAsString(key)), ::DateTime::UTC);
466 }
467 }
468
469 key = "ROTTYPE";
470 if (metadata.exists(key)) {
471 _rotType = rotTypeEnumFromStr(metadata.getAsString(key));
472 }
473}
474
481bool _eqOrNan(double lhs, double rhs) noexcept { return (std::isnan(lhs) && std::isnan(rhs)) || lhs == rhs; }
482
490 return (!lhs.isFinite() && !rhs.isFinite()) || lhs == rhs;
491}
492
493bool VisitInfo::operator==(VisitInfo const& other) const {
494 return _exposureId == other.getExposureId() && _eqOrNan(_exposureTime, other.getExposureTime()) &&
495 _eqOrNan(_darkTime, other.getDarkTime()) && _date == other.getDate() &&
496 _eqOrNan(_ut1, other.getUt1()) && _eqOrNan(_era, other.getEra()) &&
497 _eqOrNonFinite(_boresightRaDec, other.getBoresightRaDec()) &&
498 _eqOrNonFinite(_boresightAzAlt, other.getBoresightAzAlt()) &&
499 _eqOrNan(_boresightAirmass, other.getBoresightAirmass()) &&
500 _eqOrNan(_boresightRotAngle, other.getBoresightRotAngle()) && _rotType == other.getRotType() &&
501 _observatory == other.getObservatory() && _weather == other.getWeather() &&
502 _instrumentLabel == other.getInstrumentLabel() && _id == other.getId();
503}
504
506 // Completely arbitrary seed
507 return utils::hashCombine(17, _exposureId, _exposureTime, _darkTime, _date, _ut1, _era, _boresightRaDec,
508 _boresightAzAlt, _boresightAirmass, _boresightRotAngle, _rotType, _observatory,
509 _weather, _instrumentLabel, _id);
510}
511
512std::string VisitInfo::getPersistenceName() const { return getVisitInfoPersistenceName(); }
513
515 VisitInfoSchema const& keys = VisitInfoSchema::get();
516 table::BaseCatalog cat = handle.makeCatalog(keys.schema);
518 record->set(keys.exposureId, getExposureId());
519 record->set(keys.exposureTime, getExposureTime());
520 record->set(keys.darkTime, getDarkTime());
521 record->set(keys.tai, getDate().nsecs(::DateTime::TAI));
522 record->set(keys.ut1, getUt1());
523 record->set(keys.era, getEra());
524 record->set(keys.boresightRaDec, getBoresightRaDec());
525 auto boresightAzAlt = getBoresightAzAlt();
526 record->set(keys.boresightAzAlt_az, boresightAzAlt[0]);
527 record->set(keys.boresightAzAlt_alt, boresightAzAlt[1]);
528 record->set(keys.boresightAirmass, getBoresightAirmass());
529 record->set(keys.boresightRotAngle, getBoresightRotAngle());
530 record->set(keys.rotType, static_cast<int>(getRotType()));
531 auto observatory = getObservatory();
532 record->set(keys.latitude, observatory.getLatitude());
533 record->set(keys.longitude, observatory.getLongitude());
534 record->set(keys.elevation, observatory.getElevation());
535 auto weather = getWeather();
536 record->set(keys.airTemperature, weather.getAirTemperature());
537 record->set(keys.airPressure, weather.getAirPressure());
538 record->set(keys.humidity, weather.getHumidity());
539 record->set(keys.instrumentLabel, getInstrumentLabel());
540 record->set(keys.version, SERIALIZATION_VERSION);
541 record->set(keys.idnum, getId());
542 handle.saveCatalog(cat);
543}
544
546
548
554 double _parallactic_y, _parallactic_x, result;
555 _parallactic_y = sin(getBoresightHourAngle().asRadians());
556 _parallactic_x =
557 cos((getBoresightRaDec()[1]).asRadians()) * tan(getObservatory().getLatitude().asRadians()) -
558 sin((getBoresightRaDec()[1]).asRadians()) * cos(getBoresightHourAngle().asRadians());
559 result = atan2(_parallactic_y, _parallactic_x);
561}
562
564 return std::make_unique<VisitInfo>(*this);
565}
566
567bool VisitInfo::equals(typehandling::Storable const& other) const noexcept {
568 return singleClassEquals(*this, other);
569}
570
572 std::stringstream buffer;
573 buffer << "VisitInfo(";
574 buffer << "exposureId=" << getExposureId() << ", ";
575 buffer << "exposureTime=" << getExposureTime() << ", ";
576 buffer << "darkTime=" << getDarkTime() << ", ";
577 buffer << "date=" << (getDate().isValid() ? getDate().toString(daf::base::DateTime::TAI) : "<invalid>")
578 << ", ";
579 buffer << "UT1=" << getUt1() << ", ";
580 buffer << "ERA=" << getEra() << ", ";
581 buffer << "boresightRaDec=" << getBoresightRaDec() << ", ";
582 buffer << "boresightAzAlt=" << getBoresightAzAlt() << ", ";
583 buffer << "boresightAirmass=" << getBoresightAirmass() << ", ";
584 buffer << "boresightRotAngle=" << getBoresightRotAngle() << ", ";
585 buffer << "rotType=" << static_cast<int>(getRotType()) << ", ";
586 buffer << "observatory=" << getObservatory() << ", ";
587 buffer << "weather=" << getWeather() << ", ";
588 buffer << "instrumentLabel='" << getInstrumentLabel() << "', ";
589 buffer << "id=" << getId();
590 buffer << ")";
591 return buffer.str();
592}
593
595 os << visitInfo.toString();
596 return os;
597}
598
599} // namespace image
600} // namespace afw
601} // namespace lsst
py::object result
Definition: _schema.cc:429
table::Key< std::string > name
Definition: Amplifier.cc:116
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
table::Key< double > angle
std::ostream * os
Definition: Schema.cc:557
table::Key< lsst::geom::Angle > longitude
Definition: VisitInfo.cc:213
table::Key< lsst::geom::Angle > latitude
Definition: VisitInfo.cc:212
table::Key< lsst::geom::Angle > boresightAzAlt_az
Definition: VisitInfo.cc:206
table::Schema schema
Definition: VisitInfo.cc:198
table::Key< double > exposureTime
Definition: VisitInfo.cc:200
table::Key< lsst::geom::Angle > era
Definition: VisitInfo.cc:204
table::Key< double > airPressure
Definition: VisitInfo.cc:217
table::Key< lsst::geom::Angle > boresightAzAlt_alt
Definition: VisitInfo.cc:207
table::Key< int > rotType
Definition: VisitInfo.cc:210
table::Key< double > darkTime
Definition: VisitInfo.cc:201
table::Key< table::RecordId > idnum
Definition: VisitInfo.cc:223
table::Key< std::string > instrumentLabel
Definition: VisitInfo.cc:220
table::CoordKey boresightRaDec
Definition: VisitInfo.cc:205
table::Key< double > boresightAirmass
Definition: VisitInfo.cc:208
table::Key< double > airTemperature
Definition: VisitInfo.cc:216
table::Key< std::int64_t > tai
Definition: VisitInfo.cc:202
table::Key< double > elevation
Definition: VisitInfo.cc:214
table::Key< double > humidity
Definition: VisitInfo.cc:218
table::Key< int > version
Definition: VisitInfo.cc:221
table::Key< lsst::geom::Angle > boresightRotAngle
Definition: VisitInfo.cc:209
table::Key< double > ut1
Definition: VisitInfo.cc:203
table::Key< table::RecordId > exposureId
Definition: VisitInfo.cc:199
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
Definition: Persistable.h:48
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:512
daf::base::DateTime getDate() const
get uniform date and time at middle of exposure
Definition: VisitInfo.h:147
coord::Weather getWeather() const
get basic weather information
Definition: VisitInfo.h:182
lsst::geom::Angle getLocalEra() const
Definition: VisitInfo.cc:545
double getUt1() const
get UT1 (universal time) MJD date at middle of exposure
Definition: VisitInfo.h:150
double getBoresightAirmass() const
get airmass at the boresight, relative to zenith at sea level (and at the middle of the exposure,...
Definition: VisitInfo.h:165
lsst::geom::Angle getBoresightHourAngle() const
Definition: VisitInfo.cc:547
lsst::geom::Angle getBoresightRotAngle() const
Get rotation angle at boresight at middle of exposure.
Definition: VisitInfo.h:173
table::RecordId getExposureId() const
get exposure ID
Definition: VisitInfo.h:136
std::size_t hash_value() const noexcept override
Return a hash of this object.
Definition: VisitInfo.cc:505
bool operator==(VisitInfo const &other) const
Definition: VisitInfo.cc:493
lsst::geom::Angle getEra() const
get earth rotation angle at middle of exposure
Definition: VisitInfo.h:153
table::RecordId getId() const
Definition: VisitInfo.h:194
std::string toString() const override
Create a string representation of this object.
Definition: VisitInfo.cc:571
double getExposureTime() const
get exposure duration (shutter open time); (sec)
Definition: VisitInfo.h:141
RotType getRotType() const
get rotation type of boresightRotAngle
Definition: VisitInfo.h:176
bool equals(typehandling::Storable const &other) const noexcept override
Compare this object to another Storable.
Definition: VisitInfo.cc:567
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:161
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:157
std::shared_ptr< typehandling::Storable > cloneStorable() const override
Create a new VisitInfo that is a copy of this one.
Definition: VisitInfo.cc:563
std::string getInstrumentLabel() const
Definition: VisitInfo.h:192
double getDarkTime() const
get time from CCD flush to exposure readout, including shutter open time (despite the name); (sec)
Definition: VisitInfo.h:144
coord::Observatory getObservatory() const
get observatory longitude, latitude and elevation
Definition: VisitInfo.h:179
lsst::geom::Angle getBoresightParAngle() const
Get parallactic angle at the boresight.
Definition: VisitInfo.cc:549
void write(OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
Definition: VisitInfo.cc:514
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
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
Class for handling dates/times, including MJD, UTC, and TAI.
Definition: DateTime.h:64
std::string toString(Timescale scale) const
Get date as an ISO8601-formatted string.
Definition: DateTime.cc:500
bool isValid() const
Is this date valid?
Definition: DateTime.h:203
double get(DateSystem system=MJD, Timescale scale=TAI) const
Get date as a double in a specified representation, such as MJD.
Definition: DateTime.cc:430
Class for storing ordered metadata with comments.
Definition: PropertyList.h:68
void set(std::string const &name, T const &value)
Replace all values for a property name (possibly hierarchical) with a new scalar value.
Class for storing generic metadata.
Definition: PropertySet.h:66
std::string getAsString(std::string const &name) const
Get the last value for a string property name (possibly hierarchical).
virtual void remove(std::string const &name)
Remove all values for a property name (possibly hierarchical).
int64_t getAsInt64(std::string const &name) const
Get the last value for a bool/char/short/int/int64_t property name (possibly hierarchical).
bool exists(std::string const &name) const
Determine if a name (possibly hierarchical) exists.
double getAsDouble(std::string const &name) const
Get the last value for any arithmetic property name (possibly hierarchical).
A class representing an angle.
Definition: Angle.h:128
Point in an unspecified spherical coordinate system.
Definition: SpherePoint.h:57
Reports errors that are due to events beyond the control of the program.
Definition: Runtime.h:104
Reports errors from accepting an object of an unexpected or inappropriate type.
Definition: Runtime.h:167
T empty(T... args)
T isfinite(T... args)
T isnan(T... args)
int stripVisitInfoKeywords(daf::base::PropertySet &metadata)
Remove VisitInfo-related keywords from the metadata.
Definition: VisitInfo.cc:346
void setVisitInfoMetadata(daf::base::PropertyList &metadata, VisitInfo const &visitInfo)
Set FITS metadata from a VisitInfo.
Definition: VisitInfo.cc:363
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
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:489
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:481
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
std::size_t hashCombine(std::size_t seed) noexcept
Combine hashes.
Definition: hashCombine.h:35
constexpr AngleUnit degrees
constant with units of degrees
Definition: Angle.h:110
constexpr AngleUnit radians
constant with units of radians
Definition: Angle.h:109
double sin(Angle const &a)
Definition: Angle.h:102
double tan(Angle const &a)
Definition: Angle.h:104
double cos(Angle const &a)
Definition: Angle.h:103
A base class for image defects.
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