Skip to content

Commit

Permalink
Merge pull request #559 from lsst/tickets/DM-27174
Browse files Browse the repository at this point in the history
DM-27174: Create InstrumentLabel class for ExposureInfo
  • Loading branch information
parejkoj committed Jan 25, 2021
2 parents 7bed000 + 081166f commit 68cce58
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 65 deletions.
10 changes: 8 additions & 2 deletions include/lsst/afw/image/VisitInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,15 @@ class VisitInfo : public table::io::PersistableFacade<VisitInfo>, public typehan
* @param[in] rotType rotation type
* @param[in] observatory observatory longitude, latitude and altitude
* @param[in] weather basic weather information for computing air mass
* @param[in] instrumentLabel The short name of the instrument that took this data (e.g. "HSC")
*/
explicit VisitInfo(table::RecordId exposureId, double exposureTime, double darkTime,
daf::base::DateTime const &date, double ut1, lsst::geom::Angle const &era,
lsst::geom::SpherePoint const &boresightRaDec,
lsst::geom::SpherePoint const &boresightAzAlt, double boresightAirmass,
lsst::geom::Angle const &boresightRotAngle, RotType const &rotType,
coord::Observatory const &observatory, coord::Weather const &weather)
coord::Observatory const &observatory, coord::Weather const &weather,
std::string const &instrumentLabel)
: _exposureId(exposureId),
_exposureTime(exposureTime),
_darkTime(darkTime),
Expand All @@ -104,7 +106,8 @@ class VisitInfo : public table::io::PersistableFacade<VisitInfo>, public typehan
_boresightRotAngle(boresightRotAngle),
_rotType(rotType),
_observatory(observatory),
_weather(weather){};
_weather(weather),
_instrumentLabel(instrumentLabel){};

explicit VisitInfo(daf::base::PropertySet const &metadata);

Expand Down Expand Up @@ -176,6 +179,8 @@ class VisitInfo : public table::io::PersistableFacade<VisitInfo>, public typehan
// get hour angle at the boresight
lsst::geom::Angle getBoresightHourAngle() const;

std::string getInstrumentLabel() const { return _instrumentLabel; }

/**
* Get parallactic angle at the boresight
*
Expand Down Expand Up @@ -219,6 +224,7 @@ class VisitInfo : public table::io::PersistableFacade<VisitInfo>, public typehan
RotType _rotType;
coord::Observatory _observatory;
coord::Weather _weather;
std::string _instrumentLabel;
};

std::ostream &operator<<(std::ostream &os, VisitInfo const &visitInfo);
Expand Down
12 changes: 7 additions & 5 deletions python/lsst/afw/image/visitInfo.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,16 @@ PYBIND11_MODULE(visitInfo, mod) {

/* Constructors */
cls.def(py::init<table::RecordId, double, double, daf::base::DateTime const &, double,
lsst::geom::Angle const &, lsst::geom::SpherePoint const &, lsst::geom::SpherePoint const &, double,
lsst::geom::Angle const &, RotType const &, coord::Observatory const &,
coord::Weather const &>(),
lsst::geom::Angle const &, lsst::geom::SpherePoint const &,
lsst::geom::SpherePoint const &, double, lsst::geom::Angle const &, RotType const &,
coord::Observatory const &, coord::Weather const &, std::string const &>(),
"exposureId"_a = 0, "exposureTime"_a = nan, "darkTime"_a = nan, "date"_a = daf::base::DateTime(),
"ut1"_a = nan, "era"_a = nanAngle, "boresightRaDec"_a = lsst::geom::SpherePoint(nanAngle, nanAngle),
"ut1"_a = nan, "era"_a = nanAngle,
"boresightRaDec"_a = lsst::geom::SpherePoint(nanAngle, nanAngle),
"boresightAzAlt"_a = lsst::geom::SpherePoint(nanAngle, nanAngle), "boresightAirmass"_a = nan,
"boresightRotAngle"_a = nanAngle, "rotType"_a = RotType::UNKNOWN,
"observatory"_a = coord::Observatory(nanAngle, nanAngle, nan),
"weather"_a = coord::Weather(nan, nan, nan));
"weather"_a = coord::Weather(nan, nan, nan), "instrumentLabel"_a = "");
cls.def(py::init<daf::base::PropertySet const &>(), "metadata"_a);
cls.def(py::init<VisitInfo const &>(), "visitInfo"_a);

Expand Down Expand Up @@ -110,6 +111,7 @@ PYBIND11_MODULE(visitInfo, mod) {
cls.def("isPersistable", &VisitInfo::isPersistable);
cls.def("getLocalEra", &VisitInfo::getLocalEra);
cls.def("getBoresightHourAngle", &VisitInfo::getBoresightHourAngle);
cls.def("getInstrumentLabel", &VisitInfo::getInstrumentLabel);

utils::python::addOutputOp(cls, "__str__");

Expand Down
63 changes: 53 additions & 10 deletions src/image/VisitInfo.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@ lsst::geom::Angle getAngle(daf::base::PropertySet const& metadata, std::string c
return getDouble(metadata, key) * lsst::geom::degrees;
}

/**
* @internal Get a specified string from a PropertySet, or "" if not present.
*
* @param[in] metadata metadata to get
* @param[in] key key name; the associated value must be of type string if the key exists.
* @returns value of metadata for the specified key, as a string,
* with a value of "" if the key is not present.
*/
std::string getString(daf::base::PropertySet const& metadata, std::string const& key) {
return metadata.exists(key) ? metadata.getAsString(key) : "";
}

/**
* @internal Set a specified double in a PropertySet, if value is finite
*
Expand Down Expand Up @@ -111,6 +123,23 @@ bool setAngle(daf::base::PropertySet& metadata, std::string const& key, lsst::ge
return setDouble(metadata, key, angle.asDegrees(), comment);
}

/**
* @internal Set a specified string in a PropertySet, if value is non-empty.
*
* @param[in,out] metadata metadata to set
* @param[in] key name of key to set
* @param[in] value value of key
* @returns true if item set, false otherwise
*/
bool setString(daf::base::PropertySet& metadata, std::string const& key, std::string value,
std::string const& comment) {
if (!value.empty()) {
metadata.set(key, value);
return true;
}
return false;
}

/**
* @internal Get rotation type as a string to use for a for FITS keyword value, given an enum
*
Expand Down Expand Up @@ -176,6 +205,8 @@ class VisitInfoSchema {
table::Key<double> airPressure;
table::Key<double> humidity;

table::Key<std::string> instrumentLabel;

static VisitInfoSchema const& get() {
static VisitInfoSchema instance;
return instance;
Expand Down Expand Up @@ -221,10 +252,14 @@ class VisitInfoSchema {
"latitude", "latitude of telescope (+ is east of Greenwich)", "")),
longitude(schema.addField<lsst::geom::Angle>("longitude", "longitude of telescope", "")),
elevation(schema.addField<double>("elevation", "elevation of telescope", "")),

// weather data
airTemperature(schema.addField<double>("airtemperature", "air temperature", "C")),
airPressure(schema.addField<double>("airpressure", "air pressure", "Pascal")),
humidity(schema.addField<double>("humidity", "humidity (%)", "")) {}
humidity(schema.addField<double>("humidity", "humidity (%)", "")),

instrumentLabel(schema.addField<std::string>(
"instrumentlabel", "Short name of the instrument that took this data", "", 0)) {}
};

class VisitInfoFactory : public table::io::PersistableFactory {
Expand All @@ -247,7 +282,8 @@ class VisitInfoFactory : public table::io::PersistableFactory {
coord::Observatory(record.get(keys.longitude), record.get(keys.latitude),
record.get(keys.elevation)),
coord::Weather(record.get(keys.airTemperature), record.get(keys.airPressure),
record.get(keys.humidity))));
record.get(keys.humidity)),
record.get(keys.instrumentLabel)));
return result;
}

Expand All @@ -265,10 +301,11 @@ namespace detail {
int stripVisitInfoKeywords(daf::base::PropertySet& metadata) {
int nstripped = 0;

std::vector<std::string> keyList = {
"EXPID", "EXPTIME", "DARKTIME", "DATE-AVG", "TIMESYS", "TIME-MID", "MJD-AVG-UT1",
"AVG-ERA", "BORE-RA", "BORE-DEC", "BORE-AZ", "BORE-ALT", "BORE-AIRMASS", "BORE-ROTANG",
"ROTTYPE", "OBS-LONG", "OBS-LAT", "OBS-ELEV", "AIRTEMP", "AIRPRESS", "HUMIDITY"};
std::vector<std::string> keyList = {"EXPID", "EXPTIME", "DARKTIME", "DATE-AVG", "TIMESYS",
"TIME-MID", "MJD-AVG-UT1", "AVG-ERA", "BORE-RA", "BORE-DEC",
"BORE-AZ", "BORE-ALT", "BORE-AIRMASS", "BORE-ROTANG", "ROTTYPE",
"OBS-LONG", "OBS-LAT", "OBS-ELEV", "AIRTEMP", "AIRPRESS",
"HUMIDITY", "INSTRUMENT"};
for (auto&& key : keyList) {
if (metadata.exists(key)) {
metadata.remove(key);
Expand Down Expand Up @@ -308,6 +345,8 @@ void setVisitInfoMetadata(daf::base::PropertyList& metadata, VisitInfo const& vi
setDouble(metadata, "AIRTEMP", weather.getAirTemperature(), "Outside air temperature (C)");
setDouble(metadata, "AIRPRESS", weather.getAirPressure(), "Outdoor air pressure (P)");
setDouble(metadata, "HUMIDITY", weather.getHumidity(), "Relative humidity (%)");
setString(metadata, "INSTRUMENT", visitInfo.getInstrumentLabel(),
"Short name of the instrument that took this data");
}

} // namespace detail
Expand All @@ -329,7 +368,8 @@ VisitInfo::VisitInfo(daf::base::PropertySet const& metadata)
_observatory(getAngle(metadata, "OBS-LONG"), getAngle(metadata, "OBS-LAT"),
getDouble(metadata, "OBS-ELEV")),
_weather(getDouble(metadata, "AIRTEMP"), getDouble(metadata, "AIRPRESS"),
getDouble(metadata, "HUMIDITY")) {
getDouble(metadata, "HUMIDITY")),
_instrumentLabel(getString(metadata, "INSTRUMENT")) {
auto key = "EXPID";
if (metadata.exists(key)) {
_exposureId = metadata.getAsInt64(key);
Expand Down Expand Up @@ -385,14 +425,15 @@ bool VisitInfo::operator==(VisitInfo const& other) const {
_era == other.getEra() && _boresightRaDec == other.getBoresightRaDec() &&
_boresightAzAlt == other.getBoresightAzAlt() && _boresightAirmass == other.getBoresightAirmass() &&
_boresightRotAngle == other.getBoresightRotAngle() && _rotType == other.getRotType() &&
_observatory == other.getObservatory() && _weather == other.getWeather();
_observatory == other.getObservatory() && _weather == other.getWeather() &&
_instrumentLabel == other.getInstrumentLabel();
}

std::size_t VisitInfo::hash_value() const noexcept {
// Completely arbitrary seed
return utils::hashCombine(17, _exposureId, _exposureTime, _darkTime, _date, _ut1, _era, _boresightRaDec,
_boresightAzAlt, _boresightAirmass, _boresightRotAngle, _rotType, _observatory,
_weather);
_weather, _instrumentLabel);
}

std::string VisitInfo::getPersistenceName() const { return getVisitInfoPersistenceName(); }
Expand Down Expand Up @@ -422,6 +463,7 @@ void VisitInfo::write(OutputArchiveHandle& handle) const {
record->set(keys.airTemperature, weather.getAirTemperature());
record->set(keys.airPressure, weather.getAirPressure());
record->set(keys.humidity, weather.getHumidity());
record->set(keys.instrumentLabel, getInstrumentLabel());
handle.saveCatalog(cat);
}

Expand Down Expand Up @@ -466,7 +508,8 @@ std::string VisitInfo::toString() const {
buffer << "boresightRotAngle=" << getBoresightRotAngle() << ", ";
buffer << "rotType=" << static_cast<int>(getRotType()) << ", ";
buffer << "observatory=" << getObservatory() << ", ";
buffer << "weather=" << getWeather();
buffer << "weather=" << getWeather() << ", ";
buffer << "instrumentLabel=" << getInstrumentLabel();
buffer << ")";
return buffer.str();
}
Expand Down
1 change: 1 addition & 0 deletions tests/test_exposureTable.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ def createVisitInfo():
lsst.afw.image.RotType.SKY,
Observatory(11.1*degrees, 22.2*degrees, 0.333),
Weather(1.1, 2.2, 34.5),
"testCam"
)

@staticmethod
Expand Down
4 changes: 2 additions & 2 deletions tests/test_imageHash.cc
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,12 @@ BOOST_AUTO_TEST_CASE(VisitInfoHash) {
45.1 * degrees, lsst::geom::SpherePoint(23.1 * degrees, 73.2 * degrees),
lsst::geom::SpherePoint(134.5 * degrees, 33.3 * degrees), 1.73, 73.2 * degrees,
RotType::SKY, coord::Observatory(11.1 * degrees, 22.2 * degrees, 0.333),
coord::Weather(1.1, 2.2, 34.5));
coord::Weather(1.1, 2.2, 34.5), "testCam1");
VisitInfo info2(10313423, 10.01, 11.02, DateTime(65321.1, DateTime::MJD, DateTime::TAI), 12345.1,
45.1 * degrees, lsst::geom::SpherePoint(23.1 * degrees, 73.2 * degrees),
lsst::geom::SpherePoint(134.5 * degrees, 33.3 * degrees), 1.73, 73.2 * degrees,
RotType::SKY, coord::Observatory(11.1 * degrees, 22.2 * degrees, 0.333),
coord::Weather(1.1, 2.2, 34.5));
coord::Weather(1.1, 2.2, 34.5), "testCam1");

utils::assertHashesEqual(info1, info2);
}
Expand Down

0 comments on commit 68cce58

Please sign in to comment.