From 9c805c0935b1c4223646fa29ff69998a377a6d46 Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Sun, 29 Jun 2025 18:53:17 +0200 Subject: [PATCH 1/5] [Common] Fuse new evsel with timestamp --- Common/TableProducer/CMakeLists.txt | 5 ++ .../TableProducer/eventSelectionService.cxx | 34 ++++++++---- Common/Tools/EventSelectionTools.h | 54 ++++++++++--------- 3 files changed, 58 insertions(+), 35 deletions(-) diff --git a/Common/TableProducer/CMakeLists.txt b/Common/TableProducer/CMakeLists.txt index 867fbffe856..cdd408d4bff 100644 --- a/Common/TableProducer/CMakeLists.txt +++ b/Common/TableProducer/CMakeLists.txt @@ -59,6 +59,11 @@ o2physics_add_dpl_workflow(timestamp PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(timestamptester + SOURCES timestampTester.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(weak-decay-indices SOURCES weakDecayIndices.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/Common/TableProducer/eventSelectionService.cxx b/Common/TableProducer/eventSelectionService.cxx index 996317e1ab3..cc7773d1ff2 100644 --- a/Common/TableProducer/eventSelectionService.cxx +++ b/Common/TableProducer/eventSelectionService.cxx @@ -24,6 +24,7 @@ #include "Common/Core/trackUtilities.h" #include "Common/DataModel/TrackSelectionTables.h" #include "Common/Tools/EventSelectionTools.h" +#include "Common/Tools/timestampModule.h" #include "CCDB/BasicCCDBManager.h" #include "CCDB/CcdbApi.h" @@ -45,18 +46,22 @@ using namespace o2::framework; MetadataHelper metadataInfo; // Metadata helper -using BCsWithRun2InfosTimestampsAndMatches = soa::Join; -using BCsWithRun3Matchings = soa::Join; +using BCsWithRun2InfosAndMatches = soa::Join; +using BCsWithRun3Matchings = soa::Join; using FullTracks = soa::Join; using FullTracksIU = soa::Join; struct eventselectionRun2 { + o2::common::timestamp::timestampConfigurables timestampConfigurables; + o2::common::timestamp::TimestampModule timestampMod; + o2::common::eventselection::bcselConfigurables bcselOpts; o2::common::eventselection::BcSelectionModule bcselmodule; o2::common::eventselection::evselConfigurables evselOpts; o2::common::eventselection::EventSelectionModule evselmodule; + Produces timestampTable; /// Table with SOR timestamps produced by the task Produces bcsel; Produces evsel; @@ -69,8 +74,8 @@ struct eventselectionRun2 { HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - // the best: have readable cursors - // this: a stopgap solution to avoid spawning yet another device + // buffering intermediate results for passing + std::vector timestamps; std::vector bcselsbuffer; // auxiliary @@ -85,11 +90,12 @@ struct eventselectionRun2 { ccdb->setURL(ccdburl.value); // task-specific + timestampMod.init(timestampConfigurables, metadataInfo); bcselmodule.init(context, bcselOpts, histos); evselmodule.init(context, evselOpts, histos, metadataInfo); } - void process(BCsWithRun2InfosTimestampsAndMatches const& bcs, + void process(BCsWithRun2InfosAndMatches const& bcs, aod::Collisions const& collisions, aod::Zdcs const&, aod::FV0As const&, @@ -98,12 +104,16 @@ struct eventselectionRun2 { aod::FDDs const&, FullTracks const&) { - bcselmodule.processRun2(ccdb, bcs, bcselsbuffer, bcsel); - evselmodule.processRun2(ccdb, histos, collisions, tracklets, cache, bcselsbuffer, evsel); + timestampMod.process(bcs, ccdb, timestamps, timestampTable); + bcselmodule.processRun2(ccdb, bcs, timestamps, bcselsbuffer, bcsel); + evselmodule.processRun2(ccdb, histos, collisions, tracklets, cache, timestamps, bcselsbuffer, evsel); } }; struct eventselectionRun3 { + o2::common::timestamp::timestampConfigurables timestampConfigurables; + o2::common::timestamp::TimestampModule timestampMod; + o2::common::eventselection::bcselConfigurables bcselOpts; o2::common::eventselection::BcSelectionModule bcselmodule; @@ -113,6 +123,7 @@ struct eventselectionRun3 { o2::common::eventselection::lumiConfigurables lumiOpts; o2::common::eventselection::LumiModule lumimodule; + Produces timestampTable; /// Table with SOR timestamps produced by the task Produces bcsel; Produces evsel; @@ -127,6 +138,7 @@ struct eventselectionRun3 { // the best: have readable cursors // this: a stopgap solution to avoid spawning yet another device + std::vector timestamps; std::vector bcselsbuffer; // auxiliary @@ -141,6 +153,7 @@ struct eventselectionRun3 { ccdb->setURL(ccdburl.value); // task-specific + timestampMod.init(timestampConfigurables, metadataInfo); bcselmodule.init(context, bcselOpts, histos); evselmodule.init(context, evselOpts, histos, metadataInfo); lumimodule.init(context, lumiOpts, histos); @@ -154,9 +167,10 @@ struct eventselectionRun3 { aod::FDDs const&, FullTracksIU const&) { - bcselmodule.processRun3(ccdb, histos, bcs, bcselsbuffer, bcsel); - evselmodule.processRun3(ccdb, histos, bcs, collisions, pvTracks, ft0s, cache, bcselsbuffer, evsel); - lumimodule.process(ccdb, histos, bcs, bcselsbuffer); + timestampMod.process(bcs, ccdb, timestamps, timestampTable); + bcselmodule.processRun3(ccdb, histos, bcs, timestamps, bcselsbuffer, bcsel); + evselmodule.processRun3(ccdb, histos, bcs, collisions, pvTracks, ft0s, cache, timestamps, bcselsbuffer, evsel); + lumimodule.process(ccdb, histos, bcs, timestamps, bcselsbuffer); } }; diff --git a/Common/Tools/EventSelectionTools.h b/Common/Tools/EventSelectionTools.h index e7822a61556..5c84a0a00d4 100644 --- a/Common/Tools/EventSelectionTools.h +++ b/Common/Tools/EventSelectionTools.h @@ -264,8 +264,8 @@ class BcSelectionModule } //__________________________________________________ - template - void processRun2(TCCDB const& ccdb, TBCs const& bcs, TBcSelBuffer& bcselbuffer, TBcSelCursor& bcsel) + template + void processRun2(TCCDB const& ccdb, TBCs const& bcs, TTimestamps const& timestamps, TBcSelBuffer& bcselbuffer, TBcSelCursor& bcsel) { if (bcselOpts.amIneeded.value == 0) { bcselbuffer.clear(); @@ -273,8 +273,9 @@ class BcSelectionModule } bcselbuffer.clear(); for (const auto& bc : bcs) { - par = ccdb->template getForTimeStamp("EventSelection/EventSelectionParams", bc.timestamp()); - aliases = ccdb->template getForTimeStamp("EventSelection/TriggerAliases", bc.timestamp()); + auto timestamp = timestamps[bc.globalIndex()]; + par = ccdb->template getForTimeStamp("EventSelection/EventSelectionParams", timestamp); + aliases = ccdb->template getForTimeStamp("EventSelection/TriggerAliases", timestamp); // fill fired aliases uint32_t alias{0}; uint64_t triggerMask = bc.triggerMask(); @@ -401,8 +402,8 @@ class BcSelectionModule } // end processRun2 //__________________________________________________ - template - void processRun3(TCCDB const& ccdb, THistoRegistry& histos, TBCs const& bcs, TBcSelBuffer& bcselbuffer, TBcSelCursor& bcsel) + template + void processRun3(TCCDB const& ccdb, THistoRegistry& histos, TBCs const& bcs, TTimestamps const& timestamps, TBcSelBuffer& bcselbuffer, TBcSelCursor& bcsel) { if (bcselOpts.amIneeded.value == 0) { bcselbuffer.clear(); @@ -426,15 +427,16 @@ class BcSelectionModule // bc loop for (auto bc : bcs) { // o2-linter: disable=const-ref-in-for-loop (use bc as nonconst iterator) + auto timestamp = timestamps[bc.globalIndex()]; // store rct flags uint32_t rct = lastRCT; int64_t thisTF = (bc.globalBC() - bcSOR) / nBCsPerTF; if (mapRCT != nullptr && thisTF != lastTF) { // skip for unanchored runs; do it once per TF - auto itrct = mapRCT->upper_bound(bc.timestamp()); + auto itrct = mapRCT->upper_bound(timestamp); if (itrct != mapRCT->begin()) itrct--; rct = itrct->second; - LOGP(debug, "sor={} eor={} ts={} rct={}", sorTimestamp, eorTimestamp, bc.timestamp(), rct); + LOGP(debug, "sor={} eor={} ts={} rct={}", sorTimestamp, eorTimestamp, timestamp, rct); lastRCT = rct; lastTF = thisTF; } @@ -560,10 +562,10 @@ class BcSelectionModule LOGP(debug, "foundFT0={}", foundFT0); const char* srun = Form("%d", run); - if (bc.timestamp() < sorTimestamp || bc.timestamp() > eorTimestamp) { + if (timestamp < sorTimestamp || timestamp > eorTimestamp) { histos.template get(HIST("bcselection/hCounterInvalidBCTimestamp"))->Fill(srun, 1); if (bcselOpts.confCheckRunDurationLimits.value) { - LOGF(warn, "Invalid BC timestamp: %d, run: %d, sor: %d, eor: %d", bc.timestamp(), run, sorTimestamp, eorTimestamp); + LOGF(warn, "Invalid BC timestamp: %d, run: %d, sor: %d, eor: %d", timestamp, run, sorTimestamp, eorTimestamp); alias = 0u; selection = 0u; } @@ -692,8 +694,8 @@ class EventSelectionModule } //__________________________________________________ - template - bool configure(TCCDB& ccdb, TBCs const& bcs) + template + bool configure(TCCDB& ccdb, TTimestamps const& timestamps, TBCs const& bcs) { int run = bcs.iteratorAt(0).runNumber(); // extract bc pattern from CCDB for data or anchored MC only @@ -705,7 +707,8 @@ class EventSelectionModule // duration of TF in bcs nBCsPerTF = evselOpts.confNumberOfOrbitsPerTF < 0 ? runInfo.orbitsPerTF * nBCsPerOrbit : evselOpts.confNumberOfOrbitsPerTF * nBCsPerOrbit; // colliding bc pattern - int64_t ts = bcs.iteratorAt(0).timestamp(); + int64_t ts = timestamps[0]; + // getForTimeStamp replaced with getSpecific to set metadata to zero // avoids crash related to specific run number auto grplhcif = ccdb->template getSpecific("GLO/Config/GRPLHCIF", ts); @@ -721,15 +724,16 @@ class EventSelectionModule } //__________________________________________________ - template - void processRun2(TCCDB const& ccdb, THistoRegistry& histos, TCollisions const& collisions, TTracklets const& tracklets, TSlicecache& cache, TBcSelBuffer const& bcselbuffer, TEvselCursor& evsel) + template + void processRun2(TCCDB const& ccdb, THistoRegistry& histos, TCollisions const& collisions, TTracklets const& tracklets, TSlicecache& cache, TTimestamps const& timestamps, TBcSelBuffer const& bcselbuffer, TEvselCursor& evsel) { if (evselOpts.amIneeded.value == 0) { return; // dummy process } for (const auto& col : collisions) { auto bc = col.template bc_as>(); - EventSelectionParams* par = ccdb->template getForTimeStamp("EventSelection/EventSelectionParams", bc.timestamp()); + auto timestamp = timestamps[bc.globalIndex()]; + EventSelectionParams* par = ccdb->template getForTimeStamp("EventSelection/EventSelectionParams", timestamp); bool* applySelection = par->getSelection(evselOpts.muonSelection); if (evselOpts.isMC == 1) { applySelection[aod::evsel::kIsBBZAC] = 0; @@ -802,13 +806,13 @@ class EventSelectionModule } // end processRun2 //__________________________________________________ - template - void processRun3(TCCDB const& ccdb, THistoRegistry& histos, TBCs const& bcs, TCollisions const& cols, TPVTracks const& pvTracks, TFT0s const& ft0s, TSlicecache& cache, TBcSelBuffer const& bcselbuffer, TEvselCursor& evsel) + template + void processRun3(TCCDB const& ccdb, THistoRegistry& histos, TBCs const& bcs, TCollisions const& cols, TPVTracks const& pvTracks, TFT0s const& ft0s, TSlicecache& cache, TTimestamps const& timestamps, TBcSelBuffer const& bcselbuffer, TEvselCursor& evsel) { if (evselOpts.amIneeded.value == 0) { return; // dummy process } - if (!configure(ccdb, bcs)) + if (!configure(ccdb, timestamps, bcs)) return; // don't do anything in case configuration reported not ok int run = bcs.iteratorAt(0).runNumber(); @@ -1372,8 +1376,8 @@ class LumiModule } } - template - bool configure(TCCDB& ccdb, TBCs const& bcs) + template + bool configure(TCCDB& ccdb, TTimestamps const& timestamps, TBCs const& bcs) { if (bcs.size() == 0) return false; @@ -1382,7 +1386,7 @@ class LumiModule return false; if (run != lastRun && run >= 520259) { // o2-linter: disable=magic-number (scalers available for runs above 520120) lastRun = run; - int64_t ts = bcs.iteratorAt(0).timestamp(); + int64_t ts = timestamps[0]; // getting GRP LHCIF object to extract colliding system, energy and colliding bc pattern auto grplhcif = ccdb->template getForTimeStamp("GLO/Config/GRPLHCIF", ts); @@ -1511,14 +1515,14 @@ class LumiModule } //__________________________________________________ - template - void process(TCCDB& ccdb, THistoRegistry& histos, TBCs const& bcs, TBcSelBuffer const& bcselBuffer) + template + void process(TCCDB& ccdb, THistoRegistry& histos, TBCs const& bcs, TTimestamps const& timestamps, TBcSelBuffer const& bcselBuffer) { if (lumiOpts.amIneeded.value == 0) { return; } - if (!configure(ccdb, bcs)) + if (!configure(ccdb, timestamps, bcs)) return; // don't do anything in case configuration reported not ok int run = bcs.iteratorAt(0).runNumber(); From a004beb2e7fc07d473433f3d87c6dc94d0eb3e43 Mon Sep 17 00:00:00 2001 From: ALICE Builder Date: Sun, 29 Jun 2025 18:54:19 +0200 Subject: [PATCH 2/5] Please consider the following formatting changes (#436) --- Common/TableProducer/eventSelectionService.cxx | 4 ++-- Common/Tools/EventSelectionTools.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Common/TableProducer/eventSelectionService.cxx b/Common/TableProducer/eventSelectionService.cxx index cc7773d1ff2..b5d15e5cce9 100644 --- a/Common/TableProducer/eventSelectionService.cxx +++ b/Common/TableProducer/eventSelectionService.cxx @@ -61,7 +61,7 @@ struct eventselectionRun2 { o2::common::eventselection::evselConfigurables evselOpts; o2::common::eventselection::EventSelectionModule evselmodule; - Produces timestampTable; /// Table with SOR timestamps produced by the task + Produces timestampTable; /// Table with SOR timestamps produced by the task Produces bcsel; Produces evsel; @@ -123,7 +123,7 @@ struct eventselectionRun3 { o2::common::eventselection::lumiConfigurables lumiOpts; o2::common::eventselection::LumiModule lumimodule; - Produces timestampTable; /// Table with SOR timestamps produced by the task + Produces timestampTable; /// Table with SOR timestamps produced by the task Produces bcsel; Produces evsel; diff --git a/Common/Tools/EventSelectionTools.h b/Common/Tools/EventSelectionTools.h index 5c84a0a00d4..285d30d1502 100644 --- a/Common/Tools/EventSelectionTools.h +++ b/Common/Tools/EventSelectionTools.h @@ -725,7 +725,7 @@ class EventSelectionModule //__________________________________________________ template - void processRun2(TCCDB const& ccdb, THistoRegistry& histos, TCollisions const& collisions, TTracklets const& tracklets, TSlicecache& cache, TTimestamps const& timestamps, TBcSelBuffer const& bcselbuffer, TEvselCursor& evsel) + void processRun2(TCCDB const& ccdb, THistoRegistry& histos, TCollisions const& collisions, TTracklets const& tracklets, TSlicecache& cache, TTimestamps const& timestamps, TBcSelBuffer const& bcselbuffer, TEvselCursor& evsel) { if (evselOpts.amIneeded.value == 0) { return; // dummy process @@ -1386,7 +1386,7 @@ class LumiModule return false; if (run != lastRun && run >= 520259) { // o2-linter: disable=magic-number (scalers available for runs above 520120) lastRun = run; - int64_t ts = timestamps[0]; + int64_t ts = timestamps[0]; // getting GRP LHCIF object to extract colliding system, energy and colliding bc pattern auto grplhcif = ccdb->template getForTimeStamp("GLO/Config/GRPLHCIF", ts); From 636e20d7ad4ded035c0bc3e0854ca18e6f572ff6 Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Sun, 29 Jun 2025 19:37:16 +0200 Subject: [PATCH 3/5] Add forgotten files --- Common/TableProducer/timestampTester.cxx | 69 +++++++++++ Common/Tools/timestampModule.h | 144 +++++++++++++++++++++++ 2 files changed, 213 insertions(+) create mode 100644 Common/TableProducer/timestampTester.cxx create mode 100644 Common/Tools/timestampModule.h diff --git a/Common/TableProducer/timestampTester.cxx b/Common/TableProducer/timestampTester.cxx new file mode 100644 index 00000000000..1c2b097a184 --- /dev/null +++ b/Common/TableProducer/timestampTester.cxx @@ -0,0 +1,69 @@ +// 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. + +/// +/// \file timestamp.cxx +/// \author Nicolò Jacazio +/// \since 2020-06-22 +/// \brief A task to fill the timestamp table from run number. +/// Uses headers from CCDB +/// +#include +#include +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "CCDB/BasicCCDBManager.h" +#include "CommonDataFormat/InteractionRecord.h" +#include "DetectorsRaw/HBFUtils.h" +#include "MetadataHelper.h" +#include "Common/Tools/timestampModule.h" + +using namespace o2::framework; +using namespace o2::header; +using namespace o2; + +MetadataHelper metadataInfo; // Metadata helper + +struct TimestampTask { + Produces timestampTable; /// Table with SOR timestamps produced by the task + Service ccdb; /// CCDB manager to access orbit-reset timestamp + o2::ccdb::CcdbApi ccdb_api; /// API to access CCDB headers + + Configurable ccdb_url{"ccdb-url", "http://alice-ccdb.cern.ch", "URL of the CCDB database"}; + + o2::common::timestamp::timestampConfigurables timestampConfigurables; + o2::common::timestamp::TimestampModule timestampMod; + + std::vector timestampBuffer; + + void init(o2::framework::InitContext&) + { + // CCDB initialization + ccdb->setURL(ccdb_url.value); + ccdb_api.init(ccdb_url.value); + + // timestamp configuration + init + timestampMod.init(timestampConfigurables, metadataInfo); + } + + void process(aod::BCs const& bcs) + { + timestampMod.process(bcs, ccdb, timestampBuffer, timestampTable); + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + // Parse the metadata + metadataInfo.initMetadata(cfgc); + + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/Common/Tools/timestampModule.h b/Common/Tools/timestampModule.h new file mode 100644 index 00000000000..24d5fb2dc80 --- /dev/null +++ b/Common/Tools/timestampModule.h @@ -0,0 +1,144 @@ +// 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. + +#ifndef COMMON_TOOLS_TIMESTAMPMODULEH_ +#define COMMON_TOOLS_TIMESTAMPMODULEH_ + +#include +#include +#include +#include "Framework/AnalysisDataModel.h" + +namespace o2 +{ +namespace common +{ +namespace timestamp +{ + +// timestamp configurables +struct timestampConfigurables : o2::framework::ConfigurableGroup { + std::string prefix = "timestamp"; + o2::framework::Configurable verbose{"verbose", false, "verbose mode"}; + o2::framework::Configurable fatalOnInvalidTimestamp{"fatalOnInvalidTimestamp", false, "Generate fatal error for invalid timestamps"}; + o2::framework::Configurable rct_path{"rct-path", "RCT/Info/RunInformation", "path to the ccdb RCT objects for the SOR timestamps"}; + o2::framework::Configurable orbit_reset_path{"orbit-reset-path", "CTP/Calib/OrbitReset", "path to the ccdb orbit-reset objects"}; + o2::framework::Configurable isRun2MC{"isRun2MC", -1, "Running mode: enable only for Run 2 MC. Timestamps are set to SOR timestamp. Default: -1 (autoset from metadata) 0 (Standard) 1 (Run 2 MC)"}; // o2-linter: disable=name/configurable (temporary fix) +}; + +//__________________________________________ +// time stamp module +// +// class to acquire time stamps to be used in +// modular (plugin) fashion + +class TimestampModule +{ + public: + TimestampModule() + { + // constructor: initialize at defaults + lastRunNumber = 0; + orbitResetTimestamp = 0; + }; + + o2::common::timestamp::timestampConfigurables timestampOpts; + + // objects necessary during processing + std::map mapRunToOrbitReset; /// Cache of orbit reset timestamps + std::map> mapRunToRunDuration; /// Cache of run duration timestamps + int lastRunNumber; /// Last run number processed + int64_t orbitResetTimestamp; /// Orbit-reset timestamp in us + std::pair runDuration; /// Pair of SOR and EOR timestamps + + template + void init(TTimestampOpts const& external_timestampOpts, TMetadatahelper const& metadataInfo ){ + timestampOpts = external_timestampOpts; + + if (timestampOpts.isRun2MC.value == -1) { + if ((!metadataInfo.isRun3()) && metadataInfo.isMC()) { + timestampOpts.isRun2MC.value = 1; + LOG(info) << "Autosetting the Run2 MC mode based on metadata"; + } else { + timestampOpts.isRun2MC.value = 0; + } + } + } + + template + void process(TBCs const& bcs, Tccdb const& ccdb, TTimestampBuffer& timestampbuffer, TCursor& timestampTable){ + timestampbuffer.clear(); + for(auto const& bc : bcs){ + int runNumber = bc.runNumber(); + // We need to set the orbit-reset timestamp for the run number. + // This is done with caching if the run number was already processed before. + // If not the orbit-reset timestamp for the run number is queried from CCDB and added to the cache + if (runNumber == lastRunNumber) { // The run number coincides to the last run processed + LOGF(debug, "Using orbit-reset timestamp from last call"); + } else if (mapRunToOrbitReset.count(runNumber)) { // The run number was already requested before: getting it from cache! + LOGF(debug, "Getting orbit-reset timestamp from cache"); + orbitResetTimestamp = mapRunToOrbitReset[runNumber]; + runDuration = mapRunToRunDuration[runNumber]; + } else { // The run was not requested before: need to acccess CCDB! + LOGF(debug, "Getting start-of-run and end-of-run timestamps from CCDB"); + runDuration = ccdb->getRunDuration(runNumber, true); /// fatalise if timestamps are not found + int64_t sorTimestamp = runDuration.first; // timestamp of the SOR/SOX/STF in ms + int64_t eorTimestamp = runDuration.second; // timestamp of the EOR/EOX/ETF in ms + + const bool isUnanchoredRun3MC = runNumber >= 300000 && runNumber < 500000; + if (timestampOpts.isRun2MC.value == 1 || isUnanchoredRun3MC) { + // isRun2MC: bc/orbit distributions are not simulated in Run2 MC. All bcs are set to 0. + // isUnanchoredRun3MC: assuming orbit-reset is done in the beginning of each run + // Setting orbit-reset timestamp to start-of-run timestamp + orbitResetTimestamp = sorTimestamp * 1000; // from ms to us + } else if (runNumber < 300000) { // Run 2 + LOGF(debug, "Getting orbit-reset timestamp using start-of-run timestamp from CCDB"); + auto ctp = ccdb->template getForTimeStamp>(timestampOpts.orbit_reset_path.value.data(), sorTimestamp); + orbitResetTimestamp = (*ctp)[0]; + } else { + // sometimes orbit is reset after SOR. Using EOR timestamps for orbitReset query is more reliable + LOGF(debug, "Getting orbit-reset timestamp using end-of-run timestamp from CCDB"); + auto ctp = ccdb->template getForTimeStamp>(timestampOpts.orbit_reset_path.value.data(), eorTimestamp / 2 + sorTimestamp / 2); + orbitResetTimestamp = (*ctp)[0]; + } + + // Adding the timestamp to the cache map + std::pair::iterator, bool> check; + check = mapRunToOrbitReset.insert(std::pair(runNumber, orbitResetTimestamp)); + if (!check.second) { + LOGF(fatal, "Run number %i already existed with a orbit-reset timestamp of %llu", runNumber, check.first->second); + } + mapRunToRunDuration[runNumber] = runDuration; + LOGF(info, "Add new run number %i with orbit-reset timestamp %llu, SOR: %llu, EOR: %llu to cache", runNumber, orbitResetTimestamp, runDuration.first, runDuration.second); + } + + if (timestampOpts.verbose) { + LOGF(info, "Orbit-reset timestamp for run number %i found: %llu us", runNumber, orbitResetTimestamp); + } + int64_t timestamp{(orbitResetTimestamp + int64_t(bc.globalBC() * o2::constants::lhc::LHCBunchSpacingNS * 1e-3)) / 1000}; // us -> ms + if (timestamp < runDuration.first || timestamp > runDuration.second) { + if (timestampOpts.fatalOnInvalidTimestamp.value) { + LOGF(fatal, "Timestamp %llu us is out of run duration [%llu, %llu] ms", timestamp, runDuration.first, runDuration.second); + } else { + LOGF(debug, "Timestamp %llu us is out of run duration [%llu, %llu] ms", timestamp, runDuration.first, runDuration.second); + } + } + timestampbuffer.push_back(timestamp); // for buffering purposes + timestampTable(timestamp); + } + } +}; + +} // namespace timestamp +} // namespace common +} // namespace o2 + +#endif // COMMON_TOOLS_TIMESTAMPMODULEH_ \ No newline at end of file From 5e31f7e6112701fb4d9869687685927e6209b4ab Mon Sep 17 00:00:00 2001 From: ALICE Builder Date: Sun, 29 Jun 2025 19:39:10 +0200 Subject: [PATCH 4/5] Please consider the following formatting changes (#437) --- Common/TableProducer/timestampTester.cxx | 21 +++++++++------- Common/Tools/timestampModule.h | 31 +++++++++++++----------- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/Common/TableProducer/timestampTester.cxx b/Common/TableProducer/timestampTester.cxx index 1c2b097a184..6a7f829e950 100644 --- a/Common/TableProducer/timestampTester.cxx +++ b/Common/TableProducer/timestampTester.cxx @@ -16,15 +16,18 @@ /// \brief A task to fill the timestamp table from run number. /// Uses headers from CCDB /// -#include -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" +#include "MetadataHelper.h" + +#include "Common/Tools/timestampModule.h" + #include "CCDB/BasicCCDBManager.h" #include "CommonDataFormat/InteractionRecord.h" #include "DetectorsRaw/HBFUtils.h" -#include "MetadataHelper.h" -#include "Common/Tools/timestampModule.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include +#include using namespace o2::framework; using namespace o2::header; @@ -33,9 +36,9 @@ using namespace o2; MetadataHelper metadataInfo; // Metadata helper struct TimestampTask { - Produces timestampTable; /// Table with SOR timestamps produced by the task - Service ccdb; /// CCDB manager to access orbit-reset timestamp - o2::ccdb::CcdbApi ccdb_api; /// API to access CCDB headers + Produces timestampTable; /// Table with SOR timestamps produced by the task + Service ccdb; /// CCDB manager to access orbit-reset timestamp + o2::ccdb::CcdbApi ccdb_api; /// API to access CCDB headers Configurable ccdb_url{"ccdb-url", "http://alice-ccdb.cern.ch", "URL of the CCDB database"}; diff --git a/Common/Tools/timestampModule.h b/Common/Tools/timestampModule.h index 24d5fb2dc80..36cf507f398 100644 --- a/Common/Tools/timestampModule.h +++ b/Common/Tools/timestampModule.h @@ -12,11 +12,12 @@ #ifndef COMMON_TOOLS_TIMESTAMPMODULEH_ #define COMMON_TOOLS_TIMESTAMPMODULEH_ -#include -#include -#include #include "Framework/AnalysisDataModel.h" +#include +#include +#include + namespace o2 { namespace common @@ -31,13 +32,13 @@ struct timestampConfigurables : o2::framework::ConfigurableGroup { o2::framework::Configurable fatalOnInvalidTimestamp{"fatalOnInvalidTimestamp", false, "Generate fatal error for invalid timestamps"}; o2::framework::Configurable rct_path{"rct-path", "RCT/Info/RunInformation", "path to the ccdb RCT objects for the SOR timestamps"}; o2::framework::Configurable orbit_reset_path{"orbit-reset-path", "CTP/Calib/OrbitReset", "path to the ccdb orbit-reset objects"}; - o2::framework::Configurable isRun2MC{"isRun2MC", -1, "Running mode: enable only for Run 2 MC. Timestamps are set to SOR timestamp. Default: -1 (autoset from metadata) 0 (Standard) 1 (Run 2 MC)"}; // o2-linter: disable=name/configurable (temporary fix) + o2::framework::Configurable isRun2MC{"isRun2MC", -1, "Running mode: enable only for Run 2 MC. Timestamps are set to SOR timestamp. Default: -1 (autoset from metadata) 0 (Standard) 1 (Run 2 MC)"}; // o2-linter: disable=name/configurable (temporary fix) }; //__________________________________________ // time stamp module -// -// class to acquire time stamps to be used in +// +// class to acquire time stamps to be used in // modular (plugin) fashion class TimestampModule @@ -53,14 +54,15 @@ class TimestampModule o2::common::timestamp::timestampConfigurables timestampOpts; // objects necessary during processing - std::map mapRunToOrbitReset; /// Cache of orbit reset timestamps + std::map mapRunToOrbitReset; /// Cache of orbit reset timestamps std::map> mapRunToRunDuration; /// Cache of run duration timestamps - int lastRunNumber; /// Last run number processed - int64_t orbitResetTimestamp; /// Orbit-reset timestamp in us - std::pair runDuration; /// Pair of SOR and EOR timestamps + int lastRunNumber; /// Last run number processed + int64_t orbitResetTimestamp; /// Orbit-reset timestamp in us + std::pair runDuration; /// Pair of SOR and EOR timestamps template - void init(TTimestampOpts const& external_timestampOpts, TMetadatahelper const& metadataInfo ){ + void init(TTimestampOpts const& external_timestampOpts, TMetadatahelper const& metadataInfo) + { timestampOpts = external_timestampOpts; if (timestampOpts.isRun2MC.value == -1) { @@ -74,9 +76,10 @@ class TimestampModule } template - void process(TBCs const& bcs, Tccdb const& ccdb, TTimestampBuffer& timestampbuffer, TCursor& timestampTable){ + void process(TBCs const& bcs, Tccdb const& ccdb, TTimestampBuffer& timestampbuffer, TCursor& timestampTable) + { timestampbuffer.clear(); - for(auto const& bc : bcs){ + for (auto const& bc : bcs) { int runNumber = bc.runNumber(); // We need to set the orbit-reset timestamp for the run number. // This is done with caching if the run number was already processed before. @@ -141,4 +144,4 @@ class TimestampModule } // namespace common } // namespace o2 -#endif // COMMON_TOOLS_TIMESTAMPMODULEH_ \ No newline at end of file +#endif // COMMON_TOOLS_TIMESTAMPMODULEH_ From effb5417c8e5e156eae731067b3abf3035f09abc Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Sun, 29 Jun 2025 20:25:09 +0200 Subject: [PATCH 5/5] Fix errors --- Common/TableProducer/eventSelectionService.cxx | 4 ++-- Common/Tools/EventSelectionTools.h | 6 +++--- Common/Tools/timestampModule.h | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Common/TableProducer/eventSelectionService.cxx b/Common/TableProducer/eventSelectionService.cxx index b5d15e5cce9..35f17d531ab 100644 --- a/Common/TableProducer/eventSelectionService.cxx +++ b/Common/TableProducer/eventSelectionService.cxx @@ -75,7 +75,7 @@ struct eventselectionRun2 { HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; // buffering intermediate results for passing - std::vector timestamps; + std::vector timestamps; std::vector bcselsbuffer; // auxiliary @@ -138,7 +138,7 @@ struct eventselectionRun3 { // the best: have readable cursors // this: a stopgap solution to avoid spawning yet another device - std::vector timestamps; + std::vector timestamps; std::vector bcselsbuffer; // auxiliary diff --git a/Common/Tools/EventSelectionTools.h b/Common/Tools/EventSelectionTools.h index 285d30d1502..c04b2f51b62 100644 --- a/Common/Tools/EventSelectionTools.h +++ b/Common/Tools/EventSelectionTools.h @@ -273,7 +273,7 @@ class BcSelectionModule } bcselbuffer.clear(); for (const auto& bc : bcs) { - auto timestamp = timestamps[bc.globalIndex()]; + uint64_t timestamp = timestamps[bc.globalIndex()]; par = ccdb->template getForTimeStamp("EventSelection/EventSelectionParams", timestamp); aliases = ccdb->template getForTimeStamp("EventSelection/TriggerAliases", timestamp); // fill fired aliases @@ -427,7 +427,7 @@ class BcSelectionModule // bc loop for (auto bc : bcs) { // o2-linter: disable=const-ref-in-for-loop (use bc as nonconst iterator) - auto timestamp = timestamps[bc.globalIndex()]; + uint64_t timestamp = timestamps[bc.globalIndex()]; // store rct flags uint32_t rct = lastRCT; int64_t thisTF = (bc.globalBC() - bcSOR) / nBCsPerTF; @@ -732,7 +732,7 @@ class EventSelectionModule } for (const auto& col : collisions) { auto bc = col.template bc_as>(); - auto timestamp = timestamps[bc.globalIndex()]; + uint64_t timestamp = timestamps[bc.globalIndex()]; EventSelectionParams* par = ccdb->template getForTimeStamp("EventSelection/EventSelectionParams", timestamp); bool* applySelection = par->getSelection(evselOpts.muonSelection); if (evselOpts.isMC == 1) { diff --git a/Common/Tools/timestampModule.h b/Common/Tools/timestampModule.h index 36cf507f398..99241fa7713 100644 --- a/Common/Tools/timestampModule.h +++ b/Common/Tools/timestampModule.h @@ -104,12 +104,12 @@ class TimestampModule orbitResetTimestamp = sorTimestamp * 1000; // from ms to us } else if (runNumber < 300000) { // Run 2 LOGF(debug, "Getting orbit-reset timestamp using start-of-run timestamp from CCDB"); - auto ctp = ccdb->template getForTimeStamp>(timestampOpts.orbit_reset_path.value.data(), sorTimestamp); + auto ctp = ccdb->template getForTimeStamp>(timestampOpts.orbit_reset_path.value.data(), sorTimestamp); orbitResetTimestamp = (*ctp)[0]; } else { // sometimes orbit is reset after SOR. Using EOR timestamps for orbitReset query is more reliable LOGF(debug, "Getting orbit-reset timestamp using end-of-run timestamp from CCDB"); - auto ctp = ccdb->template getForTimeStamp>(timestampOpts.orbit_reset_path.value.data(), eorTimestamp / 2 + sorTimestamp / 2); + auto ctp = ccdb->template getForTimeStamp>(timestampOpts.orbit_reset_path.value.data(), eorTimestamp / 2 + sorTimestamp / 2); orbitResetTimestamp = (*ctp)[0]; }