36 const std::string& _detsReadout,
37 const std::string& _detsContinuousRO,
38 const std::string& _detsTrigger,
39 const std::string& flpList,
46 const std::string& ccdbServer =
"",
47 const std::string& metaDataStr =
"",
55 std::regex regCTP(R
"((^\s*|,\s*)(TRG)(\s*,|\s*$))");
56 std::string detsReadout{std::regex_replace(_detsReadout, regCTP, "$1CTP$3")};
57 std::string detsContinuousRO{std::regex_replace(_detsContinuousRO, regCTP,
"$1CTP$3")};
58 std::string detsTrigger{std::regex_replace(_detsTrigger, regCTP,
"$1CTP$3")};
61 if (detMask.count() == 0) {
62 throw std::runtime_error(
"empty detectors list is provided");
64 if (runTypeI < 0 || runTypeI >=
int(GRPECSObject::RunType::NRUNTYPES)) {
65 LOGP(warning,
"run type {} is not recognized, consider updating GRPECSObject.h", runTypeI);
70 LOG(info) << tstart <<
" " << tend;
72 tstart = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
76 tendVal = tstart + marginAtSOR;
77 }
else if (tendVal < tend) {
78 tendVal = tend + marginAtEOR;
87 LOGP(important,
"Overriding TPC readout mode to triggered for runType={}", o2::parameters::GRPECS::RunTypeNames[runTypeI]);
98 for (
const auto& s : flpsVec) {
100 grpecs.
addFLP((
unsigned short)std::stoi(s));
101 }
catch (
const std::exception& e) {
102 LOG(alarm) <<
"could not convert string " << s <<
" to integer FLP ID, error : " << e.what();
106 std::map<std::string, std::string> metadata;
108 auto toKeyValPairs = [&metadata](
const std::string&
str) {
110 for (
auto& token :
v0) {
112 if (keyval.size() != 2) {
113 LOG(error) <<
"Illegal command-line key/value string: " << token;
117 LOGP(info,
"Adding key {} with value {}", keyval[0], keyval[1]);
118 metadata[keyval[0]] = keyval[1];
122 toKeyValPairs(metaDataStr);
124 if (!ccdbServer.empty()) {
126 const std::string objPath{
"GLO/Config/GRPECS"};
127 api.
init(ccdbServer);
128 metadata[
"responsible"] =
"ECS";
130 metadata[
"EOR"] = fmt::format(
"{}", tend);
131 retValGLO = api.
storeAsTFileAny(&grpecs, objPath, metadata, tstart, tendVal);
132 if (retValGLO == 0) {
133 LOGP(info,
"Uploaded to {}/{} with validity {}:{} for SOR:{}/EOR:{}", ccdbServer, objPath, tstart, tendVal, tstart, tend);
135 LOGP(alarm,
"Upload to {}/{} with validity {}:{} for SOR:{}/EOR:{} FAILED, returned with code {}", ccdbServer, objPath, tstart, tendVal, tstart, tend, retValGLO);
137 if ((runType == GRPECSObject::RunType::PHYSICS || runType == GRPECSObject::RunType::COSMICS) && tstart >= tend) {
139 std::map<std::string, std::string> mdRCT;
144 long startValRCT = (
long)run;
145 long endValRCT = (
long)(run + 1);
146 retValRCT = api.
storeAsBinaryFile(&tempChar,
sizeof(tempChar),
"tmp.dat",
"char",
"RCT/Info/RunInformation", mdRCT, startValRCT, endValRCT);
147 if (retValRCT == 0) {
148 LOGP(info,
"Uploaded initial RCT object to {}/{} with validity {}:{}", ccdbServer,
"RCT/Info/RunInformation", startValRCT, endValRCT);
150 LOGP(alarm,
"Upload of initial RCT object to {}/{} with validity {}:{} FAILED, returned with code {}", ccdbServer,
"RCT/Info/RunInformation", startValRCT, endValRCT, retValRCT);
155 metadata.erase(
"EOR");
157 const auto itETag = prevHeader.find(
"ETag");
158 if (itETag != prevHeader.end()) {
159 std::string etag = itETag->second;
160 etag.erase(remove(etag.begin(), etag.end(),
'\"'), etag.end());
161 LOGP(info,
"Overriding run {} SOR-only version {}{}{}/{} validity to match complete SOR/EOR version validity", run, ccdbServer, ccdbServer.back() ==
'/' ?
"" :
"/", prevHeader[
"Valid-From"], etag);
162 retValGLOmd = api.
updateMetadata(objPath, {}, std::max(tstart, tendVal - 1), etag, tendVal);
163 if (retValGLOmd != 0) {
164 LOGP(alarm,
"Overriding run {} SOR-only version {}{}{}/{} validity to match complete SOR/EOR version validity FAILED", run, ccdbServer, ccdbServer.back() ==
'/' ?
"" :
"/", prevHeader[
"Valid-From"], etag);
167 if (runType == GRPECSObject::RunType::PHYSICS || runType == GRPECSObject::RunType::COSMICS) {
169 std::map<std::string, std::string> mdRCT;
174 long startValRCT = (
long)run;
175 long endValRCT = (
long)(run + 1);
176 retValRCT = api.
updateMetadata(
"RCT/Info/RunInformation", mdRCT, startValRCT);
177 if (retValRCT == 0) {
178 LOGP(info,
"Updated RCT object to SOR:{}/EOR:{} SOX:{}/EOX:{}", tstart, tend, tstartCTP, tendCTP);
180 LOGP(alarm,
"Update of RCT object to SOR:{}/EOR:{} SOX:{}/EOX:{} FAILED, returned with code {}", tstart, tend, tstartCTP, tendCTP, retValRCT);
186 TFile grpF(fname.c_str(),
"recreate");
188 LOG(info) <<
"Stored to local file " << fname;
192 auto cmd = fmt::format(
"curl -I -i -s \"{}{}latest/%5Cw%7B3%7D/.*/`date +%s000`/?prepare={}\"", ccdbServer, ccdbServer.back() ==
'/' ?
"" :
"/", refresh ==
CCDBRefreshMode::SYNC ?
"sync" :
"true");
193 auto t0 = std::chrono::high_resolution_clock::now();
194 auto res = gSystem->Exec(cmd.c_str());
195 auto t1 = std::chrono::high_resolution_clock::now();
196 LOGP(info,
"Executed [{}] -> {} in {:.3f} s", cmd,
res, std::chrono::duration_cast<std::chrono::milliseconds>(
t1 -
t0).
count() / 1000.f);
198 if (retValGLO != 0 || retValRCT != 0 || retValGLOmd != 0) {
206 bpo::variables_map vm;
207 bpo::options_description opt_general(
208 "Create GRP-ECS object and upload to the CCDB\n"
210 std::string(argv[0]) +
212 bpo::options_description opt_hidden(
"");
213 bpo::options_description opt_all;
214 bpo::positional_options_description opt_pos;
217 auto add_option = opt_general.add_options();
218 add_option(
"help,h",
"Print this help message");
219 add_option(
"period,p", bpo::value<std::string>(),
"data taking period");
220 add_option(
"run,r", bpo::value<int>(),
"run number");
221 add_option(
"run-type,t", bpo::value<int>()->default_value(
int(GRPECSObject::RunType::NONE)),
"run type");
222 add_option(
"hbf-per-tf,n", bpo::value<int>()->default_value(128),
"number of HBFs per TF");
223 add_option(
"detectors,d", bpo::value<string>()->default_value(
"all"),
"comma separated list of detectors");
224 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");
225 add_option(
"triggering,g", bpo::value<string>()->default_value(
"FT0,FV0"),
"comma separated list of detectors providing a trigger");
226 add_option(
"flps,f", bpo::value<string>()->default_value(
""),
"comma separated list of FLPs in the data taking");
227 add_option(
"start-time,s", bpo::value<long>()->default_value(0),
"ECS run start time in ms, now() if 0");
228 add_option(
"end-time,e", bpo::value<long>()->default_value(0),
"ECS run end time in ms, start-time+3days is used if 0");
229 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");
230 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");
231 add_option(
"ccdb-server", bpo::value<std::string>()->default_value(
"http://alice-ccdb.cern.ch"),
"CCDB server for upload, local file if empty");
232 add_option(
"meta-data,m", bpo::value<std::string>()->default_value(
"")->implicit_value(
""),
"metadata as key1=value1;key2=value2;..");
233 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))");
236 opt_all.add(opt_general).add(opt_hidden);
237 bpo::store(bpo::command_line_parser(argc, argv).options(opt_all).positional(opt_pos).run(), vm);
239 if (vm.count(
"help")) {
240 std::cout << opt_general << std::endl;
245 }
catch (bpo::error& e) {
246 std::cerr <<
"ERROR: " << e.what() << std::endl
248 std::cerr << opt_general << std::endl;
250 }
catch (std::exception& e) {
251 std::cerr << e.what() <<
", application will now exit" << std::endl;
254 if (vm.count(
"run") == 0) {
255 std::cerr <<
"ERROR: "
256 <<
"obligator run number is missing" << std::endl;
257 std::cerr << opt_general << std::endl;
260 if (vm.count(
"period") == 0) {
261 std::cerr <<
"ERROR: "
262 <<
"obligator data taking period name is missing" << std::endl;
263 std::cerr << opt_general << std::endl;
266 std::string refreshStr = vm[
"refresh"].as<
string>();
268 if (!refreshStr.empty() && refreshStr !=
"none") {
269 if (refreshStr ==
"async") {
271 }
else if (refreshStr ==
"sync") {
274 LOGP(fatal, R
"(Wrong CCDB refresh mode {}, supported are "none" (or ""), "async" and "sync")", refreshStr);
279 vm[
"period"].as<std::string>(),
281 vm[
"run-type"].as<int>(),
282 vm[
"hbf-per-tf"].as<int>(),
283 vm[
"detectors"].as<std::string>(),
284 vm[
"continuous"].as<std::string>(),
285 vm[
"triggering"].as<std::string>(),
286 vm[
"flps"].as<std::string>(),
287 vm[
"start-time"].as<long>(),
288 vm[
"end-time"].as<long>(),
289 vm[
"start-time-ctp"].as<long>(),
290 vm[
"end-time-ctp"].as<long>(),
291 vm[
"marginSOR"].as<long>(),
292 vm[
"marginEOR"].as<long>(),
293 vm[
"ccdb-server"].as<std::string>(),
294 vm[
"meta-data"].as<std::string>(),
298 std::cerr <<
"ERROR: "
299 <<
"Either GLO/Config/GRPECS or RCT/Info/RunInformation could not be stored correctly to CCDB" << std::endl;
300 std::cerr << opt_general << std::endl;
int createGRPECSObject(const std::string &dataPeriod, int run, 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="", const std::string &metaDataStr="", CCDBRefreshMode refresh=CCDBRefreshMode::NONE)