39 const std::string& _detsReadout,
40 const std::string& _detsContinuousRO,
41 const std::string& _detsTrigger,
42 const std::string& flpList,
49 const std::string& ccdbServer =
"",
50 std::string ccdbServerInp =
"",
51 const std::string& metaDataStr =
"",
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")};
65 if (detMask.count() == 0) {
66 throw std::runtime_error(
"empty detectors list is provided");
68 if (runTypeI < 0 || runTypeI >=
int(GRPECSObject::RunType::NRUNTYPES)) {
69 LOGP(warning,
"run type {} is not recognized, consider updating GRPECSObject.h", runTypeI);
74 LOG(info) << tstart <<
" " << tend;
76 tstart = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
80 tendVal = tstart + marginAtSOR;
81 }
else if (tendVal < tend) {
82 tendVal = tend + marginAtEOR;
93 LOGP(important,
"Overriding TPC readout mode to triggered for runType={}", o2::parameters::GRPECS::RunTypeNames[runTypeI]);
104 for (
const auto& s : flpsVec) {
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();
112 std::map<std::string, std::string> metadata;
114 auto toKeyValPairs = [&metadata](
const std::string&
str) {
116 for (
auto& token :
v0) {
118 if (keyval.size() != 2) {
119 LOG(error) <<
"Illegal command-line key/value string: " << token;
123 LOGP(info,
"Adding key {} with value {}", keyval[0], keyval[1]);
124 metadata[keyval[0]] = keyval[1];
128 if (ccdbServerInp.empty()) {
129 ccdbServerInp = ccdbServer;
131 if (runOrig > 0 && runOrig != run && tend <= tstart && !ccdbServerInp.empty()) {
134 bcm.setURL(ccdbServerInp);
135 bcm.setFatalWhenNull(
false);
138 throw std::runtime_error(fmt::format(
"Failed to access CTP/Config/Config for original run {}", runOrig));
140 std::string cfstr = ctpConfig->
getConfigString(), srun{fmt::format(
"run {}", run)}, srunOrig{fmt::format(
"run {}", runOrig)};
144 }
catch (std::exception e) {
145 LOGP(error,
"Failed to create CTP/Config/Config from the original run {}, reason: {}", runOrig, e.what());
149 toKeyValPairs(metaDataStr);
151 if (!ccdbServer.empty()) {
154 const std::string objPath{
"GLO/Config/GRPECS"};
155 api.
init(ccdbServer);
156 metadata[
"responsible"] =
"ECS";
158 metadata[
"EOR"] = fmt::format(
"{}", tend);
159 retValGLO = api.
storeAsTFileAny(&grpecs, objPath, metadata, tstart, tendVal);
160 if (retValGLO == 0) {
161 LOGP(info,
"Uploaded to {}/{} with validity {}:{} for SOR:{}/EOR:{}", ccdbServer, objPath, tstart, tendVal, tstart, tend);
163 LOGP(alarm,
"Upload to {}/{} with validity {}:{} for SOR:{}/EOR:{} FAILED, returned with code {}", ccdbServer, objPath, tstart, tendVal, tstart, tend, retValGLO);
165 if ((runType == GRPECSObject::RunType::PHYSICS || runType == GRPECSObject::RunType::COSMICS) && tstart >= tend) {
167 std::map<std::string, std::string> mdRCT;
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);
178 LOGP(alarm,
"Upload of initial RCT object to {}/{} with validity {}:{} FAILED, returned with code {}", ccdbServer,
"RCT/Info/RunInformation", startValRCT, endValRCT, retValRCT);
183 metadata.erase(
"EOR");
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);
195 if (runType == GRPECSObject::RunType::PHYSICS || runType == GRPECSObject::RunType::COSMICS) {
197 std::map<std::string, std::string> mdRCT;
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);
208 LOGP(alarm,
"Update of RCT object to SOR:{}/EOR:{} SOX:{}/EOX:{} FAILED, returned with code {}", tstart, tend, tstartCTP, tendCTP, retValRCT);
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);
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);
226 TFile grpF(fname.c_str(),
"recreate");
229 LOGP(info,
"Stored GRPECS to local file {}", fname);
231 std::string ctnpfname = fmt::format(
"CTPConfig_{}_from_{}.root", run, runOrig);
232 TFile ctpF(ctnpfname.c_str(),
"recreate");
235 LOGP(info,
"Stored CTPConfig to local file {}", ctnpfname);
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);
246 if (retValGLO != 0 || retValRCT != 0 || retValGLOmd != 0 || retValCTP != 0) {
254 bpo::variables_map vm;
255 bpo::options_description opt_general(
256 "Create GRP-ECS object and upload to the CCDB\n"
258 std::string(argv[0]) +
260 bpo::options_description opt_hidden(
"");
261 bpo::options_description opt_all;
262 bpo::positional_options_description opt_pos;
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))");
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);
289 if (vm.count(
"help")) {
290 std::cout << opt_general << std::endl;
295 }
catch (bpo::error& e) {
296 std::cerr <<
"ERROR: " << e.what() << std::endl
298 std::cerr << opt_general << std::endl;
300 }
catch (std::exception& e) {
301 std::cerr << e.what() <<
", application will now exit" << std::endl;
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;
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;
316 std::string refreshStr = vm[
"refresh"].as<
string>();
318 if (!refreshStr.empty() && refreshStr !=
"none") {
319 if (refreshStr ==
"async") {
321 }
else if (refreshStr ==
"sync") {
324 LOGP(fatal, R
"(Wrong CCDB refresh mode {}, supported are "none" (or ""), "async" and "sync")", refreshStr);
329 vm[
"period"].as<std::string>(),
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>(),
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;
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)