#include #include #include #include #include #include "km3net-dataformat/online/JDAQ.hh" #include "JSystem/JDateAndTime.hh" #include "JLang/JUUID.hh" #include "Jeep/JPrint.hh" #include "Jeep/JParser.hh" #include "Jeep/JMessage.hh" #include "Jeep/JProperties.hh" #include "JLang/JPredicate.hh" #include "JSupport/JMeta.hh" #include "JSupport/JFilenameSupportkit.hh" #include "JDetector/JDetectorCalibration.hh" #include "JDB/JUPI_t.hh" #include "JDB/JVendorHV.hh" #include "JDB/JDBSupportkit.hh" #include "JDB/JPMTHVRunSettings.hh" #include "JSon/JSon.hh" namespace { /** * Auxiliary class for creating PMT high-voltage look-up table from ASCII DB file. */ struct JHVTable { /** * HV-table types. */ enum JHVTableTypes { VENDOR_HV = 1, //!< Vendor high-voltages RUN_HV = 2 //!< Run-specific high-voltages }; /** * Initialise * * \param filename file name * \param type HV-table type */ JHVTable(const char* const filename, const JHVTableTypes type) { using namespace std; using namespace JPP; ifstream in(filename); switch (type) { case VENDOR_HV: { for (string buffer; getline(in, buffer); ) { istringstream is(buffer); JVendorHV entry; if (is >> entry.DETID >> entry.DUID >> entry.FLOORID >> entry.CABLEPOS >> entry.PMTSERIAL >> entry.PMT_SUPPLY_VOLTAGE) { if (entry.PMTSERIAL > 0 && entry.PMT_SUPPLY_VOLTAGE < 0) { HVmap[entry.PMTSERIAL] = entry.PMT_SUPPLY_VOLTAGE; } } } break; } case RUN_HV: { for (string buffer; getline(in, buffer); ) { istringstream is(buffer); JPMTHVRunSettings entry; if (is >> entry.DETOID >> entry.DETID >> entry.RUN >> entry.RUNSETUPID >> entry.DUID >> entry.FLOORID >> entry.PMTINTID >> entry.CABLEPOS >> entry.PMTSERIAL >> entry.CG_OID >> entry.HV_INDEX >> entry.HV_VALUE) { if (entry.PMTSERIAL > 0 && entry.HV_VALUE < 0) { HVmap[entry.PMTSERIAL] = entry.HV_VALUE; } } } break; } default: THROW(JValueOutOfRange, "JHVTable::JHVTable(): Invalid HV-table type: " << type); } in.close(); } /** * Get high-voltage. * * \param serialID PMT serial number * \return high-voltage [V] */ double operator()(const int serialID) { using namespace std; using namespace JPP; map::const_iterator p = HVmap.find(serialID); if (p != HVmap.end()) { return p->second; } else { THROW(JValueOutOfRange, "Serial number " << serialID << " not found."); } } protected: std::map HVmap; }; /** * Read PMT HV-table type from input. * * \param in input stream * \param object PMT HV-table type * \return input stream */ inline std::istream& operator>>(std::istream& in, JHVTable::JHVTableTypes& object) { using JLANG::JValueOutOfRange; int type; in >> type; switch (type) { case int(JHVTable::VENDOR_HV): object = JHVTable::VENDOR_HV; return in; case int(JHVTable::RUN_HV): object = JHVTable::RUN_HV; return in; default: THROW(JValueOutOfRange, "operator>>(): Invalid HV-table type: " << type); } } /** * Write PMT HV-table type to output. * * \param out output stream * \param object PMT HV-table type * \return output stream */ inline std::ostream& operator<<(std::ostream& out, JHVTable::JHVTableTypes object) { return out << int(object); } } /** * \file * * Auxiliary program to treat failed HV-tuning calibrations. * \author bjung */ int main(int argc, char **argv) { using namespace std; using namespace JPP; typedef JHVTable::JHVTableTypes JHVTableType_t; typedef pair JHVTable_t; string inputFile; string outputFile; JHVTable_t HVtable; set pmtSet; string login; string locationID; int elapsedTime = 0; double minHV = -1500; double maxHV = - 800; int debug; try { JProperties properties; properties.insert(gmake_property(login)); properties.insert(gmake_property(locationID)); properties.insert(gmake_property(elapsedTime)); JProperties settings; settings.insert(gmake_property(minHV)); settings.insert(gmake_property(maxHV)); JParser<> zap("Auxiliary program to treat failed high-voltage tuning results."); zap['f'] = make_field(inputFile, "input file"); zap['o'] = make_field(outputFile, "output file"); zap['b'] = make_field(HVtable, "ASCII HV table") = JPARSER::initialised(); zap['P'] = make_field(pmtSet, "Set of PMT UPIs") = JPARSER::initialised(); zap['#'] = make_field(properties, "database information") = JPARSER::initialised(); zap['@'] = make_field(settings, "HV limits") = JPARSER::initialised(); zap['d'] = make_field(debug, "debug") = 2; zap(argc, argv); } catch(const exception &error) { FATAL(error.what() << endl); } if (login.empty() || locationID.empty()) { FATAL("Missing user information (please specify via -#login and -#locationID)."); } const JUUID& UUID = JUUID::rndm(); JDateAndTime timer; timer.sub(elapsedTime); // Edit high-voltage calibrations JDBAPIVersion DBAPIVersion; string DBTestType; string metaInfoStr = MAKE_STRING(JMeta(argc, argv)); JHVCalibration toEdit; if (isJSONFile(inputFile.c_str())) { json js; ifstream ifs(inputFile.c_str()); ifs >> js; ifs.close(); // Extract data json::const_iterator i0 = js.find(APIVersion_t); if (i0 != js.cend()) { istringstream iss(i0->get()); iss >> DBAPIVersion; } JHVCalibration HVcals; json::const_iterator i1 = js.find(Data_t); if ((DBAPIVersion.getMajorVersion() == 2) && (i1 != js.cend() && i1->size() > 0)) { DBTestType = (*i1)[0].at(Test_t + Type_t).get(); JHVCalibration_t::setVersion(getDBVersionTuneHV(DBTestType)); HVcals = (*i1)[0].at(Tests_t).get(); metaInfoStr += (*i1)[0].at(Provenance_t + Info_t).at(Configuration_t).get(); } else { DBTestType = js.at(Test_t + Type_t).get(); JHVCalibration_t::setVersion(getDBVersionTuneHV(DBTestType)); HVcals = js.at(Tests_t).get(); } // Collect PMTs which need to be edited if (pmtSet.empty()) { for (JHVCalibration::iterator it = HVcals.begin(); it != HVcals.end(); ++it) { if (it->result != OK_t) { toEdit.push_back(*it); } } } else { for (set::const_iterator it = pmtSet.cbegin(); it != pmtSet.cend(); ++it) { JHVCalibration::iterator pmt = find_if(HVcals.begin(), HVcals.end(), make_predicate(&JHVCalibration_t::getNumber, it->getNumber())); if (pmt != HVcals.end()) { if (pmt->result == OK_t) { WARNING("Editing " << OK_t << " result for " << pmt->getUPI() << endl); } toEdit.push_back(*pmt); } } } } else { ERROR(inputFile << " is not a JSON file." << endl); } if (!HVtable.second.empty()) { NOTICE("Setting " << (HVtable.first == JHVTableType_t::VENDOR_HV ? "vendor " : "run-specific ") << "PMT high-voltages from file " << HVtable.second << "..." << endl); JHVTable getHV(HVtable.second.c_str(), HVtable.first); for (JHVCalibration::iterator i = toEdit.begin(); i != toEdit.end(); ++i) { const JUPI_t& upi = i->getUPI(); const double HV = getHV(upi.getNumber()); if (HV > minHV && HV < maxHV) { i->supplyVoltage = getHV(upi.getNumber()); i->result = OK_t; } else { WARNING("Invalid high-voltage for PMT " << upi << " (" << FIXED(7,1) << HV << " not within [ " << FIXED(7,1) << minHV << ", " << FIXED(7,1) << maxHV << "]); skip." << endl); } } } else { NOTICE("Setting high-voltages manually..." << endl); for (JHVCalibration::iterator i = toEdit.begin(); i != toEdit.end(); ++i) { NOTICE("Please specify high-voltage for " << RIGHT(30) << i->getUPI() << ":" << endl); double manualHV; cin >> manualHV; while (manualHV < minHV || manualHV > maxHV) { WARNING("Specified high-voltage is not within range [" << FIXED(7,1) << minHV << ", " << FIXED(7,1) << maxHV << "]; Please specify again." << endl); cin >> manualHV; } i->supplyVoltage = manualHV; i->result = OK_t; } } json js; if (DBAPIVersion.getMajorVersion() == 2) { json error = { {Message_t, "" }, {Code_t, OK_t }, {Arguments_t, json::array() } }; json metaData = { {Configuration_t, metaInfoStr }, {UUID_t, MAKE_STRING(UUID) } }; json data = { {Provenance_t + Info_t, json(metaData) }, {User_t, login }, {Location_t, locationID }, {Start_t + Time_t, timer.toString() }, {End_t + Time_t, timer().toString() }, {Test_t + Type_t, DBTestType }, {Tests_t, json(toEdit) } }; js[APIVersion_t] = MAKE_STRING(DBAPIVersion); js[Data_t + Type_t] = MAKE_STRING("ProductTestSession"); js[Encoding_t] = MAKE_STRING("NativeJSON"); js[Error_t] = json(error); js[Start_t] = timer.toString(); js[End_t] = timer().toString(); js[Data_t][0] = json(data); } else { js[User_t] = login; js[Location_t] = locationID; js[Test_t + Type_t] = DBTestType; js[Start_t + Time_t] = timer.toString(); js[End_t + Time_t] = timer().toString(); js[Tests_t] = json(toEdit); } ofstream ofs(outputFile.c_str()); ofs << setw(2) << setprecision(8); ofs << js; ofs.close(); return 0; }