#ifndef __JDETECTOR__JDETECTORVERSION__ #define __JDETECTOR__JDETECTORVERSION__ #include #include #include #include #include #include "JIO/JSerialisable.hh" #include "JIO/JSTDIO.hh" #include "JLang/JType.hh" #include "JLang/JLangToolkit.hh" #include "JLang/JException.hh" #include "JLang/JVectorize.hh" #include "JDetector/JVersion.hh" #include "Jeep/JeepToolkit.hh" /** * \file * * Data structure for detector version. * \author mdejong */ namespace JDETECTOR {} namespace JPP { using namespace JDETECTOR; } namespace JDETECTOR { using JLANG::JType; using JLANG::JTypeInformationException; using JLANG::JIOException; using JIO::JReader; using JIO::JWriter; /** * Detector version. */ struct JDetectorVersion : public JVersion { /** * Enumeration of version types.\n * Note that additional version types should be included in JGetDetectorVersion::JGetDetectorVersion. */ enum JVersion_t { V1 = 1, //!< First version V2 = 2, //!< Version with UTC time and UTM position data V3 = 3, //!< Version with PMT status field and comments V4 = 4, //!< Version with quaternion and time offset per module V5 = 5 //!< Version with module status field }; /** * Default constructor. */ JDetectorVersion() : JVersion() {} /** * Constructor. * * \param version version */ JDetectorVersion(const JVersion& version) : JVersion(version) {} /** * Check validity of version. * * \return true if valid; else false */ bool hasVersion() const { return (!this->version.empty() && (this->version[0] == 'v' || this->version[0] == 'V')); } /** * Read version from input. * * \param in input stream * \param version version * \return input stream */ friend inline std::istream& operator>>(std::istream& in, JDetectorVersion& version) { return in >> version.version; } /** * Write version to output. * * \param out output stream * \param version version * \return output stream */ friend inline std::ostream& operator<<(std::ostream& out, const JDetectorVersion& version) { return out << version.version; } /** * Read version from input. * * \param in reader * \param version version * \return reader */ friend inline JReader& operator>>(JReader& in, JDetectorVersion& version) { return in >> version.version; } /** * Write version to output. * * \param out writer * \param version version * \return writer */ friend inline JWriter& operator<<(JWriter& out, const JDetectorVersion& version) { return out << version.version; } }; /** * Auxiliary class to map detector version to numerical value. */ struct JGetDetectorVersion : public std::map { /** * Default constructor. */ JGetDetectorVersion() { using namespace JPP; #define MAKE_ENTRY(A) std::make_pair(to_upper(getClassname(#A)), A) this->insert(MAKE_ENTRY(JDetectorVersion::V1)); this->insert(MAKE_ENTRY(JDetectorVersion::V2)); this->insert(MAKE_ENTRY(JDetectorVersion::V3)); this->insert(MAKE_ENTRY(JDetectorVersion::V4)); this->insert(MAKE_ENTRY(JDetectorVersion::V5)); #undef MAKE_ENTRY } /** * Get numerical value. * * \param version version * \return numerical value */ JDetectorVersion::JVersion_t operator()(const std::string& version) const { using namespace JPP; const_iterator i = this->find(to_upper(version)); if (i != this->end()) { return i->second; } else { THROW(JTypeInformationException, "Invalid version <" << version << ">"); } } /** * Get numerical value. * * \param version version * \return numerical value */ JDetectorVersion::JVersion_t operator()(const JDetectorVersion& version) const { return (*this)(version.getVersion()); } /** * Get index of detector version. * * \param version version * \return index */ int operator[](const std::string& version) const { using namespace std; using namespace JPP; const_iterator i = this->find(to_upper(version)); if (i != this->end()) return distance(this->begin(), i); else return -1; } /** * Get index of detector version. * * \param version version * \return index */ int operator[](const JDetectorVersion& version) const { return (*this)[version.getVersion()]; } /** * Get index of detector version. * * \param value numerical value * \return index */ int operator[](const JDetectorVersion::JVersion_t& value) const { using namespace std; for (const_iterator i = this->begin(); i != this->end(); ++i) { if (i->second == value) { return distance(this->begin(), i); } } return -1; } }; /** * Auxiliary class to map numerical value to detector version. */ struct JPutDetectorVersion : public std::map { /** * Constructor. * * \param input detector versions */ JPutDetectorVersion(const JGetDetectorVersion& input) { using namespace std; for (JGetDetectorVersion::const_iterator i = input.begin(); i != input.end(); ++i) { this->insert(make_pair(i->second, i->first)); } } /** * Put detector version. * * \param value numerical value * \return version */ const std::string& operator()(const JDetectorVersion::JVersion_t& value) const { const_iterator i = this->find(value); if (i != this->end()) { return i->second; } else { THROW(JTypeInformationException, "Invalid value <" << value << ">"); } } /** * Get index of version * * \param value numerical value * \return index */ int operator[](const JDetectorVersion::JVersion_t& value) const { using namespace std; const_iterator i = this->find(value); if (i != this->end()) return distance(this->begin(), i); else return -1; } }; /** * Function object to map detector version to numerical value. */ static const JGetDetectorVersion getDetectorVersion; /** * Function object to map numerical value to detector version. */ static const JPutDetectorVersion putDetectorVersion(getDetectorVersion); /** * Get detector versions. * * Note that the order of the versions is descending. * * \param type type * \return versions */ inline std::vector getDetectorVersions(const JType& type) { return JLANG::make_array(putDetectorVersion.rbegin(), putDetectorVersion.rend(), &JPutDetectorVersion::value_type::second); } /** * Get detector versions. * * Note that the order of the versions is descending. * * \param type type * \return numerical values */ inline std::vector getDetectorVersions(const JType& type) { return JLANG::make_array(putDetectorVersion.rbegin(), putDetectorVersion.rend(), &JPutDetectorVersion::value_type::first); } /** * Get detector versions. * * \return versions */ template inline std::vector getDetectorVersions() { return getDetectorVersions(JType()); } /** * Get latest detector version. * * \param type type * \return version */ inline std::string getLatestDetectorVersion(const JType& type) { return putDetectorVersion.rbegin()->second; } /** * Get latest detector version. * * \param type type * \return version */ inline JVersion getLatestDetectorVersion(const JType& type) { return putDetectorVersion.rbegin()->second; } /** * Get latest detector version. * * \param type type * \return version */ inline JDetectorVersion::JVersion_t getLatestDetectorVersion(const JType& type) { return putDetectorVersion.rbegin()->first; } /** * Get latest detector version. * * \return version */ template inline T getLatestDetectorVersion() { return getLatestDetectorVersion(JType()); } } #endif