diff --git a/.gitignore b/.gitignore index e9d377a557f4e..dd3f634b9319b 100644 --- a/.gitignore +++ b/.gitignore @@ -82,3 +82,6 @@ bazel-* # LSP support on macOS with vim .clangd +DataFormats/Detectors/CTP/include/DataFormatsCTP/Scalers.h +dpl-config.json +O2.code-workspace diff --git a/DataFormats/Detectors/CTP/include/DataFormatsCTP/Configuration.h b/DataFormats/Detectors/CTP/include/DataFormatsCTP/Configuration.h index 18113f90d8646..a273754d411d5 100644 --- a/DataFormats/Detectors/CTP/include/DataFormatsCTP/Configuration.h +++ b/DataFormats/Detectors/CTP/include/DataFormatsCTP/Configuration.h @@ -23,6 +23,7 @@ #include #include #include +#include namespace o2 { namespace ctp @@ -47,22 +48,27 @@ struct CTPGenerator { ClassDefNV(CTPGenerator, 1); }; struct CTPInput { + const static std::map run2DetToRun3Det; CTPInput() = default; CTPInput(std::string& name, std::string& det, uint32_t index); CTPInput(const char* name, const char* det, uint32_t index); std::string name = ""; std::string level = ""; std::uint64_t inputMask = 0; - o2::detectors::DetID::ID detID = 0; + o2::detectors::DetID::ID detID = 13; + bool neg = 1; + uint32_t getIndex() const { return ((inputMask > 1) ? 1 + log2(inputMask >> 1) : 0) + 1; } std::string getInputDetName() const { return o2::detectors::DetID::getName(detID); } + void setRun3DetName(std::string& run2Name); void printStream(std::ostream& strem) const; - ClassDefNV(CTPInput, 2); + ClassDefNV(CTPInput, 3); }; struct CTPDescriptor { CTPDescriptor() = default; std::string name = ""; - std::vector inputs; + std::vector inputs; std::uint64_t getInputsMask() const; + // void createInputsFromName(); void printStream(std::ostream& strem) const; ClassDefNV(CTPDescriptor, 2) }; @@ -94,9 +100,12 @@ struct CTPClass { CTPDescriptor const* descriptor = nullptr; CTPCluster const* cluster = nullptr; int clusterIndex = 0; - int descriptorIndex = 0; + int descriptorIndex = 0xff; + uint32_t downScale = 1; + std::vector BCClassMask; + uint64_t getClassMaskForInput(int inputindex) const; void printStream(std::ostream& strem) const; - ClassDefNV(CTPClass, 3); + ClassDefNV(CTPClass, 4); }; struct CTPInputsConfiguration { CTPInputsConfiguration() = default; @@ -116,10 +125,11 @@ class CTPConfiguration bool isDetector(const o2::detectors::DetID& det); static void capitaliseString(std::string& str); static bool isNumber(const std::string& s); - enum ConfigPart { RUN, + enum ConfigPart { START, + RUN, + INPUTS, MASKS, GENS, - INPUT, LTG, LTGitems, CLUSTER, @@ -129,10 +139,13 @@ class CTPConfiguration void printStream(std::ostream& stream) const; std::vector& getCTPInputs() { return mInputs; } std::vector& getCTPClasses() { return mCTPClasses; } - uint64_t getInputMask(const std::string& name); + uint64_t getInputMask(const std::string& name) const; + int getInputIndex(const std::string& name) const; bool isMaskInInputs(const uint64_t& mask) const; bool isBCMaskInConfig(const std::string maskname) const; - CTPInput* isInputInConfig(const std::string inpname); + const CTPInput* isInputInConfig(const std::string inpname) const; + const CTPInput* isInputInConfig(const int index) const; + void createInputsInDecriptorsFromNames(); uint64_t getDecrtiptorInputsMask(const std::string& name) const; std::map> getDet2InputMap(); uint64_t getTriggerClassMask() const; @@ -141,12 +154,16 @@ class CTPConfiguration std::vector getDetectorList() const; o2::detectors::DetID::mask_t getDetectorMask() const; void createDefaultInputsConfig(); + uint64_t getClassMaskForInput(int inputindex) const; + uint64_t getClassMaskForInput(const std::string& name) const; + void printConfigString() { std::cout << mConfigString << std::endl; }; + std::string getConfigString() { return mConfigString; }; private: std::string mConfigString = ""; uint32_t mRunNumber = 0; std::string mName = ""; - std::string mVersion = "0"; + std::string mVersion = "1"; std::vector mBCMasks; std::vector mGenerators; std::vector mInputs; @@ -170,6 +187,7 @@ class CTPRunManager public: CTPRunManager() = default; void init(); + int loadRun(const std::string& cfg); int startRun(const std::string& cfg); int stopRun(uint32_t irun); int addScalers(uint32_t irun, std::time_t time); @@ -177,29 +195,28 @@ class CTPRunManager void printActiveRuns() const; int saveRunScalersToCCDB(int i); int saveRunConfigToCCDB(CTPConfiguration* cfg, long timeStart); - CTPConfiguration getConfigFromCCDB(long timestamp, std::string run); + static CTPConfiguration getConfigFromCCDB(long timestamp, std::string run); CTPRunScalers getScalersFromCCDB(long timestamp, std::string); int loadScalerNames(); // void setCCDBPathConfig(std::string path) { mCCDBPathCTPConfig = path;}; void setCCDBPathScalers(std::string path) { mCCDBPathCTPScalers = path; }; - void setCCDBHost(std::string host) { mCCDBHost = host; }; + static void setCCDBHost(std::string host) { mCCDBHost = host; }; void setCTPQC(int qc) { mQC = qc; }; void printCounters(); private: /// Database constants // std::string mCCDBHost = "http://ccdb-test.cern.ch:8080"; - std::string mCCDBHost = "http://o2-ccdb.internal"; + static std::string mCCDBHost; std::string mCCDBPathCTPScalers = "CTP/Calib/Scalers"; std::array mActiveRuns; std::array mActiveRunNumbers; std::array mCounters; std::map mScalerName2Position; - CTPActiveRun* mRunInStart = nullptr; + std::map mRunsLoaded; int mEOX = 0; // redundancy check - int mCtpcfg = 0; int mQC = 0; // 1 - no CCDB: used for QC - ClassDefNV(CTPRunManager, 4); + ClassDefNV(CTPRunManager, 5); }; } // namespace ctp diff --git a/DataFormats/Detectors/CTP/include/DataFormatsCTP/Scalers.h b/DataFormats/Detectors/CTP/include/DataFormatsCTP/Scalers.h index 2ed1731104c40..05f66ea7b8747 100644 --- a/DataFormats/Detectors/CTP/include/DataFormatsCTP/Scalers.h +++ b/DataFormats/Detectors/CTP/include/DataFormatsCTP/Scalers.h @@ -87,6 +87,7 @@ class CTPRunScalers void setDetectorMask(o2::detectors::DetID::mask_t mask) { mDetectorMask = mask; }; void setRunNumber(uint32_t rnumber) { mRunNumber = rnumber; }; void addScalerRacordRaw(CTPScalerRecordRaw& scalerrecordraw) { mScalerRecordRaw.push_back(scalerrecordraw); }; + uint32_t getRunNUmber() { return mRunNumber; }; int printRates(); int printIntegrals(); // diff --git a/DataFormats/Detectors/CTP/src/Configuration.cxx b/DataFormats/Detectors/CTP/src/Configuration.cxx index 346d49fbd9f9c..d128139d78bee 100644 --- a/DataFormats/Detectors/CTP/src/Configuration.cxx +++ b/DataFormats/Detectors/CTP/src/Configuration.cxx @@ -15,7 +15,6 @@ #include "DataFormatsCTP/Configuration.h" #include "CCDB/CcdbApi.h" #include "CCDB/BasicCCDBManager.h" -#include #include #include #include "CommonUtils/StringUtils.h" @@ -23,6 +22,8 @@ using namespace o2::ctp; // +std::string CTPRunManager::mCCDBHost = "http://o2-ccdb.internal"; +const std::map CTPInput::run2DetToRun3Det = {{"T", "FT0"}, {"V", "FV0"}, {"U", "FDD"}, {"E", "EMC"}, {"D", "EMC"}, {"H", "TRD"}, {"O", "TOF"}, {"P", "PHS"}, {"Z", "ZDC"}}; const std::map CTPConfiguration::detName2LTG = {{"FV0", "1"}, {"FT0", "2"}, {"FDD", "3"}, {"ITS", "4"}, {"TOF", "5"}, {"MFT", "6"}, {"TPC", "7"}, {"MCH", "8"}, {"MID", "9"}, {"TST", "10"}, {"TRD", "13"}, {"HMP", "14"}, {"ZDC", "15"}, {"PHS", "16"}, {"EMC", "17"}, {"CPV", "18"}}; // bool CTPConfiguration::isDetector(const o2::detectors::DetID& det) @@ -71,9 +72,15 @@ CTPInput::CTPInput(const char* name, const char* det, uint32_t index) inputMask = (1ull << (index - 1)); detID = o2::detectors::DetID(det); } +void CTPInput::setRun3DetName(std::string& run2Name) +{ + std::string run3Name = CTPInput::run2DetToRun3Det.at(run2Name); + detID = o2::detectors::DetID(run3Name.c_str()); +} void CTPInput::printStream(std::ostream& stream) const { - stream << "CTP Input:" << name << " Detector:" << getInputDetName() << " Level:" << level << " Hardware mask:0x" << std::hex << inputMask << std::dec << std::endl; + stream << "CTP Input:" << name << " Detector:" << getInputDetName() << " Level:" << level << " Hardware mask:0x" << std::hex << inputMask << std::dec; + stream << " index:" << getIndex() << std::endl; } // std::uint64_t CTPDescriptor::getInputsMask() const @@ -107,9 +114,22 @@ void CTPCluster::printStream(std::ostream& stream) const stream << std::endl; } // +uint64_t CTPClass::getClassMaskForInput(int inputindex) const +{ + uint64_t clsmask = 0; + if (descriptor != nullptr) { + clsmask = getClassMaskForInput(inputindex); + } + return clsmask; +} void CTPClass::printStream(std::ostream& stream) const { stream << "CTP Class:" << name << " Hardware mask:" << classMask << " Cluster index:" << clusterIndex << " Desc index:" << descriptorIndex; + stream << " Downscale:" << downScale; + stream << " BCM:"; + for (const auto& bcm : BCClassMask) { + stream << bcm->name << " "; + } if (descriptor != nullptr) { stream << " Descriptor:" << descriptor->name; } @@ -126,7 +146,7 @@ int CTPConfiguration::loadConfigurationRun3(const std::string& ctpconfiguration) mConfigString = ctpconfiguration; std::istringstream iss(ctpconfiguration); int ret = 0; - int level = MASKS; + int level = START; std::string line; while (std::getline(iss, line)) { o2::utils::Str::trim(line); @@ -134,8 +154,14 @@ int CTPConfiguration::loadConfigurationRun3(const std::string& ctpconfiguration) return ret; } } + for (auto& cls : mCTPClasses) { + cls.cluster = &mClusters[cls.clusterIndex]; + if (cls.descriptorIndex != 0xff) { + cls.descriptor = &mDescriptors[cls.descriptorIndex]; + } + } + createInputsInDecriptorsFromNames(); return ret; - return 0; } int CTPConfiguration::processConfigurationLineRun3(std::string& line, int& level) { @@ -155,17 +181,14 @@ int CTPConfiguration::processConfigurationLineRun3(std::string& line, int& level return 0; } size_t first; - if ((first = line.find("run")) != std::string::npos) { + if (((first = line.find("run")) != std::string::npos) && (level == START)) { level = RUN; - } else if (CTPGenerator::Generators.count(tokens[0])) { - if (level != CLASS) { - level = GENS; - } + } else if ((line.find("inp") != std::string::npos) && ((level == RUN) || (level == INPUTS))) { + level = INPUTS; + } else if (((first = line.find("bcm")) != std::string::npos) && ((level == INPUTS) || (level == MASKS))) { + level = MASKS; + } else if (CTPGenerator::Generators.count(tokens[0]) && ((level == INPUTS) || (level == MASKS) || (level == GENS))) { level = GENS; - } else if ((first = line.find("bcm")) != std::string::npos) { - if (level == MASKS) { - level = MASKS; - } } else if ((first = line.find("LTG")) != std::string::npos) { level = LTG; } else if ((first = line.find("cluster")) != std::string::npos) { @@ -180,7 +203,24 @@ int CTPConfiguration::processConfigurationLineRun3(std::string& line, int& level switch (level) { case RUN: { mRunNumber = std::stoul(tokens[1]); - level = MASKS; + level = RUN; + break; + } + case INPUTS: { + level = INPUTS; + if (tokens.size() < 3) { + LOG(error) << "Wrong input line:" << line; + break; + } + CTPInput ctpinp; + ctpinp.name = tokens[1]; + ctpinp.level = tokens[1][0]; + std::string run2Name{tokens[1][1]}; + ctpinp.setRun3DetName(run2Name); + uint32_t index = std::stoul(tokens[2]); + ctpinp.inputMask = (1ull << (index - 1)); + mInputs.push_back(ctpinp); + LOG(info) << "Input:" << ctpinp.name << " index:" << index; break; } case MASKS: { @@ -195,7 +235,7 @@ int CTPConfiguration::processConfigurationLineRun3(std::string& line, int& level } bool coded = tokens[2].find("L") != std::string::npos; coded |= tokens[2].find("H") != std::string::npos; - std::cout << "coded:" << coded << std::endl; + // std::cout << "coded:" << coded << std::endl; if (coded) { // jusko notation } else { @@ -298,28 +338,45 @@ int CTPConfiguration::processConfigurationLineRun3(std::string& line, int& level } } if (isGenerator) { - CTPDescriptor* desc = new CTPDescriptor; - desc->name = token; - mDescriptors.push_back(*desc); + CTPDescriptor desc; + desc.name = token; + mDescriptors.push_back(desc); cls.descriptorIndex = mDescriptors.size() - 1; + LOG(info) << "Class generator found:" << desc.name; } else if (token.find("~") != std::string::npos) { // inverted input + // std::cout << "Inverted input" << std::endl; std::string sinp = token.substr(1, token.size() - 1); // uint32_t inp = std::strtoul(sinp); - - CTPDescriptor* desc = new CTPDescriptor; - desc->name = token; - mDescriptors.push_back(*desc); - cls.descriptorIndex = mDescriptors.size() - 1; + if (cls.descriptorIndex == 0xff) { + CTPDescriptor desc; + desc.name = token; + mDescriptors.push_back(desc); + cls.descriptorIndex = mDescriptors.size() - 1; + } else { + CTPDescriptor desc = mDescriptors.at(cls.descriptorIndex); + desc.name += " " + token; + } } else if (isNumber(token)) { // normal input - CTPDescriptor* desc = new CTPDescriptor; - desc->name = token; - mDescriptors.push_back(*desc); - cls.descriptorIndex = mDescriptors.size() - 1; + // std::cout << "Normal input" << std::endl; + if (cls.descriptorIndex == 0xff) { + CTPDescriptor desc; + desc.name = token; + mDescriptors.push_back(desc); + cls.descriptorIndex = mDescriptors.size() - 1; + } else { + CTPDescriptor desc = mDescriptors.at(cls.descriptorIndex); + desc.name += " " + token; + } + LOG(info) << "Class input descriptor:" << mDescriptors[mDescriptors.size() - 1].name; } else if (token.find("0x") != std::string::npos) { // downscale + // std::cout << "Downscale" << std::endl; + cls.downScale = std::stoul(token, nullptr, 16); } else { // mask + // std::cout << "Mask" << std::endl; int i = 0; for (auto const& bcm : mBCMasks) { if (bcm.name == token) { + cls.BCClassMask.push_back(&bcm); LOG(info) << "Class BCMask found:" << token; break; } @@ -338,9 +395,6 @@ int CTPConfiguration::processConfigurationLineRun3(std::string& line, int& level LOG(info) << "unknown line:" << line; } } - for (auto& cls : mCTPClasses) { - cls.cluster = &mClusters[cls.clusterIndex]; - } return 0; } void CTPConfiguration::printStream(std::ostream& stream) const @@ -372,7 +426,7 @@ void CTPConfiguration::printStream(std::ostream& stream) const i.printStream(stream); } } -uint64_t CTPConfiguration::getInputMask(const std::string& name) +uint64_t CTPConfiguration::getInputMask(const std::string& name) const { for (auto const& inp : mInputs) { if (inp.name == name) { @@ -381,6 +435,15 @@ uint64_t CTPConfiguration::getInputMask(const std::string& name) } return 0; } +int CTPConfiguration::getInputIndex(const std::string& name) const +{ + const CTPInput* inp = isInputInConfig(name); + if (inp == nullptr) { + return 0xff; + } else { + return inp->getIndex(); + } +} bool CTPConfiguration::isMaskInInputs(const uint64_t& mask) const { for (auto const& inp : mInputs) { @@ -399,15 +462,48 @@ bool CTPConfiguration::isBCMaskInConfig(const std::string maskname) const } return false; } -CTPInput* CTPConfiguration::isInputInConfig(const std::string inpname) +const CTPInput* CTPConfiguration::isInputInConfig(const std::string inpname) const { - for (auto& inp : mInputs) { + for (const auto& inp : mInputs) { if (inp.name == inpname) { return &inp; } } return nullptr; } +const CTPInput* CTPConfiguration::isInputInConfig(const int index) const +{ + for (const auto& inp : mInputs) { + // std::cout << "isInputINConfig:" << inp.name << " " << inp.getIndex() << " " << index << std::endl; + if (inp.getIndex() == index) { + LOG(info) << "Found input:" << inp.name << " index:" << inp.getIndex(); + return &inp; + } + } + return nullptr; +} +void CTPConfiguration::createInputsInDecriptorsFromNames() +// using run3 conventions for inputs +{ + for (auto& des : mDescriptors) { + if (CTPConfiguration::isNumber(des.name)) { + // parse here if more inputs + uint32_t index = std::stoul(des.name); + if (index > 100) { + index = index - 100; + } + // CTPInput* inp = const_cast(isInputInConfig(index)); + const CTPInput* inp = isInputInConfig(index); + if (inp) { + des.inputs.push_back(inp); + } else { + LOG(warning) << "Descriptor not found:" << des.name; + } + } else { + LOG(info) << "Input is not a number:" << des.name; + } + } +} uint64_t CTPConfiguration::getDecrtiptorInputsMask(const std::string& name) const { for (auto const& desc : mDescriptors) { @@ -461,6 +557,20 @@ o2::detectors::DetID::mask_t CTPConfiguration::getDetectorMask() const } return mask; } +uint64_t CTPConfiguration::getClassMaskForInput(int inputindex) const +{ + uint64_t clsmask = 0; + for (auto const& cls : mCTPClasses) { + clsmask += cls.getClassMaskForInput(inputindex); + } + return clsmask; +} +uint64_t CTPConfiguration::getClassMaskForInput(const std::string& name) const +{ + uint64_t clsmask = 0; + int index = getInputIndex(name); + return getClassMaskForInput(index); +} //=============================================== // void CTPRunManager::init() @@ -473,9 +583,9 @@ void CTPRunManager::init() LOG(info) << "CTP QC:" << mQC; LOG(info) << "CTPRunManager initialised."; } -int CTPRunManager::startRun(const std::string& cfg) +int CTPRunManager::loadRun(const std::string& cfg) { - LOG(info) << "Starting run: " << cfg; + LOG(info) << "Loading run: " << cfg; const auto now = std::chrono::system_clock::now(); const long timeStamp = std::chrono::duration_cast(now.time_since_epoch()).count(); CTPActiveRun* activerun = new CTPActiveRun; @@ -483,15 +593,20 @@ int CTPRunManager::startRun(const std::string& cfg) activerun->cfg.loadConfigurationRun3(cfg); activerun->cfg.printStream(std::cout); // - activerun->scalers.setRunNumber(activerun->cfg.getRunNumber()); + uint32_t runnumber = activerun->cfg.getRunNumber(); + activerun->scalers.setRunNumber(runnumber); activerun->scalers.setClassMask(activerun->cfg.getTriggerClassMask()); o2::detectors::DetID::mask_t detmask = activerun->cfg.getDetectorMask(); activerun->scalers.setDetectorMask(detmask); // - mRunInStart = activerun; + mRunsLoaded[runnumber] = activerun; saveRunConfigToCCDB(&activerun->cfg, timeStamp); return 0; } +int CTPRunManager::startRun(const std::string& cfg) +{ + return 0; +} int CTPRunManager::stopRun(uint32_t irun) { LOG(info) << "Stopping run index: " << irun; @@ -545,10 +660,10 @@ int CTPRunManager::addScalers(uint32_t irun, std::time_t time) bool detin = (detmask & deti).count(); if (detin) { std::string detname(o2::detectors::DetID::getName(i)); - std::string countername = detname + CTPConfiguration::detName2LTG.at(detname) + "_PH"; + std::string countername = "ltg" + CTPConfiguration::detName2LTG.at(detname) + "_PH"; uint32_t detcount = mCounters[mScalerName2Position[countername]]; scalrec.scalersDets.push_back(detcount); - LOG(info) << "Scaler for detector:" << countername << ":" << detcount; + // LOG(info) << "Scaler for detector:" << countername << ":" << detcount; } } // @@ -570,8 +685,7 @@ int CTPRunManager::processMessage(std::string& topic, const std::string& message std::string firstcounters; if (topic.find("ctpconfig") != std::string::npos) { LOG(info) << "ctpcfg received"; - startRun(message); - mCtpcfg = 1; + loadRun(message); return 0; } if (topic.find("sox") != std::string::npos) { @@ -583,13 +697,8 @@ int CTPRunManager::processMessage(std::string& topic, const std::string& message return 1; } LOG(info) << "SOX received, Run keyword position:" << irun; - if (mCtpcfg == 0) { - std::string cfg = message.substr(irun, message.size() - irun); - LOG(info) << "Config:" << cfg; - startRun(cfg); - } else { - mCtpcfg = 0; - } + std::string cfg = message.substr(irun, message.size() - irun); + startRun(cfg); firstcounters = message.substr(0, irun); } if (topic.find("eox") != std::string::npos) { @@ -628,13 +737,15 @@ int CTPRunManager::processMessage(std::string& topic, const std::string& message addScalers(i, tt); } else if ((mCounters[i] != 0) && (mActiveRunNumbers[i] == 0)) { LOG(info) << "Run started:" << mCounters[i]; - mActiveRunNumbers[i] = mCounters[i]; - if (mRunInStart == nullptr) { - LOG(error) << "Internal error in processMessage: nullptr != 0 expected"; + auto run = mRunsLoaded.find(mCounters[i]); + if (run != mRunsLoaded.end()) { + mActiveRunNumbers[i] = mCounters[i]; + mActiveRuns[i] = run->second; + mRunsLoaded.erase(run); + addScalers(i, tt); + } else { + LOG(error) << "Trying to start run which is not loaded:" << mCounters[i]; } - mActiveRuns[i] = mRunInStart; - mRunInStart = nullptr; - addScalers(i, tt); } else if ((mCounters[i] == 0) && (mActiveRunNumbers[i] != 0)) { if (mEOX != 1) { LOG(error) << "Internal error in processMessage: mEOX != 1 expected 0: mEOX:" << mEOX; @@ -656,6 +767,10 @@ void CTPRunManager::printActiveRuns() const for (auto const& arun : mActiveRunNumbers) { std::cout << arun << " "; } + std::cout << " #loaded runs:" << mRunsLoaded.size(); + for (auto const& lrun : mRunsLoaded) { + std::cout << " " << lrun.second->cfg.getRunNumber(); + } std::cout << std::endl; } int CTPRunManager::saveRunScalersToCCDB(int i) diff --git a/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h b/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h index 3dd5ff53ead84..6416a1f390928 100644 --- a/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h +++ b/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h @@ -202,7 +202,7 @@ class AODProducerWorkflowDPL : public Task uint32_t mV0Amplitude = 0xFFFFF000; // 11 bits uint32_t mFDDAmplitude = 0xFFFFF000; // 11 bits uint32_t mT0Amplitude = 0xFFFFF000; // 11 bits - + int mCTPReadout = 0; // 0 = use CTP readout from CTP; 1 = create CTP readout // helper struct for extra info in fillTrackTablesPerCollision() struct TrackExtraInfo { float tpcInnerParam = 0.f; @@ -286,13 +286,12 @@ class AODProducerWorkflowDPL : public Task void addRefGlobalBCsForTOF(const o2::dataformats::VtxTrackRef& trackRef, const gsl::span& GIndices, const o2::globaltracking::RecoContainer& data, std::map& bcsMap); - + void createCTPReadout(const o2::globaltracking::RecoContainer& recoData, std::vector& ctpDigits, ProcessingContext& pc); void collectBCs(const o2::globaltracking::RecoContainer& data, const std::vector& mcRecords, std::map& bcsMap); uint64_t getTFNumber(const o2::InteractionRecord& tfStartIR, int runNumber); - template void addToTracksTable(TracksCursorType& tracksCursor, TracksCovCursorType& tracksCovCursor, const o2::track::TrackParCov& track, int collisionID); diff --git a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx index ec008edd39478..1da3dd9054d8d 100644 --- a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx +++ b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx @@ -16,6 +16,7 @@ #include "DataFormatsFDD/RecPoint.h" #include "DataFormatsGlobalTracking/RecoContainer.h" #include "DataFormatsCTP/Digits.h" +#include "DataFormatsCTP/Configuration.h" #include "DataFormatsITS/TrackITS.h" #include "DataFormatsMCH/ROFRecord.h" #include "DataFormatsMCH/TrackMCH.h" @@ -23,6 +24,7 @@ #include "DataFormatsMID/Track.h" #include "DataFormatsMFT/TrackMFT.h" #include "DataFormatsTPC/TrackTPC.h" +#include "DataFormatsTRD/TriggerRecord.h" #include "DataFormatsZDC/ZDCEnergy.h" #include "DataFormatsZDC/ZDCTDCData.h" #include "DataFormatsParameters/GRPECSObject.h" @@ -92,6 +94,56 @@ using SMatrix55Sym = ROOT::Math::SMatrix& ctpDigits, ProcessingContext& pc) +{ + // Extraxt CTP Config from CCDB + const auto ctpcfg = pc.inputs().get("ctpconfig"); + // o2::ctp::CTPConfiguration ctpcfg = o2::ctp::CTPRunManager::getConfigFromCCDB(-1, std::to_string(runNumber)); // how to get run + // Extract inputs from recoData + std::map bcsMapT0triggers; + std::map bcsMapTRDreadout; + // const auto& fddRecPoints = recoData.getFDDRecPoints(); + // const auto& fv0RecPoints = recoData.getFV0RecPoints(); + const auto& caloEMCCellsTRGR = recoData.getEMCALTriggers(); + const auto& caloPHOSCellsTRGR = recoData.getPHOSTriggers(); + const auto& triggerrecordTRD = recoData.getTRDTriggerRecords(); + // + const auto& ft0RecPoints = recoData.getFT0RecPoints(); + for (auto& ft0RecPoint : ft0RecPoints) { + auto t0triggers = ft0RecPoint.getTrigger(); + if (t0triggers.getVertex()) { + uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong(); + uint64_t classmask = ctpcfg->getClassMaskForInput("MTVX"); + bcsMapT0triggers[globalBC] = classmask; + } + } + // find trd redaout and add CTPDigit if trigger there + int cntwarnings = 0; + uint32_t orbitPrev = 0; + uint16_t bcPrev = 0; + for (auto& trdrec : triggerrecordTRD) { + auto orbitPrevT = orbitPrev; + auto bcPrevT = bcPrev; + bcPrev = trdrec.getBCData().bc; + orbitPrev = trdrec.getBCData().orbit; + if (orbitPrev < orbitPrevT || bcPrev >= o2::constants::lhc::LHCMaxBunches || (orbitPrev == orbitPrevT && bcPrev < bcPrevT)) { + cntwarnings++; + // LOGP(warning, "Bogus TRD trigger at bc:{}/orbit:{} (previous was {}/{}), with {} tracklets and {} digits",bcPrev, orbitPrev, bcPrevT, orbitPrevT, trig.getNumberOfTracklets(), trig.getNumberOfDigits()); + } else { + uint64_t globalBC = trdrec.getBCData().toLong(); + auto t0entry = bcsMapT0triggers.find(globalBC); + if (t0entry != bcsMapT0triggers.end()) { + auto& ctpdig = ctpDigits.emplace_back(); + ctpdig.intRecord.setFromLong(globalBC); + ctpdig.CTPClassMask = t0entry->second; + } else { + LOG(warning) << "Found trd and no MTVX:" << globalBC; + } + } + } + LOG(info) << "# of TRD bogus triggers:" << cntwarnings; +} + void AODProducerWorkflowDPL::collectBCs(const o2::globaltracking::RecoContainer& data, const std::vector& mcRecords, std::map& bcsMap) @@ -1096,6 +1148,7 @@ void AODProducerWorkflowDPL::init(InitContext& ic) mRecoOnly = ic.options().get("reco-mctracks-only"); mTruncate = ic.options().get("enable-truncation"); mRunNumber = ic.options().get("run-number"); + mCTPReadout = ic.options().get("ctpreadout-create"); if (mTFNumber == -1L) { LOG(info) << "TFNumber will be obtained from CCDB"; @@ -1212,9 +1265,13 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc) auto caloPHOSCells = recoData.getPHOSCells(); auto caloPHOSCellsTRGR = recoData.getPHOSTriggers(); - auto ctpDigits = recoData.getCTPDigits(); - + const auto& tinfo = pc.services().get(); + std::vector ctpDigitsCreated; + if (mCTPReadout == 1) { + createCTPReadout(recoData, ctpDigitsCreated, pc); + ctpDigits = gsl::span(ctpDigitsCreated); + } LOG(debug) << "FOUND " << primVertices.size() << " primary vertices"; LOG(debug) << "FOUND " << ft0RecPoints.size() << " FT0 rec. points"; LOG(debug) << "FOUND " << fv0RecPoints.size() << " FV0 rec. points"; @@ -1276,8 +1333,6 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc) auto caloCellsTRGTableCursor = caloCellsTRGTableBuilder.cursor(); auto originCursor = originTableBuilder.cursor(); - const auto& tinfo = pc.services().get(); - std::unique_ptr mcReader; if (mUseMC) { mcReader = std::make_unique("collisioncontext.root"); @@ -2030,6 +2085,8 @@ DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, boo std::vector outputs; auto dataRequest = std::make_shared(); + dataRequest->inputs.emplace_back("ctpconfig", "CTP", "CTPCONFIG", 0, Lifetime::Condition, ccdbParamSpec("CTP/Config/Config")); + dataRequest->requestTracks(src, useMC); dataRequest->requestPrimaryVertertices(useMC); if (src[GID::CTP]) { @@ -2099,7 +2156,8 @@ DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, boo ConfigParamSpec{"anchor-pass", VariantType::String, "", {"AnchorPassName"}}, ConfigParamSpec{"anchor-prod", VariantType::String, "", {"AnchorProduction"}}, ConfigParamSpec{"reco-pass", VariantType::String, "", {"RecoPassName"}}, - ConfigParamSpec{"reco-mctracks-only", VariantType::Int, 0, {"Store only reconstructed MC tracks and their mothers/daughters. 0 -- off, != 0 -- on"}}}}; + ConfigParamSpec{"reco-mctracks-only", VariantType::Int, 0, {"Store only reconstructed MC tracks and their mothers/daughters. 0 -- off, != 0 -- on"}}, + ConfigParamSpec{"ctpreadout-create", VariantType::Int, 0, {"Create CTP digits from detector readout and CTP inputs. !=1 -- off, 1 -- on"}}}}; } } // namespace o2::aodproducer diff --git a/Detectors/CTP/macro/CreateCTPConfig.C b/Detectors/CTP/macro/CreateCTPConfig.C index a3238ae48fd73..467db02ef7f0b 100644 --- a/Detectors/CTP/macro/CreateCTPConfig.C +++ b/Detectors/CTP/macro/CreateCTPConfig.C @@ -24,15 +24,16 @@ #include #endif using namespace o2::ctp; -CTPConfiguration CreateCTPConfig() +CTPConfiguration CreateCTPConfig(std::string cfgRun3str = "", int writeToFile = 0) { /// Demo configuration CTPConfiguration ctpcfg; // // run3 config // - std::string cfgRun3str = - "bcm TOF 100 1288 2476 \n \ + if (cfgRun3str.find(".rcfg") == std::string::npos) { + cfgRun3str = + "bcm TOF 100 1288 2476 \n \ bcm PHYS 1226 \n\ bcd10 1khz \n\ bcd20 0 \n\ @@ -57,8 +58,25 @@ ferst 1 \n\ 2 cl_1khz bcd10 \n \ 3 cluster clu4 emc cpv \n \ 4 cl_5khz bcd20 \n"; + } else { + std::string filename = cfgRun3str; + std::ifstream in; + in.open(filename); + if (!in) { + std::cout << "Can not open file:" << filename << std::endl; + exit(1); + } + std::stringstream buffer; + buffer << in.rdbuf(); + cfgRun3str = buffer.str(); + } // ctpcfg.loadConfigurationRun3(cfgRun3str); ctpcfg.printStream(std::cout); + if (writeToFile == 1) { + std::unique_ptr myFile(TFile::Open("CTPConfig.root", "RECREATE")); + myFile->WriteObject(&ctpcfg, "CTPConfig"); + std::cout << "File CTPConfig.root written." << std::endl; + } return ctpcfg; } diff --git a/Detectors/CTP/simulation/src/Digitizer.cxx b/Detectors/CTP/simulation/src/Digitizer.cxx index 0b6f3c7d969ce..2980537e201bb 100644 --- a/Detectors/CTP/simulation/src/Digitizer.cxx +++ b/Detectors/CTP/simulation/src/Digitizer.cxx @@ -110,6 +110,8 @@ void Digitizer::init() } auto& mgr = o2::ccdb::BasicCCDBManager::instance(); mgr.setURL(mCCDBServer); - mCTPConfiguration = mgr.get(o2::ctp::CCDBPathCTPConfig); + map metadata = {}; + long timestamp = 1546300800000; + mCTPConfiguration = mgr.getSpecific(o2::ctp::CCDBPathCTPConfig, timestamp, metadata); LOG(info) << " @@@ CTP Digitizer:: CCDB connected " << std::endl; } diff --git a/Detectors/CTP/workflowScalers/CMakeLists.txt b/Detectors/CTP/workflowScalers/CMakeLists.txt index b076c016e0ac3..716da7e596482 100644 --- a/Detectors/CTP/workflowScalers/CMakeLists.txt +++ b/Detectors/CTP/workflowScalers/CMakeLists.txt @@ -4,3 +4,9 @@ o2_add_executable( SOURCES src/ctp-proxy.cxx PUBLIC_LINK_LIBRARIES O2::DCStestWorkflow O2::DataFormatsCTP) +o2_add_executable( + qc-proxy + COMPONENT_NAME ctp + SOURCES src/ctp-qc-proxy.cxx + PUBLIC_LINK_LIBRARIES O2::DCStestWorkflow + O2::DataFormatsCTP) diff --git a/Detectors/CTP/workflowScalers/py/scalersCTP_v1.txt b/Detectors/CTP/workflowScalers/py/scalersCTP_v1.txt new file mode 100644 index 0000000000000..d9fda125f4306 --- /dev/null +++ b/Detectors/CTP/workflowScalers/py/scalersCTP_v1.txt @@ -0,0 +1,1070 @@ +names: "runn0" +names: "runn1" +names: "runn2" +names: "runn3" +names: "runn4" +names: "runn5" +names: "runn6" +names: "runn7" +names: "runn8" +names: "runn9" +names: "runn10" +names: "runn11" +names: "runn12" +names: "runn13" +names: "runn14" +names: "runn15" +names: "ltg1_ORB" +names: "ltg1_HB" +names: "ltg1_HBr" +names: "ltg1_HC" +names: "ltg1_PH" +names: "ltg1_PP" +names: "ltg1_CAL" +names: "ltg1_SOT" +names: "ltg1_EOT" +names: "ltg1_SOC" +names: "ltg1_EOC" +names: "ltg1_TF" +names: "ltg1_FERST" +names: "ltg1_RT" +names: "ltg1_RS" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "ltg1_GAP1" +names: "ltg1_GAP2" +names: "ltg1_TPC_sync" +names: "ltg1_TPC_rst" +names: "ltg1_TOF" +names: "ltg2_ORB" +names: "ltg2_HB" +names: "ltg2_HBr" +names: "ltg2_HC" +names: "ltg2_PH" +names: "ltg2_PP" +names: "ltg2_CAL" +names: "ltg2_SOT" +names: "ltg2_EOT" +names: "ltg2_SOC" +names: "ltg2_EOC" +names: "ltg2_TF" +names: "ltg2_FERST" +names: "ltg2_RT" +names: "ltg2_RS" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "ltg2_GAP1" +names: "ltg2_GAP2" +names: "ltg2_TPC_sync" +names: "ltg2_TPC_rst" +names: "ltg2_TOF" +names: "ltg3_ORB" +names: "ltg3_HB" +names: "ltg3_HBr" +names: "ltg3_HC" +names: "ltg3_PH" +names: "ltg3_PP" +names: "ltg3_CAL" +names: "ltg3_SOT" +names: "ltg3_EOT" +names: "ltg3_SOC" +names: "ltg3_EOC" +names: "ltg3_TF" +names: "ltg3_FERST" +names: "ltg3_RT" +names: "ltg3_RS" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "ltg3_GAP1" +names: "ltg3_GAP2" +names: "ltg3_TPC_sync" +names: "ltg3_TPC_rst" +names: "ltg3_TOF" +names: "ltg4_ORB" +names: "ltg4_HB" +names: "ltg4_HBr" +names: "ltg4_HC" +names: "ltg4_PH" +names: "ltg4_PP" +names: "ltg4_CAL" +names: "ltg4_SOT" +names: "ltg4_EOT" +names: "ltg4_SOC" +names: "ltg4_EOC" +names: "ltg4_TF" +names: "ltg4_FERST" +names: "ltg4_RT" +names: "ltg4_RS" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "ltg4_GAP1" +names: "ltg4_GAP2" +names: "ltg4_TPC_sync" +names: "ltg4_TPC_rst" +names: "ltg4_TOF" +names: "ltg5_ORB" +names: "ltg5_HB" +names: "ltg5_HBr" +names: "ltg5_HC" +names: "ltg5_PH" +names: "ltg5_PP" +names: "ltg5_CAL" +names: "ltg5_SOT" +names: "ltg5_EOT" +names: "ltg5_SOC" +names: "ltg5_EOC" +names: "ltg5_TF" +names: "ltg5_FERST" +names: "ltg5_RT" +names: "ltg5_RS" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "ltg5_GAP1" +names: "ltg5_GAP2" +names: "ltg5_TPC_sync" +names: "ltg5_TPC_rst" +names: "ltg5_TOF" +names: "ltg6_ORB" +names: "ltg6_HB" +names: "ltg6_HBr" +names: "ltg6_HC" +names: "ltg6_PH" +names: "ltg6_PP" +names: "ltg6_CAL" +names: "ltg6_SOT" +names: "ltg6_EOT" +names: "ltg6_SOC" +names: "ltg6_EOC" +names: "ltg6_TF" +names: "ltg6_FERST" +names: "ltg6_RT" +names: "ltg6_RS" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "ltg6_GAP1" +names: "ltg6_GAP2" +names: "ltg6_TPC_sync" +names: "ltg6_TPC_rst" +names: "ltg6_TOF" +names: "ltg7_ORB" +names: "ltg7_HB" +names: "ltg7_HBr" +names: "ltg7_HC" +names: "ltg7_PH" +names: "ltg7_PP" +names: "ltg7_CAL" +names: "ltg7_SOT" +names: "ltg7_EOT" +names: "ltg7_SOC" +names: "ltg7_EOC" +names: "ltg7_TF" +names: "ltg7_FERST" +names: "ltg7_RT" +names: "ltg7_RS" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "ltg7_GAP1" +names: "ltg7_GAP2" +names: "ltg7_TPC_sync" +names: "ltg7_TPC_rst" +names: "ltg7_TOF" +names: "ltg8_ORB" +names: "ltg8_HB" +names: "ltg8_HBr" +names: "ltg8_HC" +names: "ltg8_PH" +names: "ltg8_PP" +names: "ltg8_CAL" +names: "ltg8_SOT" +names: "ltg8_EOT" +names: "ltg8_SOC" +names: "ltg8_EOC" +names: "ltg8_TF" +names: "ltg8_FERST" +names: "ltg8_RT" +names: "ltg8_RS" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "ltg8_GAP1" +names: "ltg8_GAP2" +names: "ltg8_TPC_sync" +names: "ltg8_TPC_rst" +names: "ltg8_TOF" +names: "ltg9_ORB" +names: "ltg9_HB" +names: "ltg9_HBr" +names: "ltg9_HC" +names: "ltg9_PH" +names: "ltg9_PP" +names: "ltg9_CAL" +names: "ltg9_SOT" +names: "ltg9_EOT" +names: "ltg9_SOC" +names: "ltg9_EOC" +names: "ltg9_TF" +names: "ltg9_FERST" +names: "ltg9_RT" +names: "ltg9_RS" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "ltg9_GAP1" +names: "ltg9_GAP2" +names: "ltg9_TPC_sync" +names: "ltg9_TPC_rst" +names: "ltg9_TOF" +names: "ltg10_ORB" +names: "ltg10_HB" +names: "ltg10_HBr" +names: "ltg10_HC" +names: "ltg10_PH" +names: "ltg10_PP" +names: "ltg10_CAL" +names: "ltg10_SOT" +names: "ltg10_EOT" +names: "ltg10_SOC" +names: "ltg10_EOC" +names: "ltg10_TF" +names: "ltg10_FERST" +names: "ltg10_RT" +names: "ltg10_RS" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "ltg10_GAP1" +names: "ltg10_GAP2" +names: "ltg10_TPC_sync" +names: "ltg10_TPC_rst" +names: "ltg10_TOF" +names: "ltg11_ORB" +names: "ltg11_HB" +names: "ltg11_HBr" +names: "ltg11_HC" +names: "ltg11_PH" +names: "ltg11_PP" +names: "ltg11_CAL" +names: "ltg11_SOT" +names: "ltg11_EOT" +names: "ltg11_SOC" +names: "ltg11_EOC" +names: "ltg11_TF" +names: "ltg11_FERST" +names: "ltg11_RT" +names: "ltg11_RS" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "ltg11_GAP1" +names: "ltg11_GAP2" +names: "ltg11_TPC_sync" +names: "ltg11_TPC_rst" +names: "ltg11_TOF" +names: "ltg12_ORB" +names: "ltg12_HB" +names: "ltg12_HBr" +names: "ltg12_HC" +names: "ltg12_PH" +names: "ltg12_PP" +names: "ltg12_CAL" +names: "ltg12_SOT" +names: "ltg12_EOT" +names: "ltg12_SOC" +names: "ltg12_EOC" +names: "ltg12_TF" +names: "ltg12_FERST" +names: "ltg12_RT" +names: "ltg12_RS" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "ltg12_GAP1" +names: "ltg12_GAP2" +names: "ltg12_TPC_sync" +names: "ltg12_TPC_rst" +names: "ltg12_TOF" +names: "ltg13_ORB" +names: "ltg13_HB" +names: "ltg13_HBr" +names: "ltg13_HC" +names: "ltg13_PH" +names: "ltg13_PP" +names: "ltg13_CAL" +names: "ltg13_SOT" +names: "ltg13_EOT" +names: "ltg13_SOC" +names: "ltg13_EOC" +names: "ltg13_TF" +names: "ltg13_FERST" +names: "ltg13_RT" +names: "ltg13_RS" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "ltg13_GAP1" +names: "ltg13_GAP2" +names: "ltg13_TPC_sync" +names: "ltg13_TPC_rst" +names: "ltg13_TOF" +names: "ltg14_ORB" +names: "ltg14_HB" +names: "ltg14_HBr" +names: "ltg14_HC" +names: "ltg14_PH" +names: "ltg14_PP" +names: "ltg14_CAL" +names: "ltg14_SOT" +names: "ltg14_EOT" +names: "ltg14_SOC" +names: "ltg14_EOC" +names: "ltg14_TF" +names: "ltg14_FERST" +names: "ltg14_RT" +names: "ltg14_RS" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "ltg14_GAP1" +names: "ltg14_GAP2" +names: "ltg14_TPC_sync" +names: "ltg14_TPC_rst" +names: "ltg14_TOF" +names: "ltg15_ORB" +names: "ltg15_HB" +names: "ltg15_HBr" +names: "ltg15_HC" +names: "ltg15_PH" +names: "ltg15_PP" +names: "ltg15_CAL" +names: "ltg15_SOT" +names: "ltg15_EOT" +names: "ltg15_SOC" +names: "ltg15_EOC" +names: "ltg15_TF" +names: "ltg15_FERST" +names: "ltg15_RT" +names: "ltg15_RS" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "ltg15_GAP1" +names: "ltg15_GAP2" +names: "ltg15_TPC_sync" +names: "ltg15_TPC_rst" +names: "ltg15_TOF" +names: "ltg16_ORB" +names: "ltg16_HB" +names: "ltg16_HBr" +names: "ltg16_HC" +names: "ltg16_PH" +names: "ltg16_PP" +names: "ltg16_CAL" +names: "ltg16_SOT" +names: "ltg16_EOT" +names: "ltg16_SOC" +names: "ltg16_EOC" +names: "ltg16_TF" +names: "ltg16_FERST" +names: "ltg16_RT" +names: "ltg16_RS" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "ltg16_GAP1" +names: "ltg16_GAP2" +names: "ltg16_TPC_sync" +names: "ltg16_TPC_rst" +names: "ltg16_TOF" +names: "ltg17_ORB" +names: "ltg17_HB" +names: "ltg17_HBr" +names: "ltg17_HC" +names: "ltg17_PH" +names: "ltg17_PP" +names: "ltg17_CAL" +names: "ltg17_SOT" +names: "ltg17_EOT" +names: "ltg17_SOC" +names: "ltg17_EOC" +names: "ltg17_TF" +names: "ltg17_FERST" +names: "ltg17_RT" +names: "ltg17_RS" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "ltg17_GAP1" +names: "ltg17_GAP2" +names: "ltg17_TPC_sync" +names: "ltg17_TPC_rst" +names: "ltg17_TOF" +names: "ltg18_ORB" +names: "ltg18_HB" +names: "ltg18_HBr" +names: "ltg18_HC" +names: "ltg18_PH" +names: "ltg18_PP" +names: "ltg18_CAL" +names: "ltg18_SOT" +names: "ltg18_EOT" +names: "ltg18_SOC" +names: "ltg18_EOC" +names: "ltg18_TF" +names: "ltg18_FERST" +names: "ltg18_RT" +names: "ltg18_RS" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "" +names: "ltg18_GAP1" +names: "ltg18_GAP2" +names: "ltg18_TPC_sync" +names: "ltg18_TPC_rst" +names: "ltg18_TOF" +names: "bc40" +names: "clk240" +names: "extorb" +names: "PLSRin" +names: "FastLMin" +names: "BUSYin" +names: "SPAREin" +names: "inp1" +names: "inp2" +names: "inp3" +names: "inp4" +names: "inp5" +names: "inp6" +names: "inp7" +names: "inp8" +names: "inp9" +names: "inp10" +names: "inp11" +names: "inp12" +names: "inp13" +names: "inp14" +names: "inp15" +names: "inp16" +names: "inp17" +names: "inp18" +names: "inp19" +names: "inp20" +names: "inp21" +names: "inp22" +names: "inp23" +names: "inp24" +names: "inp25" +names: "inp26" +names: "inp27" +names: "inp28" +names: "inp29" +names: "inp30" +names: "inp31" +names: "inp32" +names: "inp33" +names: "inp34" +names: "inp35" +names: "inp36" +names: "inp37" +names: "inp38" +names: "inp39" +names: "inp40" +names: "inp41" +names: "inp42" +names: "inp43" +names: "inp44" +names: "inp45" +names: "inp46" +names: "inp47" +names: "inp48" +names: "clamb1" +names: "clamb2" +names: "clamb3" +names: "clamb4" +names: "clamb5" +names: "clamb6" +names: "clamb7" +names: "clamb8" +names: "clamb9" +names: "clamb10" +names: "clamb11" +names: "clamb12" +names: "clamb13" +names: "clamb14" +names: "clamb15" +names: "clamb16" +names: "clamb17" +names: "clamb18" +names: "clamb19" +names: "clamb20" +names: "clamb21" +names: "clamb22" +names: "clamb23" +names: "clamb24" +names: "clamb25" +names: "clamb26" +names: "clamb27" +names: "clamb28" +names: "clamb29" +names: "clamb30" +names: "clamb31" +names: "clamb32" +names: "clamb33" +names: "clamb34" +names: "clamb35" +names: "clamb36" +names: "clamb37" +names: "clamb38" +names: "clamb39" +names: "clamb40" +names: "clamb41" +names: "clamb42" +names: "clamb43" +names: "clamb44" +names: "clamb45" +names: "clamb46" +names: "clamb47" +names: "clamb48" +names: "clamb49" +names: "clamb50" +names: "clamb51" +names: "clamb52" +names: "clamb53" +names: "clamb54" +names: "clamb55" +names: "clamb56" +names: "clamb57" +names: "clamb58" +names: "clamb59" +names: "clamb60" +names: "clamb61" +names: "clamb62" +names: "clamb63" +names: "clamb64" +names: "clama1" +names: "clama2" +names: "clama3" +names: "clama4" +names: "clama5" +names: "clama6" +names: "clama7" +names: "clama8" +names: "clama9" +names: "clama10" +names: "clama11" +names: "clama12" +names: "clama13" +names: "clama14" +names: "clama15" +names: "clama16" +names: "clama17" +names: "clama18" +names: "clama19" +names: "clama20" +names: "clama21" +names: "clama22" +names: "clama23" +names: "clama24" +names: "clama25" +names: "clama26" +names: "clama27" +names: "clama28" +names: "clama29" +names: "clama30" +names: "clama31" +names: "clama32" +names: "clama33" +names: "clama34" +names: "clama35" +names: "clama36" +names: "clama37" +names: "clama38" +names: "clama39" +names: "clama40" +names: "clama41" +names: "clama42" +names: "clama43" +names: "clama44" +names: "clama45" +names: "clama46" +names: "clama47" +names: "clama48" +names: "clama49" +names: "clama50" +names: "clama51" +names: "clama52" +names: "clama53" +names: "clama54" +names: "clama55" +names: "clama56" +names: "clama57" +names: "clama58" +names: "clama59" +names: "clama60" +names: "clama61" +names: "clama62" +names: "clama63" +names: "clama64" +names: "cla0b1" +names: "cla0b2" +names: "cla0b3" +names: "cla0b4" +names: "cla0b5" +names: "cla0b6" +names: "cla0b7" +names: "cla0b8" +names: "cla0b9" +names: "cla0b10" +names: "cla0b11" +names: "cla0b12" +names: "cla0b13" +names: "cla0b14" +names: "cla0b15" +names: "cla0b16" +names: "cla0b17" +names: "cla0b18" +names: "cla0b19" +names: "cla0b20" +names: "cla0b21" +names: "cla0b22" +names: "cla0b23" +names: "cla0b24" +names: "cla0b25" +names: "cla0b26" +names: "cla0b27" +names: "cla0b28" +names: "cla0b29" +names: "cla0b30" +names: "cla0b31" +names: "cla0b32" +names: "cla0b33" +names: "cla0b34" +names: "cla0b35" +names: "cla0b36" +names: "cla0b37" +names: "cla0b38" +names: "cla0b39" +names: "cla0b40" +names: "cla0b41" +names: "cla0b42" +names: "cla0b43" +names: "cla0b44" +names: "cla0b45" +names: "cla0b46" +names: "cla0b47" +names: "cla0b48" +names: "cla0b49" +names: "cla0b50" +names: "cla0b51" +names: "cla0b52" +names: "cla0b53" +names: "cla0b54" +names: "cla0b55" +names: "cla0b56" +names: "cla0b57" +names: "cla0b58" +names: "cla0b59" +names: "cla0b60" +names: "cla0b61" +names: "cla0b62" +names: "cla0b63" +names: "cla0b64" +names: "cla0a1" +names: "cla0a2" +names: "cla0a3" +names: "cla0a4" +names: "cla0a5" +names: "cla0a6" +names: "cla0a7" +names: "cla0a8" +names: "cla0a9" +names: "cla0a10" +names: "cla0a11" +names: "cla0a12" +names: "cla0a13" +names: "cla0a14" +names: "cla0a15" +names: "cla0a16" +names: "cla0a17" +names: "cla0a18" +names: "cla0a19" +names: "cla0a20" +names: "cla0a21" +names: "cla0a22" +names: "cla0a23" +names: "cla0a24" +names: "cla0a25" +names: "cla0a26" +names: "cla0a27" +names: "cla0a28" +names: "cla0a29" +names: "cla0a30" +names: "cla0a31" +names: "cla0a32" +names: "cla0a33" +names: "cla0a34" +names: "cla0a35" +names: "cla0a36" +names: "cla0a37" +names: "cla0a38" +names: "cla0a39" +names: "cla0a40" +names: "cla0a41" +names: "cla0a42" +names: "cla0a43" +names: "cla0a44" +names: "cla0a45" +names: "cla0a46" +names: "cla0a47" +names: "cla0a48" +names: "cla0a49" +names: "cla0a50" +names: "cla0a51" +names: "cla0a52" +names: "cla0a53" +names: "cla0a54" +names: "cla0a55" +names: "cla0a56" +names: "cla0a57" +names: "cla0a58" +names: "cla0a59" +names: "cla0a60" +names: "cla0a61" +names: "cla0a62" +names: "cla0a63" +names: "cla0a64" +names: "cla1b1" +names: "cla1b2" +names: "cla1b3" +names: "cla1b4" +names: "cla1b5" +names: "cla1b6" +names: "cla1b7" +names: "cla1b8" +names: "cla1b9" +names: "cla1b10" +names: "cla1b11" +names: "cla1b12" +names: "cla1b13" +names: "cla1b14" +names: "cla1b15" +names: "cla1b16" +names: "cla1b17" +names: "cla1b18" +names: "cla1b19" +names: "cla1b20" +names: "cla1b21" +names: "cla1b22" +names: "cla1b23" +names: "cla1b24" +names: "cla1b25" +names: "cla1b26" +names: "cla1b27" +names: "cla1b28" +names: "cla1b29" +names: "cla1b30" +names: "cla1b31" +names: "cla1b32" +names: "cla1b33" +names: "cla1b34" +names: "cla1b35" +names: "cla1b36" +names: "cla1b37" +names: "cla1b38" +names: "cla1b39" +names: "cla1b40" +names: "cla1b41" +names: "cla1b42" +names: "cla1b43" +names: "cla1b44" +names: "cla1b45" +names: "cla1b46" +names: "cla1b47" +names: "cla1b48" +names: "cla1b49" +names: "cla1b50" +names: "cla1b51" +names: "cla1b52" +names: "cla1b53" +names: "cla1b54" +names: "cla1b55" +names: "cla1b56" +names: "cla1b57" +names: "cla1b58" +names: "cla1b59" +names: "cla1b60" +names: "cla1b61" +names: "cla1b62" +names: "cla1b63" +names: "cla1b64" +names: "cla1a1" +names: "cla1a2" +names: "cla1a3" +names: "cla1a4" +names: "cla1a5" +names: "cla1a6" +names: "cla1a7" +names: "cla1a8" +names: "cla1a9" +names: "cla1a10" +names: "cla1a11" +names: "cla1a12" +names: "cla1a13" +names: "cla1a14" +names: "cla1a15" +names: "cla1a16" +names: "cla1a17" +names: "cla1a18" +names: "cla1a19" +names: "cla1a20" +names: "cla1a21" +names: "cla1a22" +names: "cla1a23" +names: "cla1a24" +names: "cla1a25" +names: "cla1a26" +names: "cla1a27" +names: "cla1a28" +names: "cla1a29" +names: "cla1a30" +names: "cla1a31" +names: "cla1a32" +names: "cla1a33" +names: "cla1a34" +names: "cla1a35" +names: "cla1a36" +names: "cla1a37" +names: "cla1a38" +names: "cla1a39" +names: "cla1a40" +names: "cla1a41" +names: "cla1a42" +names: "cla1a43" +names: "cla1a44" +names: "cla1a45" +names: "cla1a46" +names: "cla1a47" +names: "cla1a48" +names: "cla1a49" +names: "cla1a50" +names: "cla1a51" +names: "cla1a52" +names: "cla1a53" +names: "cla1a54" +names: "cla1a55" +names: "cla1a56" +names: "cla1a57" +names: "cla1a58" +names: "cla1a59" +names: "cla1a60" +names: "cla1a61" +names: "cla1a62" +names: "cla1a63" +names: "cla1a64" +names: "l0_trigger" +names: "l1_trigger" +names: "l2_trigger" +names: "clum1" +names: "clum2" +names: "clum3" +names: "clum4" +names: "clum5" +names: "clum6" +names: "clu01" +names: "clu02" +names: "clu03" +names: "clu04" +names: "clu05" +names: "clu06" +names: "clu11" +names: "clu12" +names: "clu13" +names: "clu14" +names: "clu15" +names: "clu16" +names: "ltg1_busy" +names: "ltg2_busy" +names: "ltg3_busy" +names: "ltg4_busy" +names: "ltg5_busy" +names: "ltg6_busy" +names: "ltg7_busy" +names: "ltg8_busy" +names: "ltg9_busy" +names: "ltg10_busy" +names: "ltg11_busy" +names: "ltg12_busy" +names: "ltg13_busy" +names: "ltg14_busy" +names: "ltg15_busy" +names: "ltg16_busy" +names: "ltg17_busy" +names: "ltg18_busy" diff --git a/Detectors/CTP/workflowScalers/src/ctp-proxy.cxx b/Detectors/CTP/workflowScalers/src/ctp-proxy.cxx index f979f6cd969c7..146b01f8c3960 100644 --- a/Detectors/CTP/workflowScalers/src/ctp-proxy.cxx +++ b/Detectors/CTP/workflowScalers/src/ctp-proxy.cxx @@ -23,8 +23,6 @@ // example to run: // default: processing , intermal database // o2-ctp-proxy --ctp-proxy '--channel-config "name=ctp-proxy,type=sub,method=connect,address=tcp://10.161.64.100:50090,rateLogging=5,transport=zeromq"' -b -// no processing -// o2-ctp-proxy --ctp-proxy '--channel-config "name=ctp-proxy,type=sub,method=connect,address=tcp://10.161.64.100:50090,rateLogging=5,transport=zeromq"' --for-qc -b // processing, test database // o2-ctp-proxy --ctp-proxy '--channel-config "name=ctp-proxy,type=sub,method=connect,address=tcp://10.161.64.100:50090,rateLogging=5,transport=zeromq"' '--ccdb-host=http://ccdb-test.cern.ch:8080' -b @@ -47,13 +45,12 @@ using namespace o2::framework; using DetID = o2::detectors::DetID; -InjectorFunction dcs2dpl(bool qc, std::string& ccdbhost) +InjectorFunction dcs2dpl(std::string& ccdbhost) // InjectorFunction dcs2dpl() { auto timesliceId = std::make_shared(0); auto runMgr = std::make_shared(); runMgr->setCCDBHost(ccdbhost); - runMgr->setCTPQC(qc); runMgr->init(); return [timesliceId, runMgr](TimingInfo&, fair::mq::Device& device, fair::mq::Parts& parts, ChannelRetriever channelRetriever) { // make sure just 2 messages received @@ -65,34 +62,7 @@ InjectorFunction dcs2dpl(bool qc, std::string& ccdbhost) size_t dataSize = parts.At(1)->GetSize(); std::string messageData{static_cast(parts.At(1)->GetData()), parts.At(1)->GetSize()}; LOG(info) << "received message " << messageHeader << " of size " << dataSize; // << " Payload:" << messageData; - o2::header::DataHeader hdrF("CTP_COUNTERS", o2::header::gDataOriginCTP, 0); - OutputSpec outsp{hdrF.dataOrigin, hdrF.dataDescription, hdrF.subSpecification}; - auto channel = channelRetriever(outsp, *timesliceId); - if (channel.empty()) { - LOG(error) << "No output channel found for OutputSpec " << outsp; - return; - } runMgr->processMessage(messageHeader, messageData); - hdrF.tfCounter = *timesliceId; // this also - hdrF.payloadSerializationMethod = o2::header::gSerializationMethodNone; - hdrF.splitPayloadParts = 1; - hdrF.splitPayloadIndex = 0; - hdrF.payloadSize = parts.At(1)->GetSize(); - hdrF.firstTForbit = 0; // this should be irrelevant for Counters ? Orbit is in payload - - auto fmqFactory = device.GetChannel(channel).Transport(); - - o2::header::Stack headerStackF{hdrF, DataProcessingHeader{*timesliceId, 1}}; - auto hdMessageF = fmqFactory->CreateMessage(headerStackF.size(), fair::mq::Alignment{64}); - auto plMessageF = fmqFactory->CreateMessage(hdrF.payloadSize, fair::mq::Alignment{64}); - memcpy(hdMessageF->GetData(), headerStackF.data(), headerStackF.size()); - memcpy(plMessageF->GetData(), parts.At(1)->GetData(), hdrF.payloadSize); - - fair::mq::Parts outParts; - outParts.AddPart(std::move(hdMessageF)); - outParts.AddPart(std::move(plMessageF)); - sendOnChannel(device, outParts, channel, *timesliceId); - LOG(info) << "Sent CTP counters DPL message" << std::flush; }; } @@ -100,7 +70,6 @@ InjectorFunction dcs2dpl(bool qc, std::string& ccdbhost) void customize(std::vector& workflowOptions) { workflowOptions.push_back(ConfigParamSpec{"subscribe-to", VariantType::String, "type=sub,method=connect,address=tcp://188.184.30.57:5556,rateLogging=10,transport=zeromq", {"channel subscribe to"}}); - workflowOptions.push_back(ConfigParamSpec{"for-qc", VariantType::Bool, false, {"disable processing messages in run manager"}}); workflowOptions.push_back(ConfigParamSpec{"ccdb-host", VariantType::String, "http://o2-ccdb.internal:8080", {"ccdb host"}}); } @@ -123,7 +92,6 @@ WorkflowSpec defineDataProcessing(ConfigContext const& config) }; const std::string devName = "ctp-proxy"; auto chan = config.options().get("subscribe-to"); - bool qc = config.options().get("for-qc"); std::string ccdbhost = config.options().get("ccdb-host"); if (chan.empty()) { throw std::runtime_error("input channel is not provided"); @@ -139,7 +107,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(qc, ccdbhost)); + dcs2dpl(ccdbhost)); LOG(info) << "===> Proxy done"; WorkflowSpec workflow; workflow.emplace_back(ctpProxy); diff --git a/Detectors/CTP/workflowScalers/src/ctp-qc-proxy.cxx b/Detectors/CTP/workflowScalers/src/ctp-qc-proxy.cxx new file mode 100644 index 0000000000000..e9ea2b6d47ce6 --- /dev/null +++ b/Detectors/CTP/workflowScalers/src/ctp-qc-proxy.cxx @@ -0,0 +1,145 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// example to run: +// default: processing , intermal database +// o2-ctp-qc-proxy --ctp-qc-proxy '--channel-config "name=ctp-qc-proxy,type=sub,method=connect,address=tcp://10.161.64.100:50090,rateLogging=5,transport=zeromq"' -b + +#include "Framework/WorkflowSpec.h" +#include "Framework/DataProcessorSpec.h" +#include "Framework/DataSpecUtils.h" +#include "Framework/ControlService.h" +#include "Framework/Logger.h" +#include "Framework/Lifetime.h" +#include "Framework/ConfigParamSpec.h" +#include "Framework/ExternalFairMQDeviceProxy.h" +#include "DetectorsCommonDataFormats/DetID.h" +#include "Headers/DataHeaderHelpers.h" +#include +#include +#include "CommonUtils/StringUtils.h" +#include +#include + +using namespace o2::framework; +using DetID = o2::detectors::DetID; +InjectorFunction dcs2dpl() +// InjectorFunction dcs2dpl() +{ + auto timesliceId = std::make_shared(0); + return [timesliceId](TimingInfo&, fair::mq::Device& device, fair::mq::Parts& parts, ChannelRetriever channelRetriever) { + // make sure just 2 messages received + if (parts.Size() != 2) { + LOG(error) << "received " << parts.Size() << " instead of 2 expected"; + return; + } + std::string messageHeader{static_cast(parts.At(0)->GetData()), parts.At(0)->GetSize()}; + size_t dataSize = parts.At(1)->GetSize(); + std::string messageData{static_cast(parts.At(1)->GetData()), parts.At(1)->GetSize()}; + LOG(info) << "received message " << messageHeader << " of size " << dataSize; // << " Payload:" << messageData; + o2::header::DataHeader hdrF("CTP_COUNTERS", o2::header::gDataOriginCTP, 0); + OutputSpec outsp{hdrF.dataOrigin, hdrF.dataDescription, hdrF.subSpecification}; + auto channel = channelRetriever(outsp, *timesliceId); + if (channel.empty()) { + LOG(error) << "No output channel found for OutputSpec " << outsp; + return; + } + hdrF.tfCounter = *timesliceId; // this also + hdrF.payloadSerializationMethod = o2::header::gSerializationMethodNone; + hdrF.splitPayloadParts = 1; + hdrF.splitPayloadIndex = 0; + hdrF.payloadSize = parts.At(0)->GetSize() + parts.At(1)->GetSize() + 1; + hdrF.firstTForbit = 0; // this should be irrelevant for Counters ? Orbit is in payload + + auto fmqFactory = device.GetChannel(channel).Transport(); + + o2::header::Stack headerStackF{hdrF, DataProcessingHeader{*timesliceId, 1}}; + auto hdMessageF = fmqFactory->CreateMessage(headerStackF.size(), fair::mq::Alignment{64}); + auto plMessageF = fmqFactory->CreateMessage(hdrF.payloadSize, fair::mq::Alignment{64}); + memcpy(hdMessageF->GetData(), headerStackF.data(), headerStackF.size()); + std::string payload = (messageHeader + " " + messageData); + LOG(info) << messageHeader; + int Nchars = 1000; + if (messageData.size() > Nchars) { + LOG(info) << messageData.substr(0, Nchars); + } else { + LOG(info) << messageData; + } + const char* c = payload.c_str(); + const void* pp = static_cast(c); + memcpy(plMessageF->GetData(), pp, hdrF.payloadSize); + + // + + fair::mq::Parts outParts; + outParts.AddPart(std::move(hdMessageF)); + outParts.AddPart(std::move(plMessageF)); + sendOnChannel(device, outParts, channel, *timesliceId); + LOG(info) << "Sent CTP counters DPL message" << std::flush; + }; +} + +// we need to add workflow options before including Framework/runDataProcessing +void customize(std::vector& workflowOptions) +{ + workflowOptions.push_back(ConfigParamSpec{"subscribe-to", VariantType::String, "type=sub,method=connect,address=tcp://188.184.30.57:5556,rateLogging=10,transport=zeromq", {"channel subscribe to"}}); +} + +#include "Framework/runDataProcessing.h" + +WorkflowSpec defineDataProcessing(ConfigContext const& config) +{ + LOG(info) << "Defining data processing"; + auto setChanName = [](const std::string& chan, const std::string& name) { + size_t n = 0; + if (std::string(chan).find("name=") != std::string::npos) { + n = std::string(chan).find(","); + if (n == std::string::npos) { + throw std::runtime_error(fmt::format("wrongly formatted channel: {}", chan)); + } + n++; + } + LOG(info) << "===>inside:" << name << " " << chan; + return o2::utils::Str::concat_string("name=", name, ",", chan.substr(n, chan.size())); + }; + const std::string devName = "ctp-qc-proxy"; + auto chan = config.options().get("subscribe-to"); + if (chan.empty()) { + throw std::runtime_error("input channel is not provided"); + } + chan = setChanName(chan, devName); + LOG(info) << "name:" << devName << " chan:" << chan; + LOG(info) << "Channels setup: " << chan; + Outputs ctpCountersOutputs; + ctpCountersOutputs.emplace_back("CTP", "CTP_COUNTERS", 0, Lifetime::Timeframe); + LOG(info) << "===> Proxy to be set"; + DataProcessorSpec ctpProxy = specifyExternalFairMQDeviceProxy( + devName.c_str(), + std::move(ctpCountersOutputs), + // this is just default, can be overriden by --ctp-config-proxy '--channel-config..' + chan.c_str(), + dcs2dpl()); + LOG(info) << "===> Proxy done"; + WorkflowSpec workflow; + workflow.emplace_back(ctpProxy); + return workflow; +}