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>
19#include "CCDB/CcdbApi.h"
22
26namespace bpo = boost::program_options;
27
31
32int createGRPECSObject(const std::string& dataPeriod,
33 int run,
34 int runTypeI,
35 int nHBPerTF,
36 const std::string& _detsReadout,
37 const std::string& _detsContinuousRO,
38 const std::string& _detsTrigger,
39 const std::string& flpList,
40 long tstart,
41 long tend,
42 long tstartCTP,
43 long tendCTP,
44 long marginAtSOR,
45 long marginAtEOR,
46 const std::string& ccdbServer = "",
47 const std::string& metaDataStr = "",
49{
50 int retValGLO = 0;
51 int retValRCT = 0;
52 int retValGLOmd = 0;
53
54 // substitute TRG by CTP
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")};
59
60 auto detMask = DetID::getMask(detsReadout);
61 if (detMask.count() == 0) {
62 throw std::runtime_error("empty detectors list is provided");
63 }
64 if (runTypeI < 0 || runTypeI >= int(GRPECSObject::RunType::NRUNTYPES)) {
65 LOGP(warning, "run type {} is not recognized, consider updating GRPECSObject.h", runTypeI);
66 }
67 auto runType = (GRPECSObject::RunType)runTypeI;
68 auto detMaskCont = detMask & DetID::getMask(detsContinuousRO);
69 auto detMaskTrig = detMask & DetID::getMask(detsTrigger);
70 LOG(info) << tstart << " " << tend;
71 if (tstart == 0) {
72 tstart = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
73 }
74 long tendVal = 0;
75 if (tend < tstart) {
76 tendVal = tstart + marginAtSOR;
77 } else if (tendVal < tend) {
78 tendVal = tend + marginAtEOR;
79 }
80 GRPECSObject grpecs;
81 grpecs.setTimeStart(tstart);
82 grpecs.setTimeEnd(tend);
83 grpecs.setTimeStartCTP(tstartCTP);
84 grpecs.setTimeEndCTP(tendCTP);
85
86 if (runType == GRPECSObject::RunType::LASER && detMask[DetID::TPC] && detMaskCont[DetID::TPC]) {
87 LOGP(important, "Overriding TPC readout mode to triggered for runType={}", o2::parameters::GRPECS::RunTypeNames[runTypeI]);
88 detMaskCont.reset(DetID::TPC);
89 }
90 grpecs.setNHBFPerTF(nHBPerTF);
91 grpecs.setDetsReadOut(detMask);
92 grpecs.setDetsContinuousReadOut(detMaskCont);
93 grpecs.setDetsTrigger(detMaskTrig);
94 grpecs.setRun(run);
95 grpecs.setRunType((GRPECSObject::RunType)runType);
96 grpecs.setDataPeriod(dataPeriod);
97 auto flpsVec = o2::utils::Str::tokenize(flpList, ',');
98 for (const auto& s : flpsVec) {
99 try {
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();
103 }
104 }
105 grpecs.print();
106 std::map<std::string, std::string> metadata;
107
108 auto toKeyValPairs = [&metadata](const std::string& str) {
109 auto v0 = o2::utils::Str::tokenize(str, ';', true);
110 for (auto& token : v0) {
111 auto keyval = o2::utils::Str::tokenize(token, '=', false);
112 if (keyval.size() != 2) {
113 LOG(error) << "Illegal command-line key/value string: " << token;
114 continue;
115 }
116 o2::utils::Str::trim(keyval[1]);
117 LOGP(info, "Adding key {} with value {}", keyval[0], keyval[1]);
118 metadata[keyval[0]] = keyval[1];
119 }
120 };
121
122 toKeyValPairs(metaDataStr);
123
124 if (!ccdbServer.empty()) {
125 CcdbApi api;
126 const std::string objPath{"GLO/Config/GRPECS"};
127 api.init(ccdbServer);
128 metadata["responsible"] = "ECS";
129 metadata[o2::base::NameConf::CCDBRunTag.data()] = std::to_string(run);
130 metadata["EOR"] = fmt::format("{}", tend);
131 retValGLO = api.storeAsTFileAny(&grpecs, objPath, metadata, tstart, tendVal); // making it 1-year valid to be sure we have something
132 if (retValGLO == 0) {
133 LOGP(info, "Uploaded to {}/{} with validity {}:{} for SOR:{}/EOR:{}", ccdbServer, objPath, tstart, tendVal, tstart, tend);
134 } else {
135 LOGP(alarm, "Upload to {}/{} with validity {}:{} for SOR:{}/EOR:{} FAILED, returned with code {}", ccdbServer, objPath, tstart, tendVal, tstart, tend, retValGLO);
136 }
137 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
138 char tempChar{};
139 std::map<std::string, std::string> mdRCT;
140 mdRCT["SOR"] = std::to_string(tstart);
141 mdRCT["EOR"] = std::to_string(tend);
142 mdRCT["SOX"] = std::to_string(tstartCTP);
143 mdRCT["EOX"] = std::to_string(tendCTP);
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);
149 } else {
150 LOGP(alarm, "Upload of initial RCT object to {}/{} with validity {}:{} FAILED, returned with code {}", ccdbServer, "RCT/Info/RunInformation", startValRCT, endValRCT, retValRCT);
151 }
152 }
153 if (tend > tstart) {
154 // override SOR version to the same limits
155 metadata.erase("EOR");
156 auto prevHeader = api.retrieveHeaders(objPath, metadata, tendVal + 1); // is there an object to override
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);
165 }
166 }
167 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
168 char tempChar{};
169 std::map<std::string, std::string> mdRCT;
170 mdRCT["SOR"] = std::to_string(tstart);
171 mdRCT["EOR"] = std::to_string(tend);
172 mdRCT["SOX"] = std::to_string(tstartCTP);
173 mdRCT["EOX"] = std::to_string(tendCTP);
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);
179 } else {
180 LOGP(alarm, "Update of RCT object to SOR:{}/EOR:{} SOX:{}/EOX:{} FAILED, returned with code {}", tstart, tend, tstartCTP, tendCTP, retValRCT);
181 }
182 }
183 }
184 } else { // write a local file
186 TFile grpF(fname.c_str(), "recreate");
187 grpF.WriteObjectAny(&grpecs, grpecs.Class(), o2::base::NameConf::CCDBOBJECT.data());
188 LOG(info) << "Stored to local file " << fname;
189 }
190 //
191 if (refresh != CCDBRefreshMode::NONE && !ccdbServer.empty()) {
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);
197 }
198 if (retValGLO != 0 || retValRCT != 0 || retValGLOmd != 0) {
199 return 4;
200 }
201 return 0;
202}
203
204int main(int argc, char** argv)
205{
206 bpo::variables_map vm;
207 bpo::options_description opt_general(
208 "Create GRP-ECS object and upload to the CCDB\n"
209 "Usage:\n " +
210 std::string(argv[0]) +
211 "");
212 bpo::options_description opt_hidden("");
213 bpo::options_description opt_all;
214 bpo::positional_options_description opt_pos;
215
216 try {
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))");
234 add_option("marginSOR", bpo::value<long>()->default_value(4 * o2::ccdb::CcdbObjectInfo::DAY), "validity at SOR");
235 add_option("marginEOR", bpo::value<long>()->default_value(10 * o2::ccdb::CcdbObjectInfo::MINUTE), "validity margin to add after EOR");
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);
238
239 if (vm.count("help")) {
240 std::cout << opt_general << std::endl;
241 exit(0);
242 }
243
244 bpo::notify(vm);
245 } catch (bpo::error& e) {
246 std::cerr << "ERROR: " << e.what() << std::endl
247 << std::endl;
248 std::cerr << opt_general << std::endl;
249 exit(1);
250 } catch (std::exception& e) {
251 std::cerr << e.what() << ", application will now exit" << std::endl;
252 exit(2);
253 }
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;
258 exit(3);
259 }
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;
264 exit(3);
265 }
266 std::string refreshStr = vm["refresh"].as<string>();
268 if (!refreshStr.empty() && refreshStr != "none") {
269 if (refreshStr == "async") {
270 refresh = CCDBRefreshMode::ASYNC;
271 } else if (refreshStr == "sync") {
272 refresh = CCDBRefreshMode::SYNC;
273 } else {
274 LOGP(fatal, R"(Wrong CCDB refresh mode {}, supported are "none" (or ""), "async" and "sync")", refreshStr);
275 }
276 }
277
279 vm["period"].as<std::string>(),
280 vm["run"].as<int>(),
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>(),
295 refresh);
296
297 if (retVal != 0) {
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;
301 exit(retVal);
302 }
303}
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
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:1416
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:1599
static constexpr long DAY
static constexpr long MINUTE
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)
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)
CCDBRefreshMode
@ SYNC
@ ASYNC
@ 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)
#define main
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
const std::string str