#ifndef __JDETECTOR__JDETECTORCALIBRATION__ #define __JDETECTOR__JDETECTORCALIBRATION__ #include #include #include "JSon/JSon.hh" #include "JDB/JPBS_t.hh" #include "JDB/JUPI_t.hh" #include "JLang/JObjectID.hh" #include "JLang/JException.hh" #include "Jeep/JPrint.hh" #include "Jeep/JStatus.hh" #include "JDetector/JCalibration.hh" #include "JGeometry3D/JPosition3D.hh" #include "JGeometry3D/JQuaternion3D.hh" /** * \author mdejong, bjung, acreusot */ namespace JDETECTOR {} namespace JPP { using namespace JDETECTOR; } /** * Auxiliary classes and methods for detector calibration. */ namespace JDETECTOR { using JSON::json; using JLANG::JObjectID; using JLANG::JValueOutOfRange; using JLANG::JNoValue; using JDATABASE::JUPI_t; using JDATABASE::JPBS_t; using JEEP::JStatus; using JGEOMETRY3D::JPosition3D; using JGEOMETRY3D::JQuaternion3D; static const std::string TCAL = "tcal"; //!< PMT time offsets static const std::string PCAL = "pcal"; //!< (optical|base) module positions static const std::string RCAL = "rcal"; //!< (optical|base) module orientations static const std::string ACAL = "acal"; //!< acoustic time offsets (piezo sensor or hydrophone) static const std::string CCAL = "ccal"; //!< compass alignment (a.k.a.\ quaternion calibration) static const std::string SCAL = "scal"; //!< PMT status /** * Detector calibration key words for JSON I/O. */ // Meta data static const std::string User_t = "User"; static const std::string Location_t = "Location"; static const std::string Time_t = "Time"; static const std::string Start_t = "Start"; static const std::string End_t = "End"; static const std::string Comment_t = "Comment"; static const std::string Encoding_t = "Encoding"; static const std::string Input_t = "Inputs"; static const std::string Error_t = "Error"; static const std::string Message_t = "Message"; static const std::string Code_t = "Code"; static const std::string Provenance_t = "Provenance"; static const std::string Info_t = "Info"; static const std::string Configuration_t = "Configuration"; static const std::string Arguments_t = "Arguments"; static const std::string Inputs_t = "Inputs"; static const std::string UUID_t = "UUID"; static const std::string APIVersion_t = "APIVersion"; static const std::string Result_t = "Result"; static const std::string OK_t = "OK"; static const std::string Fail_t = "FAIL"; // Type specifiers static const std::string Type_t = "Type"; static const std::string Test_t = "Test"; static const std::string Tests_t = "Tests"; static const std::string Data_t = "Data"; static const std::string URL_t = "URL"; static const std::string Name_t = "Name"; static const std::string Unit_t = "Unit"; static const std::string Values_t = "Values"; static const std::string Parameters_t = "Parameters"; static const std::string RunNumber_t = "RUN_NUMBER"; // Calibration types static const std::string PMTT0s_t = "PMTT0s"; static const std::string PMTStatusInfo_t = "PMTStatusInfo"; static const std::string PMTSupplyVoltage_t = "PMT_Supply_Voltage"; static const std::string PMTThreshold_t = "PMT_Threshold"; static const std::string DOMPositions_t = "DOMPositions"; static const std::string DOMRotations_t = "DOMRotations"; static const std::string DOMAcousticT0_t = "DOMAcousticT0s"; static const std::string DOMCompassRotations_t = "DOMCompassRotations"; static const std::string DOMStatusInfo_t = "DOMStatusInfo"; static const std::string PMTGain_t = "PMT_Gain"; static const std::string BasePositions_t = "BasePositions"; static const std::string BaseRotations_t = "BaseRotations"; static const std::string BaseStatusInfo_t = "BaseStatusInfo"; // Identifiers static const std::string UPI_t = "UPI"; static const std::string PBS_t = "PBS"; static const std::string Variant_t = "Variant"; static const std::string DetOID_t = "DetOID"; static const std::string DetID_t = "DetID"; static const std::string PMTSerial_t = "Serial"; static const std::string DOMSerial_t = "DOMSerial"; static const std::string DOMId_t = "DOMId"; static const std::string Id_t = "Id"; // Variable names static const std::string T0_t = "T0"; static const std::string PX_t = "PX"; static const std::string PY_t = "PY"; static const std::string PZ_t = "PZ"; static const std::string Q0_t = "Q0"; static const std::string QX_t = "QX"; static const std::string QY_t = "QY"; static const std::string QZ_t = "QZ"; static const std::string STATUS_t = "Status"; // Units static const std::string Unitless_t = "-"; static const std::string Volt_t = "V"; /** * Check validity of JSon data. * * \param js JSon data * \return true if valid; else false */ inline bool is_valid(const json& js) { return ((js.contains(Result_t) && js[Result_t] == OK_t) || (js.contains(Error_t) && js[Error_t][Code_t] == OK_t)); } /** * Cast single value to array of strings, conform the DB-format. * * \param value value * \return std::vector containing value casted to string */ template inline std::vector get_string_array(T value) { using namespace std; return vector{ to_string(value) }; } /** * Retrieve value from json array of strings. * * \param string_value_array array of string-casted values * \return double-casted value */ inline double retrieve_value(std::vector string_value_array) { return std::stod(string_value_array[0]); } /** * Auxiliary data structure for PMT time calibration. */ struct JPMTCalibration_t : public JObjectID, public JCalibration { /** * Default constructor. */ JPMTCalibration_t() {} /** * Constructor. * * \param id PMT identifier * \param calibration PMT time calibration */ JPMTCalibration_t(const JObjectID& id, const JCalibration& calibration) : JObjectID (id), JCalibration(calibration) {} }; /** * Convert PMT time calibration to JSon. * * \param js json * \param object PMT time calibration */ inline void to_json(json& js, const JPMTCalibration_t& object) { js = json{ { PMTSerial_t, object.getID() }, { T0_t, object.getT0() } }; } /** * Convert JSon to PMT time calibration. * * \param js json * \param object PMT time calibration */ inline void from_json(const json& js, JPMTCalibration_t& object) { object.setID(js.at(PMTSerial_t).get()); object.setT0(js.at(T0_t).get()); } /** * Auxiliary data structure for PMT status. */ struct JPMTStatus_t : public JObjectID, public JStatus { /** * Default constructor. */ JPMTStatus_t() {} /** * Constructor. * * \param id PMT identifier * \param status PMT status */ JPMTStatus_t(const JObjectID& id, const JStatus& status) : JObjectID(id), JStatus (status) {} }; /** * Convert PMT status to JSon. * * \param js json * \param object PMT status */ inline void to_json(json& js, const JPMTStatus_t& object) { js = json{ { PMTSerial_t, object.getID() }, { STATUS_t, object.getStatus() } }; } /** * Convert JSon to PMT status. * * \param js json * \param object PMT status */ inline void from_json(const json& js, JPMTStatus_t& object) { object.setID(js.at(PMTSerial_t).get()); object.setStatus(js.at(STATUS_t).get()); } /** * Data structure for PMT high-voltage calibration. */ struct JHVCalibration_t : public JUPI_t { /** * Default constructor. */ JHVCalibration_t() : JUPI_t (), result (Fail_t), supplyVoltage(0.0), runNumbers (std::vector(0)), PMTgain (0.0) {} /** * Constructor. * * \param upi %UPI * \param result result * \param hv HV * \param runNumberList run numbers * \param gain gain */ JHVCalibration_t(const JUPI_t& upi, const std::string& result, const double hv, const std::vector runNumberList = std::vector(0), const double gain = 1.0) : JUPI_t (upi), result (result), supplyVoltage(hv), runNumbers (runNumberList), PMTgain (gain) {} /** * Get HV-tuning database test type. * * \return HV-tuning database test type */ static int getVersion() { return get_version(); } /** * Set HV-tuning database test type. * * \param version HV-tuning database test type */ static void setVersion(const int version) { get_version() = version; } std::string result; double supplyVoltage; std::vector runNumbers; double PMTgain; private: /** * Get reference to HV-tuning database test type. * * \return HV-tuning database test type */ static int& get_version() { static int version = 3; return version; } }; /** * Convert PMT high-voltage calibration to JSon. * * \param js json2 * \param object PMT high-voltage calibration */ inline void to_json(json& js, const JHVCalibration_t& object) { using namespace std; ostringstream os; os << object.getUPI(); js[UPI_t] = os.str(); js[Test_t + Result_t] = object.result; js[Test_t + Parameters_t][0] = json{ { Name_t, PMTSupplyVoltage_t }, { Unit_t, Volt_t }, { Values_t, get_string_array(object.supplyVoltage) } }; static const int version = JHVCalibration_t::getVersion(); if (version < 2) { js[Test_t + Parameters_t][2] = json{ { Name_t, PMTGain_t }, { Unit_t, Unitless_t }, { Values_t, get_string_array(object.PMTgain) } }; } if (version < 3) { vector runNumberList; for (vector::const_iterator i = object.runNumbers.cbegin(); i != object.runNumbers.cend(); ++i) { runNumberList.push_back(to_string(*i)); } js[Test_t + Parameters_t][1] = json{ { Name_t, RunNumber_t }, { Unit_t, Unitless_t }, { Values_t, runNumberList } }; } } /** * Convert JSon to PMT high-voltage calibration. * * \param js json * \param object PMT high-voltage calibration */ inline void from_json(const json& js, JHVCalibration_t& object) { using namespace std; stringstream is(js.at(UPI_t).get()); is >> static_cast(object); json parameters = js.at(Test_t + Parameters_t); if (JHVCalibration_t::getVersion() > 0 && parameters.size() > 0) { object.result = js.at(Test_t + Result_t).get(); object.supplyVoltage = retrieve_value(parameters[0].at(Values_t).get>()); if (JHVCalibration_t::getVersion() < 3 && parameters.size() > 1) { vector runNumberList = parameters[1].at(Values_t).get>(); for (vector::const_iterator i = runNumberList.begin(); i != runNumberList.end(); ++i) { object.runNumbers.push_back(stoi(*i)); } } if (JHVCalibration_t::getVersion() < 2 && parameters.size() > 2) { object.PMTgain = retrieve_value(parameters[2].at(Values_t).get>()); } } else { THROW(JValueOutOfRange, "JHVCalibration_t::from_json(): No " << MAKE_STRING(Test_t + Parameters_t) << " found." << endl); } } /** * Data structure for PMT threshold calibration. */ struct JPMTThresholdCalibration_t : public JUPI_t { /** * Default constructor. */ JPMTThresholdCalibration_t() {} /** * Constructor. * * \param upi %UPI * \param result result * \param threshold threshold * \param runNumbers run numbers */ JPMTThresholdCalibration_t(const JUPI_t& upi, const std::string& result, const double threshold, const std::vector& runNumbers = std::vector(0)) : JUPI_t (upi), result (result), threshold (threshold), runNumberList(runNumbers) {} std::string result; double threshold; std::vector runNumberList; }; /** * Convert PMT threshold calibration to JSon. * * \param js json * \param object PMT threshold calibration */ inline void to_json(json& js, const JPMTThresholdCalibration_t& object) { std::ostringstream os; os << object.getUPI(); js[UPI_t] = os.str(); js[Test_t + Result_t] = object.result; js[Test_t + Parameters_t][0] = json{ { Name_t, PMTThreshold_t }, { Unit_t, Unitless_t }, { Values_t, get_string_array(object.threshold) } }; js[Test_t + Parameters_t][2] = json{ { Name_t, RunNumber_t }, { Unit_t, Unitless_t }, { Values_t, object.runNumberList } }; } /** * Convert JSon to PMT threshold calibration. * * \param js json * \param object PMT threshold calibration */ inline void from_json(const json& js, JPMTThresholdCalibration_t& object) { using namespace std; stringstream is(js.at(UPI_t).get()); is >> static_cast(object); object.result = js.at(Test_t + Result_t).get(); object.threshold = retrieve_value(js.at(Test_t + Parameters_t)[0].at(Values_t).get>()); object.runNumberList = js.at(Test_t + Parameters_t)[2].at(Values_t).get>(); } /** * Auxiliary data structure for module position. */ struct JModulePosition_t : public JObjectID, public JPosition3D { /** * Default constructor. */ JModulePosition_t() {} /** * Constructor. * * \param id module identifier * \param position module position */ JModulePosition_t(const JObjectID& id, const JPosition3D& position) : JObjectID (id), JPosition3D(position) {} }; /** * Convert module position to JSon. * * \param js json * \param object module position */ inline void to_json(json& js, const JModulePosition_t& object) { js = json{ { Id_t, object.getID() }, { PX_t, object.getX() }, { PY_t, object.getY() }, { PZ_t, object.getZ() } }; } /** * Convert JSon to module position. * * \param js json * \param object module position */ inline void from_json(const json& js, JModulePosition_t& object) { if (js.contains(DOMId_t)) object.setID(js.at(DOMId_t).get()); else if (js.contains(Id_t)) object.setID(js.at(Id_t) .get()); else THROW(JNoValue, "Missing module identifier."); object.setPosition(JPosition3D(js.at(PX_t).get(), js.at(PY_t).get(), js.at(PZ_t).get())); } /** * Auxiliary data structure for module rotation. */ struct JModuleRotation_t : public JObjectID, public JQuaternion3D { /** * Default constructor. */ JModuleRotation_t() {} /** * Constructor. * * \param id module identifier * \param rotation module rotation */ JModuleRotation_t(const JObjectID& id, const JQuaternion3D& rotation) : JObjectID (id), JQuaternion3D(rotation) {} }; /** * Convert module rotation to JSon. * * \param js json * \param object module rotation */ inline void to_json(json& js, const JModuleRotation_t& object) { js = json{ { Id_t, object.getID() }, { Q0_t, object.getA() }, { QX_t, object.getB() }, { QY_t, object.getC() }, { QZ_t, object.getD() } }; } /** * Convert JSon to module rotation. * * \param js json * \param object module rotation */ inline void from_json(const json& js, JModuleRotation_t& object) { if (js.contains(DOMId_t)) object.setID(js.at(DOMId_t).get()); else if (js.contains(Id_t)) object.setID(js.at(Id_t) .get()); else THROW(JNoValue, "Missing module identifier."); object.setQuaternion(JQuaternion3D(js.at(Q0_t).get(), js.at(QX_t).get(), js.at(QY_t).get(), js.at(QZ_t).get())); } /** * Auxiliary data structure for module status. */ struct JModuleStatus_t : public JObjectID, public JStatus { /** * Default constructor. */ JModuleStatus_t() {} /** * Constructor. * * \param id module identifier * \param status module status */ JModuleStatus_t(const JObjectID& id, const JStatus& status) : JObjectID(id), JStatus (status) {} }; /** * Convert module status to JSon. * * \param js json * \param object module status */ inline void to_json(json& js, const JModuleStatus_t& object) { js = json{ { Id_t, object.getID() }, { STATUS_t, object.getStatus() } }; } /** * Convert JSon to module status. * * \param js json * \param object module status */ inline void from_json(const json& js, JModuleStatus_t& object) { if (js.contains(DOMId_t)) object.setID(js.at(DOMId_t).get()); else if (js.contains(Id_t)) object.setID(js.at(Id_t) .get()); else THROW(JNoValue, "Missing module identifier."); object.setStatus(js.at(STATUS_t).get()); } /** * Auxiliary data structure for module time calibration. */ struct JModuleCalibration_t : public JObjectID, public JCalibration { /** * Default constructor. */ JModuleCalibration_t() {} /** * Constructor. * * \param id module identifier * \param calibration module time calibration */ JModuleCalibration_t(const JObjectID& id, const JCalibration& calibration) : JObjectID (id), JCalibration(calibration) {} }; /** * Convert module time calibration to JSon. * * \param js json * \param object module time calibration */ inline void to_json(json& js, const JModuleCalibration_t& object) { js = json{ { Id_t, object.getID() }, { T0_t, object.getT0() } }; } /** * Convert JSon to module time calibration. * * \param js json * \param object module time calibration */ inline void from_json(const json& js, JModuleCalibration_t& object) { if (js.contains(DOMId_t)) object.setID(js.at(DOMId_t).get()); else if (js.contains(Id_t)) object.setID(js.at(Id_t) .get()); else THROW(JNoValue, "Missing module identifier."); object.setT0(js.at(T0_t).get()); } /** * Auxiliary data structure for compass rotation. */ struct JCompassRotation_t : public JObjectID, public JQuaternion3D { /** * Default constructor. */ JCompassRotation_t() {} /** * Constructor. * * \param id module identifier * \param rotation compass rotation */ JCompassRotation_t(const JObjectID& id, const JQuaternion3D& rotation) : JObjectID (id), JQuaternion3D(rotation) {} }; /** * Convert compass rotation to JSon. * * \param js json * \param object compass rotation */ inline void to_json(json& js, const JCompassRotation_t& object) { js = json{ { Id_t, object.getID() }, { Q0_t, object.getA() }, { QX_t, object.getB() }, { QY_t, object.getC() }, { QZ_t, object.getD() } }; } /** * Convert JSon to compass rotation. * * \param js json * \param object compass rotation */ inline void from_json(const json& js, JCompassRotation_t& object) { if (js.contains(DOMId_t)) object.setID(js.at(DOMId_t).get()); else if (js.contains(Id_t)) object.setID(js.at(Id_t) .get()); else THROW(JNoValue, "Missing module identifier."); object.setQuaternion(JQuaternion3D(js.at(Q0_t).get(), js.at(QX_t).get(), js.at(QY_t).get(), js.at(QZ_t).get())); } typedef std::vector JHVCalibration; //!< PMT high voltage calibration typedef std::vector JPMTThresholdCalibration; //!< PMT threshold calibration typedef std::vector JPMTCalibration; //!< PMT time calibration typedef std::vector JPMTStatus; //!< PMT status typedef std::vector JModulePosition; //!< Module position typedef std::vector JModuleRotation; //!< Module rotation typedef std::vector JModuleStatus; //!< Module status typedef std::vector JModuleCalibration; //!< Module time calibration typedef std::vector JCompassRotation; //!< Compass rotation } #endif