Project
Loading...
Searching...
No Matches
create-grp-ecs.cxx
Go to the documentation of this file.
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#include <boost/program_options.hpp>
13#include <ctime>
14#include <chrono>
15#include <regex>
16#include <TSystem.h>
20#include "CCDB/CcdbApi.h"
24
28namespace bpo = boost::program_options;
29
33
34int createGRPECSObject(const std::string& dataPeriod,
35 int run,
36 int runOrig, // in case of replay
37 int runTypeI,
38 int nHBPerTF,
39 const std::string& _detsReadout,
40 const std::string& _detsContinuousRO,
41 const std::string& _detsTrigger,
42 const std::string& flpList,
43 long tstart,
44 long tend,
45 long tstartCTP,
46 long tendCTP,
47 long marginAtSOR,
48 long marginAtEOR,
49 const std::string& ccdbServer = "",
50 std::string ccdbServerInp = "",
51 const std::string& metaDataStr = "",
53{
54 int retValGLO = 0;
55 int retValRCT = 0;
56 int retValGLOmd = 0;
57 int retValCTP = 0;
58 // substitute TRG by CTP
59 std::regex regCTP(R"((^\s*|,\s*)(TRG)(\s*,|\s*$))");
60 std::string detsReadout{std::regex_replace(_detsReadout, regCTP, "$1CTP$3")};
61 std::string detsContinuousRO{std::regex_replace(_detsContinuousRO, regCTP, "$1CTP$3")};
62 std::string detsTrigger{std::regex_replace(_detsTrigger, regCTP, "$1CTP$3")};
63
64 auto detMask = DetID::getMask(detsReadout);
65 if (detMask.count() == 0) {
66 throw std::runtime_error("empty detectors list is provided");
67 }
68 if (runTypeI < 0 || runTypeI >= int(GRPECSObject::RunType::NRUNTYPES)) {
69 LOGP(warning, "run type {} is not recognized, consider updating GRPECSObject.h", runTypeI);
70 }
71 auto runType = (GRPECSObject::RunType)runTypeI;
72 auto detMaskCont = detMask & DetID::getMask(detsContinuousRO);
73 auto detMaskTrig = detMask & DetID::getMask(detsTrigger);
74 LOG(info) << tstart << " " << tend;
75 if (tstart == 0) {
76 tstart = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
77 }
78 long tendVal = 0;
79 if (tend < tstart) {
80 tendVal = tstart + marginAtSOR;
81 } else if (tendVal < tend) {
82 tendVal = tend + marginAtEOR;
83 }
84 GRPECSObject grpecs;
85 o2::ctp::CTPConfiguration* ctpConfig = nullptr;
86 o2::ctp::CTPConfiguration ctpConfigNew;
87 grpecs.setTimeStart(tstart);
88 grpecs.setTimeEnd(tend);
89 grpecs.setTimeStartCTP(tstartCTP);
90 grpecs.setTimeEndCTP(tendCTP);
91
92 if (runType == GRPECSObject::RunType::LASER && detMask[DetID::TPC] && detMaskCont[DetID::TPC]) {
93 LOGP(important, "Overriding TPC readout mode to triggered for runType={}", o2::parameters::GRPECS::RunTypeNames[runTypeI]);
94 detMaskCont.reset(DetID::TPC);
95 }
96 grpecs.setNHBFPerTF(nHBPerTF);
97 grpecs.setDetsReadOut(detMask);
98 grpecs.setDetsContinuousReadOut(detMaskCont);
99 grpecs.setDetsTrigger(detMaskTrig);
100 grpecs.setRun(run);
101 grpecs.setRunType((GRPECSObject::RunType)runType);
102 grpecs.setDataPeriod(dataPeriod);
103 auto flpsVec = o2::utils::Str::tokenize(flpList, ',');
104 for (const auto& s : flpsVec) {
105 try {
106 grpecs.addFLP((unsigned short)std::stoi(s));
107 } catch (const std::exception& e) {
108 LOG(alarm) << "could not convert string " << s << " to integer FLP ID, error : " << e.what();
109 }
110 }
111 grpecs.print();
112 std::map<std::string, std::string> metadata;
113
114 auto toKeyValPairs = [&metadata](const std::string& str) {
115 auto v0 = o2::utils::Str::tokenize(str, ';', true);
116 for (auto& token : v0) {
117 auto keyval = o2::utils::Str::tokenize(token, '=', false);
118 if (keyval.size() != 2) {
119 LOG(error) << "Illegal command-line key/value string: " << token;
120 continue;
121 }
122 o2::utils::Str::trim(keyval[1]);
123 LOGP(info, "Adding key {} with value {}", keyval[0], keyval[1]);
124 metadata[keyval[0]] = keyval[1];
125 }
126 };
127
128 if (ccdbServerInp.empty()) {
129 ccdbServerInp = ccdbServer;
130 }
131 if (runOrig > 0 && runOrig != run && tend <= tstart && !ccdbServerInp.empty()) { // create CTP config
132 try {
134 bcm.setURL(ccdbServerInp);
135 bcm.setFatalWhenNull(false);
136 ctpConfig = bcm.getForRun<o2::ctp::CTPConfiguration>("CTP/Config/Config", runOrig);
137 if (!ctpConfig) {
138 throw std::runtime_error(fmt::format("Failed to access CTP/Config/Config for original run {}", runOrig));
139 }
140 std::string cfstr = ctpConfig->getConfigString(), srun{fmt::format("run {}", run)}, srunOrig{fmt::format("run {}", runOrig)};
141 o2::utils::Str::replaceAll(cfstr, srunOrig, srun);
142 ctpConfigNew.loadConfigurationRun3(cfstr);
143 ctpConfigNew.setRunNumber(run);
144 } catch (std::exception e) {
145 LOGP(error, "Failed to create CTP/Config/Config from the original run {}, reason: {}", runOrig, e.what());
146 }
147 }
148
149 toKeyValPairs(metaDataStr);
150
151 if (!ccdbServer.empty()) {
152 CcdbApi api;
153
154 const std::string objPath{"GLO/Config/GRPECS"};
155 api.init(ccdbServer);
156 metadata["responsible"] = "ECS";
157 metadata[o2::base::NameConf::CCDBRunTag.data()] = std::to_string(run);
158 metadata["EOR"] = fmt::format("{}", tend);
159 retValGLO = api.storeAsTFileAny(&grpecs, objPath, metadata, tstart, tendVal); // making it 1-year valid to be sure we have something
160 if (retValGLO == 0) {
161 LOGP(info, "Uploaded to {}/{} with validity {}:{} for SOR:{}/EOR:{}", ccdbServer, objPath, tstart, tendVal, tstart, tend);
162 } else {
163 LOGP(alarm, "Upload to {}/{} with validity {}:{} for SOR:{}/EOR:{} FAILED, returned with code {}", ccdbServer, objPath, tstart, tendVal, tstart, tend, retValGLO);
164 }
165 if ((runType == GRPECSObject::RunType::PHYSICS || runType == GRPECSObject::RunType::COSMICS) && tstart >= tend) { // also create the RCT/Info/RunInformation entry in case the run type is PHYSICS, to be finalized at EOR
166 char tempChar{};
167 std::map<std::string, std::string> mdRCT;
168 mdRCT["SOR"] = std::to_string(tstart);
169 mdRCT["EOR"] = std::to_string(tend);
170 mdRCT["SOX"] = std::to_string(tstartCTP);
171 mdRCT["EOX"] = std::to_string(tendCTP);
172 long startValRCT = (long)run;
173 long endValRCT = (long)(run + 1);
174 retValRCT = api.storeAsBinaryFile(&tempChar, sizeof(tempChar), "tmp.dat", "char", "RCT/Info/RunInformation", mdRCT, startValRCT, endValRCT);
175 if (retValRCT == 0) {
176 LOGP(info, "Uploaded initial RCT object to {}/{} with validity {}:{}", ccdbServer, "RCT/Info/RunInformation", startValRCT, endValRCT);
177 } else {
178 LOGP(alarm, "Upload of initial RCT object to {}/{} with validity {}:{} FAILED, returned with code {}", ccdbServer, "RCT/Info/RunInformation", startValRCT, endValRCT, retValRCT);
179 }
180 }
181 if (tend > tstart) {
182 // override SOR version to the same limits
183 metadata.erase("EOR");
184 auto prevHeader = api.retrieveHeaders(objPath, metadata, tendVal + 1); // is there an object to override
185 const auto itETag = prevHeader.find("ETag");
186 if (itETag != prevHeader.end()) {
187 std::string etag = itETag->second;
188 etag.erase(remove(etag.begin(), etag.end(), '\"'), etag.end());
189 LOGP(info, "Overriding run {} SOR-only version {}{}{}/{} validity to match complete SOR/EOR version validity", run, ccdbServer, ccdbServer.back() == '/' ? "" : "/", prevHeader["Valid-From"], etag);
190 retValGLOmd = api.updateMetadata(objPath, {}, std::max(tstart, tendVal - 1), etag, tendVal);
191 if (retValGLOmd != 0) {
192 LOGP(alarm, "Overriding run {} SOR-only version {}{}{}/{} validity to match complete SOR/EOR version validity FAILED", run, ccdbServer, ccdbServer.back() == '/' ? "" : "/", prevHeader["Valid-From"], etag);
193 }
194 }
195 if (runType == GRPECSObject::RunType::PHYSICS || runType == GRPECSObject::RunType::COSMICS) { // also storing the RCT/Info/RunInformation entry in case the run type is PHYSICS and if we are at the end of run
196 char tempChar{};
197 std::map<std::string, std::string> mdRCT;
198 mdRCT["SOR"] = std::to_string(tstart);
199 mdRCT["EOR"] = std::to_string(tend);
200 mdRCT["SOX"] = std::to_string(tstartCTP);
201 mdRCT["EOX"] = std::to_string(tendCTP);
202 long startValRCT = (long)run;
203 long endValRCT = (long)(run + 1);
204 retValRCT = api.updateMetadata("RCT/Info/RunInformation", mdRCT, startValRCT);
205 if (retValRCT == 0) {
206 LOGP(info, "Updated RCT object to SOR:{}/EOR:{} SOX:{}/EOX:{}", tstart, tend, tstartCTP, tendCTP);
207 } else {
208 LOGP(alarm, "Update of RCT object to SOR:{}/EOR:{} SOX:{}/EOX:{} FAILED, returned with code {}", tstart, tend, tstartCTP, tendCTP, retValRCT);
209 }
210 }
211 }
212
213 if (ctpConfig && ctpConfigNew.getRunNumber() == run) { // create CTP config
214 std::map<std::string, std::string> metadataCTP;
215 metadataCTP["runNumber"] = fmt::format("{}", run);
216 metadataCTP["comment"] = fmt::format("cloned from run {}", runOrig);
217 retValCTP = api.storeAsTFileAny(&ctpConfigNew, "CTP/Config/Config", metadataCTP, tstart, tendVal);
218 if (retValCTP == 0) {
219 LOGP(info, "Uploaded to {}/{} with validity {}:{} for SOR:{}/EOR:{}, cloned from run {}", ccdbServer, "CTP/Config/Config", tstart, tendVal, tstart, tend, runOrig);
220 } else {
221 LOGP(alarm, "Upload to {}/{} with validity {}:{} for SOR:{}/EOR:{} (cloned from run {}) FAILED, returned with code {}", ccdbServer, "CTP/Config/Config", tstart, tendVal, tstart, tend, runOrig, retValCTP);
222 }
223 }
224 } else { // write a local file
226 TFile grpF(fname.c_str(), "recreate");
227 grpF.WriteObjectAny(&grpecs, grpecs.Class(), o2::base::NameConf::CCDBOBJECT.data());
228 grpF.Close();
229 LOGP(info, "Stored GRPECS to local file {}", fname);
230 if (ctpConfig && ctpConfigNew.getRunNumber() == run) {
231 std::string ctnpfname = fmt::format("CTPConfig_{}_from_{}.root", run, runOrig);
232 TFile ctpF(ctnpfname.c_str(), "recreate");
233 ctpF.WriteObjectAny(&ctpConfigNew, ctpConfigNew.Class(), o2::base::NameConf::CCDBOBJECT.data());
234 ctpF.Close();
235 LOGP(info, "Stored CTPConfig to local file {}", ctnpfname);
236 }
237 }
238
239 if (refresh != CCDBRefreshMode::NONE && !ccdbServer.empty()) {
240 auto cmd = fmt::format("curl -I -i -s \"{}{}latest/%5Cw%7B3%7D/.*/`date +%s000`/?prepare={}\"", ccdbServer, ccdbServer.back() == '/' ? "" : "/", refresh == CCDBRefreshMode::SYNC ? "sync" : "true");
241 auto t0 = std::chrono::high_resolution_clock::now();
242 auto res = gSystem->Exec(cmd.c_str());
243 auto t1 = std::chrono::high_resolution_clock::now();
244 LOGP(info, "Executed [{}] -> {} in {:.3f} s", cmd, res, std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0).count() / 1000.f);
245 }
246 if (retValGLO != 0 || retValRCT != 0 || retValGLOmd != 0 || retValCTP != 0) {
247 return 4;
248 }
249 return 0;
250}
251
252int main(int argc, char** argv)
253{
254 bpo::variables_map vm;
255 bpo::options_description opt_general(
256 "Create GRP-ECS object and upload to the CCDB\n"
257 "Usage:\n " +
258 std::string(argv[0]) +
259 "");
260 bpo::options_description opt_hidden("");
261 bpo::options_description opt_all;
262 bpo::positional_options_description opt_pos;
263
264 try {
265 auto add_option = opt_general.add_options();
266 add_option("help,h", "Print this help message");
267 add_option("period,p", bpo::value<std::string>(), "data taking period");
268 add_option("run,r", bpo::value<int>(), "run number");
269 add_option("run-type,t", bpo::value<int>()->default_value(int(GRPECSObject::RunType::NONE)), "run type");
270 add_option("hbf-per-tf,n", bpo::value<int>()->default_value(128), "number of HBFs per TF");
271 add_option("detectors,d", bpo::value<string>()->default_value("all"), "comma separated list of detectors");
272 add_option("continuous,c", bpo::value<string>()->default_value("ITS,TPC,TOF,MFT,MCH,MID,ZDC,FT0,FV0,FDD,CTP"), "comma separated list of detectors in continuous readout mode");
273 add_option("triggering,g", bpo::value<string>()->default_value("FT0,FV0"), "comma separated list of detectors providing a trigger");
274 add_option("flps,f", bpo::value<string>()->default_value(""), "comma separated list of FLPs in the data taking");
275 add_option("start-time,s", bpo::value<long>()->default_value(0), "ECS run start time in ms, now() if 0");
276 add_option("end-time,e", bpo::value<long>()->default_value(0), "ECS run end time in ms, start-time+3days is used if 0");
277 add_option("start-time-ctp", bpo::value<long>()->default_value(0), "run start CTP time in ms, same as ECS if not set or 0");
278 add_option("end-time-ctp", bpo::value<long>()->default_value(0), "run end CTP time in ms, same as ECS if not set or 0");
279 add_option("ccdb-server", bpo::value<std::string>()->default_value("http://alice-ccdb.cern.ch"), "CCDB server for upload, local file if empty");
280 add_option("ccdb-server-input", bpo::value<std::string>()->default_value(""), "CCDB server for inputs (if needed, e.g. CTPConfig), dy default ccdb-server is used");
281 add_option("meta-data,m", bpo::value<std::string>()->default_value("")->implicit_value(""), "metadata as key1=value1;key2=value2;..");
282 add_option("refresh", bpo::value<string>()->default_value("")->implicit_value("async"), R"(refresh server cache after upload: "none" (or ""), "async" (non-blocking) and "sync" (blocking))");
283 add_option("marginSOR", bpo::value<long>()->default_value(4 * o2::ccdb::CcdbObjectInfo::DAY), "validity at SOR");
284 add_option("marginEOR", bpo::value<long>()->default_value(10 * o2::ccdb::CcdbObjectInfo::MINUTE), "validity margin to add after EOR");
285 add_option("original-run,o", bpo::value<int>()->default_value(0), "if >0, use as the source run to create CTP/Config/Config object");
286 opt_all.add(opt_general).add(opt_hidden);
287 bpo::store(bpo::command_line_parser(argc, argv).options(opt_all).positional(opt_pos).run(), vm);
288
289 if (vm.count("help")) {
290 std::cout << opt_general << std::endl;
291 exit(0);
292 }
293
294 bpo::notify(vm);
295 } catch (bpo::error& e) {
296 std::cerr << "ERROR: " << e.what() << std::endl
297 << std::endl;
298 std::cerr << opt_general << std::endl;
299 exit(1);
300 } catch (std::exception& e) {
301 std::cerr << e.what() << ", application will now exit" << std::endl;
302 exit(2);
303 }
304 if (vm.count("run") == 0) {
305 std::cerr << "ERROR: "
306 << "obligatory run number is missing" << std::endl;
307 std::cerr << opt_general << std::endl;
308 exit(3);
309 }
310 if (vm.count("period") == 0) {
311 std::cerr << "ERROR: "
312 << "obligatory data taking period name is missing" << std::endl;
313 std::cerr << opt_general << std::endl;
314 exit(3);
315 }
316 std::string refreshStr = vm["refresh"].as<string>();
318 if (!refreshStr.empty() && refreshStr != "none") {
319 if (refreshStr == "async") {
320 refresh = CCDBRefreshMode::ASYNC;
321 } else if (refreshStr == "sync") {
322 refresh = CCDBRefreshMode::SYNC;
323 } else {
324 LOGP(fatal, R"(Wrong CCDB refresh mode {}, supported are "none" (or ""), "async" and "sync")", refreshStr);
325 }
326 }
327
329 vm["period"].as<std::string>(),
330 vm["run"].as<int>(),
331 vm["original-run"].as<int>(),
332 vm["run-type"].as<int>(),
333 vm["hbf-per-tf"].as<int>(),
334 vm["detectors"].as<std::string>(),
335 vm["continuous"].as<std::string>(),
336 vm["triggering"].as<std::string>(),
337 vm["flps"].as<std::string>(),
338 vm["start-time"].as<long>(),
339 vm["end-time"].as<long>(),
340 vm["start-time-ctp"].as<long>(),
341 vm["end-time-ctp"].as<long>(),
342 vm["marginSOR"].as<long>(),
343 vm["marginEOR"].as<long>(),
344 vm["ccdb-server"].as<std::string>(),
345 vm["ccdb-server-input"].as<std::string>(),
346 vm["meta-data"].as<std::string>(),
347 refresh);
348
349 if (retVal != 0) {
350 std::cerr << "ERROR: "
351 << "Either GLO/Config/GRPECS or RCT/Info/RunInformation could not be stored correctly to CCDB" << std::endl;
352 std::cerr << opt_general << std::endl;
353 exit(retVal);
354 }
355}
definition of CTPConfiguration and related CTP structures
int32_t retVal
Header of the AggregatedRunInfo struct.
Definition of the Names Generator class.
uint32_t res
Definition RawData.h:0
static std::string getGRPECSFileName(const std::string_view prefix=STANDARDSIMPREFIX)
Definition NameConf.cxx:64
static constexpr std::string_view CCDBOBJECT
Definition NameConf.h:66
static constexpr std::string_view CCDBRunTag
Definition NameConf.h:69
static BasicCCDBManager & instance()
int storeAsTFileAny(const T *obj, std::string const &path, std::map< std::string, std::string > const &metadata, long startValidityTimestamp=-1, long endValidityTimestamp=-1, std::vector< char >::size_type maxSize=0) const
Definition CcdbApi.h:157
void init(std::string const &hosts)
Definition CcdbApi.cxx:165
std::map< std::string, std::string > retrieveHeaders(std::string const &path, std::map< std::string, std::string > const &metadata, long timestamp=-1) const
Definition CcdbApi.cxx:1433
int storeAsBinaryFile(const char *buffer, size_t size, const std::string &fileName, const std::string &objectType, const std::string &path, const std::map< std::string, std::string > &metadata, long startValidityTimestamp, long endValidityTimestamp, std::vector< char >::size_type maxSize=0) const
Definition CcdbApi.cxx:351
int updateMetadata(std::string const &path, std::map< std::string, std::string > const &metadata, long timestamp, std::string const &id="", long newEOV=0)
Definition CcdbApi.cxx:1616
static constexpr long DAY
static constexpr long MINUTE
int loadConfigurationRun3(const std::string &ctpconfiguartion)
void setRunNumber(uint32_t runnumber)
Static class with identifiers, bitmasks and names for ALICE detectors.
Definition DetID.h:58
static constexpr ID TPC
Definition DetID.h:64
static mask_t getMask(const std::string_view detList)
detector masks from any non-alpha-num delimiter-separated list (empty if NONE is supplied)
Definition DetID.cxx:42
void setDetsContinuousReadOut(DetID::mask_t mask)
o2::parameters::GRPECS::RunType RunType
void addFLP(unsigned short flp)
void setDetsReadOut(DetID::mask_t mask)
void setTimeEnd(timePoint t)
void setTimeStart(timePoint t)
void setTimeEndCTP(timePoint t)
void setNHBFPerTF(uint32_t n)
void setTimeStartCTP(timePoint t)
void print() const
print itself
void setDataPeriod(const std::string v)
void setDetsTrigger(DetID::mask_t mask)
CCDBRefreshMode
@ SYNC
@ ASYNC
@ NONE
int createGRPECSObject(const std::string &dataPeriod, int run, int runOrig, int runTypeI, int nHBPerTF, const std::string &_detsReadout, const std::string &_detsContinuousRO, const std::string &_detsTrigger, const std::string &flpList, long tstart, long tend, long tstartCTP, long tendCTP, long marginAtSOR, long marginAtEOR, const std::string &ccdbServer="", std::string ccdbServerInp="", const std::string &metaDataStr="", CCDBRefreshMode refresh=CCDBRefreshMode::NONE)
GLint GLsizei count
Definition glcorearb.h:399
GLfloat v0
Definition glcorearb.h:811
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
Definition glcorearb.h:5034
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
Definition glcorearb.h:5034
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
static void trim(std::string &s)
Definition StringUtils.h:71
static std::vector< std::string > tokenize(const std::string &src, char delim, bool trimToken=true, bool skipEmpty=true)
static int replaceAll(std::string &s, const std::string &from, const std::string &to)
#define main
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
const std::string str