diff --git a/DataFormats/Detectors/CTP/include/DataFormatsCTP/Configuration.h b/DataFormats/Detectors/CTP/include/DataFormatsCTP/Configuration.h index 4ff0256f33827..fdd73986f1eaf 100644 --- a/DataFormats/Detectors/CTP/include/DataFormatsCTP/Configuration.h +++ b/DataFormats/Detectors/CTP/include/DataFormatsCTP/Configuration.h @@ -173,6 +173,8 @@ class CTPConfiguration uint64_t getDecrtiptorInputsMask(const std::string& name) const; std::map> getDet2InputMap(); uint64_t getTriggerClassMask() const; + uint64_t getTriggerClassMaskWInputs() const; + uint64_t getTriggerClassMaskWInputsNoTrgDets() const; std::vector getTriggerClassList() const; uint32_t getRunNumber() { return mRunNumber; }; std::vector getDetectorList() const; @@ -203,6 +205,17 @@ class CTPConfiguration std::ostream& operator<<(std::ostream& in, const CTPConfiguration& conf); +struct CtpCfg { + CtpCfg() = default; + std::string filename = "ctp.cfg"; + int readAndSave(std::string& path); + uint32_t TFOrbits = 0; + int ccdb = -1; // -1 means def constructor was called + uint32_t orbitShift = 0; + uint32_t irInputs_1_24 = 0; + uint32_t irInputs_25_48 = 0; + ClassDefNV(CtpCfg, 1) +}; } // namespace ctp } // namespace o2 #endif //_CTP_CONFIGURATION_H_ diff --git a/DataFormats/Detectors/CTP/src/Configuration.cxx b/DataFormats/Detectors/CTP/src/Configuration.cxx index 03f9b38db0e9f..38a49132db3d1 100644 --- a/DataFormats/Detectors/CTP/src/Configuration.cxx +++ b/DataFormats/Detectors/CTP/src/Configuration.cxx @@ -905,6 +905,30 @@ uint64_t CTPConfiguration::getTriggerClassMask() const } return clsmask; } +uint64_t CTPConfiguration::getTriggerClassMaskWInputs() const +{ + uint64_t clsmask = 0; + for (auto const& cls : mCTPClasses) { + if (cls.name.find("TRUE") != std::string::npos) { // ignoring internal ctp generators + continue; + } + clsmask |= cls.classMask; + } + return clsmask; +} +uint64_t CTPConfiguration::getTriggerClassMaskWInputsNoTrgDets() const +{ + uint64_t clsmask = 0; + for (auto const& cls : mCTPClasses) { + bool exclude = cls.name.find("TRUE") != std::string::npos; // ignoring internal ctp generators + exclude += cls.name.find("EMC") != std::string::npos; + exclude += cls.name.find("TRD") != std::string::npos; + exclude += cls.name.find("HMP") != std::string::npos; + if (!exclude) + clsmask |= cls.classMask; + } + return clsmask; +} // Hardware positions of classes std::vector CTPConfiguration::getTriggerClassList() const { @@ -1153,6 +1177,47 @@ int CTPInputsConfiguration::getInputIndexFromName(std::string& name) return 0xff; } +int CtpCfg::readAndSave(std::string& path) +{ + std::string file = path + filename; + std::ifstream ctpcfg(file); + if (ctpcfg.is_open()) { + std::string line; + while (std::getline(ctpcfg, line)) { + o2::utils::Str::trim(line); + if (line.size() == 0) { + continue; + } + if (line[0] == '#') { + continue; + } + std::vector tokens = o2::utils::Str::tokenize(line, ' '); + size_t ntokens = tokens.size(); + if (ntokens < 2) { + LOG(warn) << "Not enough tokens"; + continue; + } + if (tokens[0].find("TForbits") != std::string::npos) { + TFOrbits = std::atol(tokens[1].c_str()); + } else if (tokens[0].find("ccdb") != std::string::npos) { + ccdb = std::atoi(tokens[1].c_str()); + } else if (tokens[0].find("orbitshift") != std::string::npos) { + orbitShift = std::atol(tokens[1].c_str()); + } else if (tokens[0].find("ir_inputs") != std::string::npos) { + irInputs_1_24 = std::stoul(tokens[2].c_str(), nullptr, 16); + irInputs_25_48 = std::stoul(tokens[1].c_str(), nullptr, 16); + } else { + LOG(warn) << " Token not found:" << tokens[0]; + } + } + LOG(warn) << "Open file success:" << file; + } else { + LOG(warn) << "Can not open file:" << file; + return 1; + } + return 0; +} + std::ostream& o2::ctp::operator<<(std::ostream& in, const o2::ctp::CTPConfiguration& conf) { conf.printStream(in); diff --git a/DataFormats/Detectors/CTP/src/DataFormatsCTPLinkDef.h b/DataFormats/Detectors/CTP/src/DataFormatsCTPLinkDef.h index da21f779723f8..ac2a83d31edda 100644 --- a/DataFormats/Detectors/CTP/src/DataFormatsCTPLinkDef.h +++ b/DataFormats/Detectors/CTP/src/DataFormatsCTPLinkDef.h @@ -55,4 +55,6 @@ #pragma link C++ class o2::ctp::TriggerOffsetsParam + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::ctp::TriggerOffsetsParam> + ; +#pragma link C++ class o2::ctp::CtpCfg + ; + #endif diff --git a/Detectors/CTP/reconstruction/include/CTPReconstruction/RawDataDecoder.h b/Detectors/CTP/reconstruction/include/CTPReconstruction/RawDataDecoder.h index 7579e9dc1d6f5..8ebc7e0304561 100644 --- a/Detectors/CTP/reconstruction/include/CTPReconstruction/RawDataDecoder.h +++ b/Detectors/CTP/reconstruction/include/CTPReconstruction/RawDataDecoder.h @@ -55,7 +55,12 @@ class RawDataDecoder int init(); static int shiftNew(const o2::InteractionRecord& irin, uint32_t TFOrbit, std::bitset<48>& inpmask, int64_t shift, int level, std::map& digmap); static int shiftInputs(std::map& digitsMap, o2::pmr::vector& digits, uint32_t TFOrbit, uint64_t trgclassmask = 0xffffffffffffffff); - int checkReadoutConsistentncy(o2::pmr::vector& digits, uint64_t trgclassmask = 0xffffffffffffffff); + int checkReadoutConsistentncy(o2::pmr::vector& digits, uint64_t trgclassmask = 0xffffffffffffffff, uint64_t trigclassmaskNoTrgDets = 0xffffffffffffffff); + std::array getClassErrorsA() { return mClassErrorsA; } + std::array getClassErrorsB() { return mClassErrorsB; } + std::array getClassCountersA() { return mClassCountersA; } + std::array getClassCountersB() { return mClassCountersB; } + int getLostDueToShift() { return mLostDueToShift; } private: static constexpr uint32_t TF_TRIGGERTYPE_MASK = 0x800; @@ -83,8 +88,13 @@ class RawDataDecoder // error verbosness int mErrorIR = 0; int mErrorTCR = 0; - int mErrorMax = 3; + int mErrorMax = 5; bool mStickyError = false; + std::array mClassErrorsA{}; + std::array mClassErrorsB{}; // from inputs + std::array mClassCountersA{}; + std::array mClassCountersB{}; // from inputs + int mLostDueToShift = 0; CTPConfiguration mCTPConfig; }; } // namespace ctp diff --git a/Detectors/CTP/reconstruction/src/RawDataDecoder.cxx b/Detectors/CTP/reconstruction/src/RawDataDecoder.cxx index fa7fd673c7e85..797dd0e300519 100644 --- a/Detectors/CTP/reconstruction/src/RawDataDecoder.cxx +++ b/Detectors/CTP/reconstruction/src/RawDataDecoder.cxx @@ -294,13 +294,17 @@ int RawDataDecoder::decodeRaw(o2::framework::InputRecord& inputs, std::vector& digitsMap, o2::pmr::vector& digits, uint32_t TFOrbit, uint64_t trgclassmask) { // int nClasswoInp = 0; // counting classes without input which should never happen - int nLM = 0; - int nL0 = 0; - int nL1 = 0; - int nTwI = 0; - int nTwoI = 0; - int nTwoIlost = 0; std::map digitsMapShifted; auto L0shift = o2::ctp::TriggerOffsetsParam::Instance().LM_L0; auto L1shift = L0shift + o2::ctp::TriggerOffsetsParam::Instance().L0_L1; @@ -593,86 +591,77 @@ int RawDataDecoder::shiftInputs(std::map& digit } } for (auto const& dig : digitsMapShifted) { - auto d = dig.second; - if ((d.CTPInputMask & LMMASKInputs).count()) { - nLM++; - } - if ((d.CTPInputMask & L0MASKInputs).count()) { - nL0++; - } - if ((d.CTPInputMask & L1MASKInputs).count()) { - nL1++; - } - if ((d.CTPClassMask).to_ulong() & trgclassmask) { - if (d.CTPInputMask.count()) { - nTwI++; - } else { - if (d.intRecord.bc == (o2::constants::lhc::LHCMaxBunches - L1shift)) { // input can be lost because latency class-l1input = 1 - nTwoIlost++; - } else { - // LOG(error) << d.intRecord << " " << d.CTPClassMask << " " << d.CTPInputMask; - // std::cout << "ERROR:" << std::hex << d.CTPClassMask << " " << d.CTPInputMask << std::dec << std::endl; - nTwoI++; - } - } - } digits.push_back(dig.second); } - int ret = 0; - if (nTwoI) { // Trigger class wo Input - LOG(error) << "LM:" << nLM << " L0:" << nL0 << " L1:" << nL1 << " TwI:" << nTwI << " Trigger classes wo input:" << nTwoI; - ret = 64; - } - if (nTwoIlost) { - LOG(warn) << " Trigger classes wo input from diff latency 1:" << nTwoIlost; - } - return ret; + return 0; } // -int RawDataDecoder::checkReadoutConsistentncy(o2::pmr::vector& digits, uint64_t trgclassmask) +int RawDataDecoder::checkReadoutConsistentncy(o2::pmr::vector& digits, uint64_t trgclassmask, uint64_t trgclassmaskNoTrgDet) { + LOG(debug) << "Checking readout"; int ret = 0; - int lost = 0; + static int nerror = 0; for (auto const& digit : digits) { // if class mask => inps for (int i = 0; i < digit.CTPClassMask.size(); i++) { - if (digit.CTPClassMask[i] & trgclassmask) { + bool trgcls = trgclassmask & (1ull << i); + if (digit.CTPClassMask[i] & trgcls) { const CTPClass* cls = mCTPConfig.getCTPClassFromHWIndex(i); if (cls == nullptr) { - LOG(error) << "Class mask index not found in CTP config:" << i; + if (nerror < mErrorMax) { + LOG(error) << "Class mask index not found in CTP config:" << i; + nerror++; + } ret = 128; continue; } + mClassCountersA[i]++; + if (cls->descriptor == nullptr) + continue; uint64_t clsinpmask = cls->descriptor->getInputsMask(); uint64_t diginpmask = digit.CTPInputMask.to_ullong(); if (!((clsinpmask & diginpmask) == clsinpmask)) { - LOG(error) << "CTP class:" << cls->name << " inpmask:" << clsinpmask << " not compatible with inputs mask:" << diginpmask; + if (nerror < mErrorMax) { + LOG(error) << "Cls=>Inps: CTP class:" << cls->name << " inpmask:" << clsinpmask << " not compatible with inputs mask:" << diginpmask; + nerror++; + } + mClassErrorsA[i]++; ret = 128; } } } // if inps => class mask for (auto const& cls : mCTPConfig.getCTPClasses()) { - uint64_t clsinpmask = cls.descriptor->getInputsMask(); + // cls.printStream(std::cout); + if (cls.descriptor == nullptr) + continue; + uint64_t clsinpmask = cls.descriptor->getInputsMask(); // class definition uint64_t diginpmask = digit.CTPInputMask.to_ullong(); uint64_t digclsmask = digit.CTPClassMask.to_ullong(); if ((clsinpmask & diginpmask) == clsinpmask) { - if ((cls.classMask & digclsmask) == 0) { - int32_t BCShiftCorrection = -o2::ctp::TriggerOffsetsParam::Instance().customOffset[o2::detectors::DetID::CTP]; - int32_t offset = BCShiftCorrection + o2::ctp::TriggerOffsetsParam::Instance().LM_L0 + o2::ctp::TriggerOffsetsParam::Instance().L0_L1_classes - 1; - offset = o2::constants::lhc::LHCMaxBunches - offset; - if (digit.intRecord.bc < offset) { - LOG(error) << "CTP class:" << cls.name << " inpmask:" << clsinpmask << " cls mask:" << cls.classMask << " not found in digit:" << digit; - ret = 256; - } else { - lost++; + if (cls.classMask & trgclassmask) { + mClassCountersB[cls.getIndex()]++; + if ((cls.classMask & digclsmask) == 0) { + int32_t BCShiftCorrection = -o2::ctp::TriggerOffsetsParam::Instance().customOffset[o2::detectors::DetID::CTP]; + int32_t offset = BCShiftCorrection + o2::ctp::TriggerOffsetsParam::Instance().LM_L0 + o2::ctp::TriggerOffsetsParam::Instance().L0_L1_classes - 1; + offset = o2::constants::lhc::LHCMaxBunches - offset; + if (digit.intRecord.bc < offset) { + if ((nerror < mErrorMax) && (cls.classMask & ~trgclassmaskNoTrgDet)) { + LOG(info) << "Inp=>Cls: CTP class:" << cls.name << " inpmask:" << clsinpmask << " cls mask:" << cls.classMask << " not found in digit:" << digit; + nerror++; + } + mClassErrorsB[cls.getIndex()]++; + ret = 256; + } else { + mLostDueToShift++; + } } } } } } - if (lost) { - LOG(info) << "LOST classes because of shift:" << lost; + if (mLostDueToShift) { + LOG(debug) << "LOST classes because of shift:" << mLostDueToShift; } return ret; } diff --git a/Detectors/CTP/workflow/src/RawDecoderSpec.cxx b/Detectors/CTP/workflow/src/RawDecoderSpec.cxx index 753f88114a14b..3f7c729b351a3 100644 --- a/Detectors/CTP/workflow/src/RawDecoderSpec.cxx +++ b/Detectors/CTP/workflow/src/RawDecoderSpec.cxx @@ -69,8 +69,21 @@ void RawDecoderSpec::endOfStream(framework::EndOfStreamContext& ec) o0 = TFOrbits[i]; } std::cout << std::endl; - std::cout << "Number of missing TF:" << nmiss << std::endl; - std::cout << "# of IR errors:" << mDecoder.getErrorIR() << " TCR errors:" << mDecoder.getErrorTCR() << std::endl; + LOG(info) << " Lost due to the shift:" << mDecoder.getLostDueToShift(); + LOG(info) << "Number of missing TF:" << nmiss << std::endl; + if (mDecoder.getErrorIR() || mDecoder.getErrorTCR()) + LOG(error) << "# of IR errors:" << mDecoder.getErrorIR() << " TCR errors:" << mDecoder.getErrorTCR() << std::endl; + std::array clsA = mDecoder.getClassCountersA(); + std::array clsB = mDecoder.getClassCountersB(); + std::array clsEA = mDecoder.getClassErrorsA(); + std::array clsEB = mDecoder.getClassErrorsB(); + + for (int i = 0; i < o2::ctp::CTP_NCLASSES; i++) { + bool print = clsA[i] > 0 || clsB[i] > 0 || clsEA[i] > 0 || clsEB[i] > 0; + if (clsEA[i]) + LOG(error) << " Class without inputs:"; + LOG(important) << "CLASS:" << i << " Cls=>Inp:" << clsA[i] << " Inp=>Cls:" << clsB[i] << " ErrorsCls=>Inps:" << clsEA[i] << " MissingInps=>Cls:" << clsEB[i]; + } } void RawDecoderSpec::run(framework::ProcessingContext& ctx) { diff --git a/Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/RunManager.h b/Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/RunManager.h index 72fb9c2056367..6d2172e3da165 100644 --- a/Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/RunManager.h +++ b/Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/RunManager.h @@ -72,7 +72,7 @@ class CTPRunManager : public ctpCCDBManager int mEOX = 0; // redundancy check int mNew = 1; // 1 - no CCDB: used for QC int mQCWritePeriod = 3; // Time in 10secs between two writes to QCCD - ClassDefNV(CTPRunManager, 7); + ClassDefNV(CTPRunManager, 8); }; } // namespace ctp } // namespace o2 diff --git a/Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/ctpCCDBManager.h b/Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/ctpCCDBManager.h index c968a83183624..4237ad4501fcc 100644 --- a/Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/ctpCCDBManager.h +++ b/Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/ctpCCDBManager.h @@ -29,11 +29,13 @@ class ctpCCDBManager int saveRunConfigToCCDB(CTPConfiguration* cfg, long timeStart); int saveSoxOrbit(uint32_t runNumber, uint32_t soxOrbit, long timeStart); int saveOrbitReset(long timeStamp); + int saveCtpCfg(uint32_t runNumber, long timeStamp); static CTPConfiguration getConfigFromCCDB(long timestamp, std::string run, bool& ok); static CTPConfiguration getConfigFromCCDB(long timestamp, std::string run); CTPRunScalers getScalersFromCCDB(long timestamp, std::string, bool& ok); static void setCCDBHost(std::string host) { mCCDBHost = host; }; static void setQCDBHost(std::string host) { mQCDBHost = host; }; + void setCtpCfgDir(std::string& ctpcfgdir) { mCtpCfgDir = ctpcfgdir; }; protected: /// Database constants @@ -46,7 +48,10 @@ class ctpCCDBManager const std::string mQCDBPathCTPScalers = "qc/CTP/Scalers"; const std::string mCCDBPathSoxOrbit = "CTP/Calib/FirstRunOrbit"; const std::string mCCDBPathOrbitReset = "CTP/Calib/OrbitReset"; - ClassDefNV(ctpCCDBManager, 1); + const std::string mCCDBPathCtpCfg = "CTP/Config/CtpCfg"; + std::string mCtpCfgDir; + + ClassDefNV(ctpCCDBManager, 2); }; } // namespace ctp } // namespace o2 diff --git a/Detectors/CTP/workflowScalers/src/RunManager.cxx b/Detectors/CTP/workflowScalers/src/RunManager.cxx index 5d0b906e28088..054505aea7ba6 100644 --- a/Detectors/CTP/workflowScalers/src/RunManager.cxx +++ b/Detectors/CTP/workflowScalers/src/RunManager.cxx @@ -87,6 +87,7 @@ void CTPRunManager::init() LOG(info) << "QCDB writing every:" << mQCWritePeriod << " 10 secs"; LOG(info) << "CCDB host:" << mCCDBHost; LOG(info) << "CTP vNew cfg:" << mNew; + LOG(info) << "ctp.cfg dir:" << mCtpCfgDir; LOG(info) << "CTPRunManager initialised."; } int CTPRunManager::loadRun(const std::string& cfg) @@ -106,7 +107,7 @@ int CTPRunManager::loadRun(const std::string& cfg) timeStamp = (tt * 1000.); LOG(info) << "Timestamp file:" << timeStamp; cfgmod = cfg.substr(pos, cfg.size()); - LOG(info) << "ctpcfg: using ctp time"; + LOG(info) << "ctpconfig: using ctp time"; } } CTPActiveRun* activerun = new CTPActiveRun; @@ -122,7 +123,9 @@ int CTPRunManager::loadRun(const std::string& cfg) // mRunsLoaded[runnumber] = activerun; saveRunConfigToCCDB(&activerun->cfg, timeStamp); - + if (mCtpCfgDir != "none") { + saveCtpCfg(runnumber, timeStamp); + } return 0; } int CTPRunManager::setRunConfigBK(uint32_t runNumber, const std::string& cfg) @@ -272,6 +275,9 @@ int CTPRunManager::processMessage(std::string& topic, const std::string& message } return ret; } + if (topic.find("rocnts") != std::string::npos) { + return 0; + } static int nerror = 0; if (topic.find("sox") != std::string::npos) { // get config diff --git a/Detectors/CTP/workflowScalers/src/ctp-proxy.cxx b/Detectors/CTP/workflowScalers/src/ctp-proxy.cxx index b2896215d1c6a..f8f8ad3c95fbb 100644 --- a/Detectors/CTP/workflowScalers/src/ctp-proxy.cxx +++ b/Detectors/CTP/workflowScalers/src/ctp-proxy.cxx @@ -46,13 +46,14 @@ #include "BookkeepingApi/BkpClient.h" using namespace o2::framework; using DetID = o2::detectors::DetID; -InjectorFunction dcs2dpl(std::string& ccdbhost, std::string& bkhost, std::string& qchost, int qcwriteperiod) +InjectorFunction dcs2dpl(std::string& ccdbhost, std::string& bkhost, std::string& qchost, int qcwriteperiod, std::string& ctpcfgdir) { auto runMgr = std::make_shared(); runMgr->setCCDBHost(ccdbhost); runMgr->setBKHost(bkhost); runMgr->setQCDBHost(qchost); runMgr->setQCWritePeriod(qcwriteperiod); + runMgr->setCtpCfgDir(ctpcfgdir); runMgr->init(); // runMgr->setClient(client); return [runMgr](TimingInfo&, ServiceRegistryRef const& services, fair::mq::Parts& parts, ChannelRetriever channelRetriever, size_t newTimesliceId, bool& stop) -> bool { @@ -78,6 +79,7 @@ void customize(std::vector& workflowOptions) workflowOptions.push_back(ConfigParamSpec{"ccdb-host", VariantType::String, "http://o2-ccdb.internal:8080", {"ccdb host"}}); workflowOptions.push_back(ConfigParamSpec{"bk-host", VariantType::String, "none", {"bk host"}}); workflowOptions.push_back(ConfigParamSpec{"qc-host", VariantType::String, "none", {"qc host"}}); + workflowOptions.push_back(ConfigParamSpec{"ctpcfg-dir", VariantType::String, "none", {"ctp.cfg file directory"}}); workflowOptions.push_back(ConfigParamSpec{"qc-writeperiod", VariantType::Int, 30, {"Period of writing to QCDB in units of 10secs, default = 30 (5 mins)"}}); } @@ -104,6 +106,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& config) std::string bkhost = config.options().get("bk-host"); std::string qchost = config.options().get("qc-host"); int qcwriteperiod = config.options().get("qc-writeperiod"); + std::string ctpcfgdir = config.options().get("ctpcfg-dir"); if (chan.empty()) { throw std::runtime_error("input channel is not provided"); } @@ -118,7 +121,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& config) std::move(ctpCountersOutputs), // this is just default, can be overriden by --ctp-config-proxy '--channel-config..' chan.c_str(), - dcs2dpl(ccdbhost, bkhost, qchost, qcwriteperiod)); + dcs2dpl(ccdbhost, bkhost, qchost, qcwriteperiod, ctpcfgdir)); ctpProxy.labels.emplace_back(DataProcessorLabel{"input-proxy"}); LOG(info) << "===> Proxy done"; WorkflowSpec workflow; diff --git a/Detectors/CTP/workflowScalers/src/ctpCCDBManager.cxx b/Detectors/CTP/workflowScalers/src/ctpCCDBManager.cxx index cbe8fe5dd675f..58850d88eb2c6 100644 --- a/Detectors/CTP/workflowScalers/src/ctpCCDBManager.cxx +++ b/Detectors/CTP/workflowScalers/src/ctpCCDBManager.cxx @@ -167,6 +167,36 @@ int ctpCCDBManager::saveOrbitReset(long timeStamp) } return 0; } +int ctpCCDBManager::saveCtpCfg(uint32_t runNumber, long timeStart) +{ + if (mCCDBHost == "none") { + LOG(info) << "CtpCfg not written to CCDB none"; + return 0; + } + CtpCfg ctpcfg; + int ret = ctpcfg.readAndSave(mCtpCfgDir); + if (ret == 0) { + using namespace std::chrono_literals; + std::chrono::seconds days3 = 259200s; + std::chrono::seconds min10 = 600s; + long time3days = std::chrono::duration_cast(days3).count(); + long time10min = std::chrono::duration_cast(min10).count(); + long tmin = timeStart - time10min; + long tmax = timeStart + time3days; + o2::ccdb::CcdbApi api; + map metadata; // can be empty + metadata["runNumber"] = std::to_string(runNumber); + api.init(mCCDBHost.c_str()); // or http://localhost:8080 for a local installation + // store abitrary user object in strongly typed manner + ret = api.storeAsTFileAny(&ctpcfg, mCCDBPathCtpCfg, metadata, tmin, tmax); + if (ret == 0) { + LOG(info) << "CtpCfg saved in ccdb:" << mCCDBHost << " tmin:" << tmin << " tmax:" << tmax; + } else { + LOG(error) << "CtpCfg Problem writing to database ret:" << ret; + } + } + return ret; +} CTPConfiguration ctpCCDBManager::getConfigFromCCDB(long timestamp, std::string run, bool& ok) { auto& mgr = o2::ccdb::BasicCCDBManager::instance();