Skip to content

Commit 636e20d

Browse files
committed
Add forgotten files
1 parent a004beb commit 636e20d

File tree

2 files changed

+213
-0
lines changed

2 files changed

+213
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
///
13+
/// \file timestamp.cxx
14+
/// \author Nicolò Jacazio
15+
/// \since 2020-06-22
16+
/// \brief A task to fill the timestamp table from run number.
17+
/// Uses headers from CCDB
18+
///
19+
#include <vector>
20+
#include <map>
21+
#include "Framework/runDataProcessing.h"
22+
#include "Framework/AnalysisTask.h"
23+
#include "CCDB/BasicCCDBManager.h"
24+
#include "CommonDataFormat/InteractionRecord.h"
25+
#include "DetectorsRaw/HBFUtils.h"
26+
#include "MetadataHelper.h"
27+
#include "Common/Tools/timestampModule.h"
28+
29+
using namespace o2::framework;
30+
using namespace o2::header;
31+
using namespace o2;
32+
33+
MetadataHelper metadataInfo; // Metadata helper
34+
35+
struct TimestampTask {
36+
Produces<aod::Timestamps> timestampTable; /// Table with SOR timestamps produced by the task
37+
Service<o2::ccdb::BasicCCDBManager> ccdb; /// CCDB manager to access orbit-reset timestamp
38+
o2::ccdb::CcdbApi ccdb_api; /// API to access CCDB headers
39+
40+
Configurable<std::string> ccdb_url{"ccdb-url", "http://alice-ccdb.cern.ch", "URL of the CCDB database"};
41+
42+
o2::common::timestamp::timestampConfigurables timestampConfigurables;
43+
o2::common::timestamp::TimestampModule timestampMod;
44+
45+
std::vector<int64_t> timestampBuffer;
46+
47+
void init(o2::framework::InitContext&)
48+
{
49+
// CCDB initialization
50+
ccdb->setURL(ccdb_url.value);
51+
ccdb_api.init(ccdb_url.value);
52+
53+
// timestamp configuration + init
54+
timestampMod.init(timestampConfigurables, metadataInfo);
55+
}
56+
57+
void process(aod::BCs const& bcs)
58+
{
59+
timestampMod.process(bcs, ccdb, timestampBuffer, timestampTable);
60+
}
61+
};
62+
63+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
64+
{
65+
// Parse the metadata
66+
metadataInfo.initMetadata(cfgc);
67+
68+
return WorkflowSpec{adaptAnalysisTask<TimestampTask>(cfgc)};
69+
}

Common/Tools/timestampModule.h

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
#ifndef COMMON_TOOLS_TIMESTAMPMODULEH_
13+
#define COMMON_TOOLS_TIMESTAMPMODULEH_
14+
15+
#include <cstdlib>
16+
#include <cmath>
17+
#include <array>
18+
#include "Framework/AnalysisDataModel.h"
19+
20+
namespace o2
21+
{
22+
namespace common
23+
{
24+
namespace timestamp
25+
{
26+
27+
// timestamp configurables
28+
struct timestampConfigurables : o2::framework::ConfigurableGroup {
29+
std::string prefix = "timestamp";
30+
o2::framework::Configurable<bool> verbose{"verbose", false, "verbose mode"};
31+
o2::framework::Configurable<bool> fatalOnInvalidTimestamp{"fatalOnInvalidTimestamp", false, "Generate fatal error for invalid timestamps"};
32+
o2::framework::Configurable<std::string> rct_path{"rct-path", "RCT/Info/RunInformation", "path to the ccdb RCT objects for the SOR timestamps"};
33+
o2::framework::Configurable<std::string> orbit_reset_path{"orbit-reset-path", "CTP/Calib/OrbitReset", "path to the ccdb orbit-reset objects"};
34+
o2::framework::Configurable<int> 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)
35+
};
36+
37+
//__________________________________________
38+
// time stamp module
39+
//
40+
// class to acquire time stamps to be used in
41+
// modular (plugin) fashion
42+
43+
class TimestampModule
44+
{
45+
public:
46+
TimestampModule()
47+
{
48+
// constructor: initialize at defaults
49+
lastRunNumber = 0;
50+
orbitResetTimestamp = 0;
51+
};
52+
53+
o2::common::timestamp::timestampConfigurables timestampOpts;
54+
55+
// objects necessary during processing
56+
std::map<int, int64_t> mapRunToOrbitReset; /// Cache of orbit reset timestamps
57+
std::map<int, std::pair<int64_t, int64_t>> mapRunToRunDuration; /// Cache of run duration timestamps
58+
int lastRunNumber; /// Last run number processed
59+
int64_t orbitResetTimestamp; /// Orbit-reset timestamp in us
60+
std::pair<int64_t, int64_t> runDuration; /// Pair of SOR and EOR timestamps
61+
62+
template <typename TTimestampOpts, typename TMetadatahelper>
63+
void init(TTimestampOpts const& external_timestampOpts, TMetadatahelper const& metadataInfo ){
64+
timestampOpts = external_timestampOpts;
65+
66+
if (timestampOpts.isRun2MC.value == -1) {
67+
if ((!metadataInfo.isRun3()) && metadataInfo.isMC()) {
68+
timestampOpts.isRun2MC.value = 1;
69+
LOG(info) << "Autosetting the Run2 MC mode based on metadata";
70+
} else {
71+
timestampOpts.isRun2MC.value = 0;
72+
}
73+
}
74+
}
75+
76+
template <typename TBCs, typename Tccdb, typename TTimestampBuffer, typename TCursor>
77+
void process(TBCs const& bcs, Tccdb const& ccdb, TTimestampBuffer& timestampbuffer, TCursor& timestampTable){
78+
timestampbuffer.clear();
79+
for(auto const& bc : bcs){
80+
int runNumber = bc.runNumber();
81+
// We need to set the orbit-reset timestamp for the run number.
82+
// This is done with caching if the run number was already processed before.
83+
// If not the orbit-reset timestamp for the run number is queried from CCDB and added to the cache
84+
if (runNumber == lastRunNumber) { // The run number coincides to the last run processed
85+
LOGF(debug, "Using orbit-reset timestamp from last call");
86+
} else if (mapRunToOrbitReset.count(runNumber)) { // The run number was already requested before: getting it from cache!
87+
LOGF(debug, "Getting orbit-reset timestamp from cache");
88+
orbitResetTimestamp = mapRunToOrbitReset[runNumber];
89+
runDuration = mapRunToRunDuration[runNumber];
90+
} else { // The run was not requested before: need to acccess CCDB!
91+
LOGF(debug, "Getting start-of-run and end-of-run timestamps from CCDB");
92+
runDuration = ccdb->getRunDuration(runNumber, true); /// fatalise if timestamps are not found
93+
int64_t sorTimestamp = runDuration.first; // timestamp of the SOR/SOX/STF in ms
94+
int64_t eorTimestamp = runDuration.second; // timestamp of the EOR/EOX/ETF in ms
95+
96+
const bool isUnanchoredRun3MC = runNumber >= 300000 && runNumber < 500000;
97+
if (timestampOpts.isRun2MC.value == 1 || isUnanchoredRun3MC) {
98+
// isRun2MC: bc/orbit distributions are not simulated in Run2 MC. All bcs are set to 0.
99+
// isUnanchoredRun3MC: assuming orbit-reset is done in the beginning of each run
100+
// Setting orbit-reset timestamp to start-of-run timestamp
101+
orbitResetTimestamp = sorTimestamp * 1000; // from ms to us
102+
} else if (runNumber < 300000) { // Run 2
103+
LOGF(debug, "Getting orbit-reset timestamp using start-of-run timestamp from CCDB");
104+
auto ctp = ccdb->template getForTimeStamp<std::vector<Long64_t>>(timestampOpts.orbit_reset_path.value.data(), sorTimestamp);
105+
orbitResetTimestamp = (*ctp)[0];
106+
} else {
107+
// sometimes orbit is reset after SOR. Using EOR timestamps for orbitReset query is more reliable
108+
LOGF(debug, "Getting orbit-reset timestamp using end-of-run timestamp from CCDB");
109+
auto ctp = ccdb->template getForTimeStamp<std::vector<Long64_t>>(timestampOpts.orbit_reset_path.value.data(), eorTimestamp / 2 + sorTimestamp / 2);
110+
orbitResetTimestamp = (*ctp)[0];
111+
}
112+
113+
// Adding the timestamp to the cache map
114+
std::pair<std::map<int, int64_t>::iterator, bool> check;
115+
check = mapRunToOrbitReset.insert(std::pair<int, int64_t>(runNumber, orbitResetTimestamp));
116+
if (!check.second) {
117+
LOGF(fatal, "Run number %i already existed with a orbit-reset timestamp of %llu", runNumber, check.first->second);
118+
}
119+
mapRunToRunDuration[runNumber] = runDuration;
120+
LOGF(info, "Add new run number %i with orbit-reset timestamp %llu, SOR: %llu, EOR: %llu to cache", runNumber, orbitResetTimestamp, runDuration.first, runDuration.second);
121+
}
122+
123+
if (timestampOpts.verbose) {
124+
LOGF(info, "Orbit-reset timestamp for run number %i found: %llu us", runNumber, orbitResetTimestamp);
125+
}
126+
int64_t timestamp{(orbitResetTimestamp + int64_t(bc.globalBC() * o2::constants::lhc::LHCBunchSpacingNS * 1e-3)) / 1000}; // us -> ms
127+
if (timestamp < runDuration.first || timestamp > runDuration.second) {
128+
if (timestampOpts.fatalOnInvalidTimestamp.value) {
129+
LOGF(fatal, "Timestamp %llu us is out of run duration [%llu, %llu] ms", timestamp, runDuration.first, runDuration.second);
130+
} else {
131+
LOGF(debug, "Timestamp %llu us is out of run duration [%llu, %llu] ms", timestamp, runDuration.first, runDuration.second);
132+
}
133+
}
134+
timestampbuffer.push_back(timestamp); // for buffering purposes
135+
timestampTable(timestamp);
136+
}
137+
}
138+
};
139+
140+
} // namespace timestamp
141+
} // namespace common
142+
} // namespace o2
143+
144+
#endif // COMMON_TOOLS_TIMESTAMPMODULEH_

0 commit comments

Comments
 (0)