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