12#include <boost/program_options.hpp>
19#include <fairlogger/Logger.h>
25#include <unordered_map>
53std::string defaultCCDBHost()
55 const char* host = std::getenv(
"ALICEO2_CCDB_HOST");
56 return (host && *host) ? std::string(host) :
std::
string(
"http://alice-ccdb.cern.ch");
94 runStart = soreor.first;
95 runEnd = soreor.second;
103 uint64_t runStart = -1;
104 uint64_t runEnd = -1;
105 uint64_t timestamp = -1;
114 std::cout <<
"** A GRP utility **\n\n";
115 std::cout <<
"Usage: " << argv[0] <<
" subcommand [sub-command-options]\n";
117 std::cout <<
"The following subcommands are available:\n";
118 std::cout <<
"\t createGRPs : Create baseline GRP objects/file\n";
119 std::cout <<
"\t anchorGRPs : Fetch GRP objects from CCDB based on run number\n";
120 std::cout <<
"\t print_GRPECS : print a GRPECS object/file\n";
121 std::cout <<
"\t print_GRPMAG : print a GRPMagField object/file\n";
122 std::cout <<
"\t print_GRPLHC : print a GRPLHCIF object/file\n";
123 std::cout <<
"\t setROMode : modify/set readoutMode in a GRPECS file\n";
125 std::cout <<
"Sub-command options can be seen with subcommand --help\n";
131void printGRP(std::string
const&
filename, std::string
const& objtype)
133 std::cout <<
"\nPrinting " << objtype <<
" from file " <<
filename <<
"\n\n";
139 std::cerr <<
"Error loading " << objtype <<
" objects from file " <<
filename <<
"\n";
146 printGRP<o2::parameters::GRPECSObject>(
filename,
"GRPECS");
151 printGRP<o2::parameters::GRPMagField>(
filename,
"GRPMAG");
156 printGRP<o2::parameters::GRPLHCIFData>(
filename,
"GRPLHCIF");
160 std::vector<std::string>
const& triggered,
bool clear =
false)
165 std::cout <<
"no filename given\n";
170 TFile flGRP(
filename.c_str(),
"update");
171 if (flGRP.IsZombie()) {
172 LOG(error) <<
"Failed to open GRPECS file " <<
filename <<
" in update mode ";
175 std::unique_ptr<GRPECSObject> grp(
static_cast<GRPECSObject*
>(flGRP.GetObjectChecked(grpName.c_str(), GRPECSObject::Class())));
180 if (grp->isDetReadOut(
id)) {
181 grp->remDetContinuousReadOut(
id);
187 for (
auto& detstr : continuous) {
190 if (grp->isDetReadOut(
id)) {
191 grp->addDetContinuousReadOut(
id);
192 LOG(info) <<
"Setting det " << detstr <<
" to continuous RO mode";
196 for (
auto& detstr : triggered) {
199 if (grp->isDetReadOut(
id)) {
200 grp->addDetTrigger(
id);
201 LOG(info) <<
"Setting det " << detstr <<
" to trigger CTP";
205 flGRP.WriteObjectAny(grp.get(), grp->Class(), grpName.c_str());
214 if (!std::filesystem::exists(
filename)) {
215 LOG(error) <<
"Input file " <<
filename <<
"does not exist\n";
219 std::string targetdir =
path + CCDBpath;
222 }
catch (std::exception e) {
223 LOGP(error,
"Could not create local snapshot cache directory {}, reason: {}", targetdir, e.what());
227 auto targetfile = std::filesystem::path(targetdir +
"/snapshot.root");
228 auto opts = std::filesystem::copy_options::overwrite_existing;
229 std::filesystem::copy_file(
filename, targetfile, opts);
230 if (std::filesystem::exists(targetfile)) {
231 LOG(info) <<
"file " <<
filename <<
" copied/published to " << targetfile;
237bool anchor_GRPs(
Options const& opts, std::vector<std::string>
const&
paths = {
"GLO/Config/GRPECS",
"GLO/Config/GRPMagField",
"GLO/Config/GRPLHCIF"})
240 gCCDBWrapper = std::move(std::make_unique<CCDBHelper>(opts));
245 const bool preserve_path =
true;
246 const std::string
filename(
"snapshot.root");
247 std::map<std::string, std::string>
filter;
249 for (
auto& p :
paths) {
250 LOG(info) <<
"Fetching " <<
p <<
" from CCDB";
260 const char* CCDBPATH =
"/GLO/Calib/MeanVertex";
261 if (opts.
vertex ==
"ccdb") {
264 LOG(info) <<
"Creating MeanVertex object on the fly using the InteractionDiamond params";
266 const auto& xyz =
param.position;
267 const auto& sigma =
param.width;
271 std::map<std::string, std::string> meta;
272 meta[
"Created-by"] =
"Monte Carlo GRPTool";
274 gCCDBWrapper = std::move(std::make_unique<CCDBHelper>(opts));
280 std::filesystem::path directory_path = opts.
publishto + CCDBPATH;
282 std::filesystem::file_time_type latest_time = std::filesystem::file_time_type::min();
284 std::filesystem::path latest_file;
286 for (
const auto& file : std::filesystem::directory_iterator(directory_path)) {
288 if (file.is_regular_file()) {
290 std::filesystem::file_time_type mod_time = std::filesystem::last_write_time(file.path());
292 if (mod_time > latest_time) {
293 latest_time = mod_time;
294 latest_file = file.path();
298 auto oldpath = latest_file;
299 auto newpath = latest_file.parent_path();
300 newpath.append(std::string(
"snapshot.root"));
301 std::filesystem::rename(oldpath, newpath);
311 uint64_t runStart = -1;
315 LOG(info) <<
"---- creating MeanVertex ----";
321 LOG(info) <<
" --- creating GRP ECS -----";
326 auto soreor = ccdbmgr.getRunDuration(opts.
run);
327 runStart = soreor.first;
331 std::vector<std::string> modules{};
335 std::vector<std::string> readout{};
337 for (
auto& detstr : readout) {
346 grp.
setRunType(o2::parameters::GRPECSObject::RunType::PHYSICS);
349 TFile grpF(grpfilename.c_str(),
"recreate");
362 LOG(info) <<
" --- creating magfield GRP -----";
375 LOG(info) <<
"Downloading mag field directly from CCDB";
376 if (!
anchor_GRPs(opts, {
"GLO/Config/GRPMagField"})) {
377 LOG(fatal) <<
"Downloading mag field failed";
381 printGRPMAG(std::string(opts.
publishto) + std::string(
"/GLO/Config/GRPMagField/snapshot.root"));
389 const std::unordered_map<int, std::pair<int, int>> field_to_current = {{2, {12000, 6000}},
391 {-2, {-12000, -6000}},
392 {-5, {-30000, -6000}},
395 auto currents_iter = field_to_current.find(fieldvalue);
396 if (currents_iter == field_to_current.end()) {
397 LOG(error) <<
" Could not lookup currents for fieldvalue " << fieldvalue;
401 o2::units::Current_t currDip = (*currents_iter).second.second;
402 o2::units::Current_t currL3 = (*currents_iter).second.first;
410 TFile grpF(grpfilename.c_str(),
"recreate");
421 LOG(info) <<
" --- creating GRP LHCIF -----";
423 LOG(info) <<
"Downloading complete GRPLHCIF object directly from CCDB";
451 LOG(info) <<
"Initializing with default bunch filling";
461 TFile grpF(grpfilename.c_str(),
"recreate");
508 bpo::options_description global(
"Global options");
509 global.add_options()(
"command", bpo::value<std::string>(),
"command to execute")(
"subargs", bpo::value<std::vector<std::string>>(),
"Arguments for command");
510 global.add_options()(
"help,h",
"Produce help message.");
512 bpo::positional_options_description
pos;
513 pos.add(
"command", 1).add(
"subargs", -1);
515 bpo::variables_map vm;
516 bpo::parsed_options parsed{
nullptr};
518 parsed = bpo::command_line_parser(argc, argv).options(global).positional(
pos).allow_unregistered().run();
520 bpo::store(parsed, vm);
523 if (vm.count(
"help") > 0 && vm.count(
"command") == 0) {
527 }
catch (
const bpo::error& e) {
528 std::cerr << e.what() <<
"\n\n";
529 std::cerr <<
"Error parsing global options; Available options:\n";
530 std::cerr << global << std::endl;
534 auto subparse = [&parsed](
auto& desc,
auto& vm, std::string
const& command_name) {
538 std::vector<std::string> opts = bpo::collect_unrecognized(parsed.options, bpo::include_positional);
542 bpo::store(bpo::command_line_parser(opts).options(desc).run(), vm);
545 if (vm.count(
"help")) {
546 std::cout << desc << std::endl;
549 }
catch (
const bpo::error& e) {
550 std::cerr << e.what() <<
"\n\n";
551 std::cerr <<
"Error parsing options for " << command_name <<
" Available options:\n";
552 std::cerr << desc << std::endl;
558 std::string cmd = vm[
"command"].as<std::string>();
560 if (cmd ==
"anchorGRPs") {
563 bpo::options_description desc(
"anchor GRP options");
566 desc.add_options()(
"run", bpo::value<int>(&optvalues.
run)->default_value(-1),
"Run number");
567 desc.add_options()(
"print",
"print resulting GRPs");
568 desc.add_options()(
"publishto", bpo::value<std::string>(&optvalues.
publishto)->default_value(
"GRP"),
"Base path under which GRP objects should be published on disc. This path can serve as lookup for CCDB queries of the GRP objects.");
569 if (!subparse(desc, vm,
"anchorGRPs")) {
572 if (vm.count(
"print") > 0) {
573 optvalues.
print =
true;
575 }
else if (cmd ==
"createGRPs") {
579 bpo::options_description desc(
"create options");
580 desc.add_options()(
"detectorList", bpo::value<std::string>(&optvalues.
detectorList)->default_value(
"ALICE2"),
"Pick a specific version of ALICE, for specifics check the o2-sim description");
581 desc.add_options()(
"readoutDets", bpo::value<std::vector<std::string>>(&optvalues.
readout)->multitoken()->default_value(std::vector<std::string>({
"all"}),
"all Run3 detectors"),
"Detector list to be readout/active");
582 desc.add_options()(
"skipReadout", bpo::value<std::vector<std::string>>(&optvalues.
skipreadout)->multitoken()->default_value(std::vector<std::string>(),
"nothing skipped"),
"list of inactive detectors (precendence over --readout)");
583 desc.add_options()(
"run", bpo::value<int>(&optvalues.
run)->default_value(-1),
"Run number");
584 desc.add_options()(
"hbfpertf", bpo::value<int>(&optvalues.
orbitsPerTF)->default_value(128),
"heart beat frames per timeframe (timeframelength)");
585 desc.add_options()(
"field", bpo::value<std::string>(&optvalues.
fieldstring)->default_value(
"-5"),
"L3 field rounded to kGauss, allowed values +-2,+-5 and 0; +-<intKGaus>U for uniform field");
586 desc.add_options()(
"outprefix,o", bpo::value<std::string>(&optvalues.
outprefix)->default_value(
"o2sim"),
"Prefix for GRP output files");
587 desc.add_options()(
"bcPatternFile", bpo::value<std::string>(&optvalues.
bcPatternFile)->default_value(
""),
"Interacting BC pattern file (e.g. from CreateBCPattern.C)");
588 desc.add_options()(
"lhcif-CCDB",
"take GRPLHCIF directly from CCDB");
589 desc.add_options()(
"print",
"print resulting GRPs");
590 desc.add_options()(
"publishto", bpo::value<std::string>(&optvalues.
publishto)->default_value(
""),
"Base path under which GRP objects should be published on disc. This path can serve as lookup for CCDB queries of the GRP objects.");
591 desc.add_options()(
"isRun5", bpo::bool_switch(&optvalues.
isRun5),
"Whether or not to expect a Run5 detector configuration. (deprecated, use detectorList option)");
592 desc.add_options()(
"vertex", bpo::value<std::string>(&optvalues.
vertex)->default_value(
"ccdb"),
"How the vertex is to be initialized. Default is CCDB. Alternative is \"Diamond\" which is constructing the mean vertex from the Diamond param via the configKeyValues path");
593 desc.add_options()(
"timestamp", bpo::value<uint64_t>(&optvalues.
timestamp)->default_value(0),
"Force timestamp to be used (useful when anchoring)");
594 desc.add_options()(
"configKeyValues", bpo::value<std::string>(&optvalues.
configKeyValues)->default_value(
""),
"Semicolon separated key=value strings (e.g.: 'TPC.gasDensity=1;...')");
595 if (!subparse(desc, vm,
"createGRPs")) {
598 if (vm.count(
"print") > 0) {
599 optvalues.
print =
true;
601 if (vm.count(
"lhcif-CCDB") > 0) {
604 auto vertexmode = vm[
"vertex"].as<std::string>();
605 if (!(vertexmode ==
"ccdb" || vertexmode ==
"Diamond")) {
611 }
else if (cmd ==
"setROMode") {
614 bpo::options_description desc(
"setting detector readout modes");
615 desc.add_options()(
"file,f", bpo::value<std::string>(&optvalues.
grpfilename)->default_value(
"o2sim_grpecs.root"),
"Path to GRPECS file");
616 desc.add_options()(
"continuousRO", bpo::value<std::vector<std::string>>(&optvalues.
continuous)->multitoken()->default_value(std::vector<std::string>({
"all"}),
"all active detectors"),
"List of detectors to set to continuous mode");
617 desc.add_options()(
"triggerCTP", bpo::value<std::vector<std::string>>(&optvalues.
triggered)->multitoken()->default_value(std::vector<std::string>({
""}),
"none"),
"List of detectors to trigger CTP");
618 desc.add_options()(
"clear",
"clears all RO modes (prio to applying other options)");
619 if (!subparse(desc, vm,
"setROMode")) {
622 if (vm.count(
"clear") > 0) {
625 }
else if (cmd ==
"print_GRPECS") {
628 bpo::options_description desc(
"print options");
629 desc.add_options()(
"file,f", bpo::value<std::string>(&optvalues.
grpfilename),
"Path to GRP file");
630 if (!subparse(desc, vm,
"print_GRPECS")) {
633 }
else if (cmd ==
"print_GRPLHC") {
636 bpo::options_description desc(
"print options");
637 desc.add_options()(
"file,f", bpo::value<std::string>(&optvalues.
grpfilename),
"Path to GRP file");
638 if (!subparse(desc, vm,
"print_GRPECS")) {
641 }
else if (cmd ==
"print_GRPMAG") {
644 bpo::options_description desc(
"print options");
645 desc.add_options()(
"file,f", bpo::value<std::string>(&optvalues.
grpfilename),
"Path to GRP file");
646 if (!subparse(desc, vm,
"print_GRPECS")) {
650 std::cerr <<
"Error: Unknown command " << cmd << std::endl;
657int main(
int argc,
char* argv[])
663 std::cout <<
"Parse options failed\n";
Header of the AggregatedRunInfo struct.
container for the LHC InterFace data
Header of the General Run Parameters object for B field values.
Definition of the Names Generator class.
static BunchFilling * loadFrom(const std::string &fileName, const std::string &objName="")
static std::string getGRPECSFileName(const std::string_view prefix=STANDARDSIMPREFIX)
static std::string getGRPLHCIFFileName(const std::string_view prefix=STANDARDSIMPREFIX)
static constexpr std::string_view CCDBOBJECT
static std::string getGRPMagFieldFileName(const std::string_view prefix=STANDARDSIMPREFIX)
static BasicCCDBManager & instance()
std::pair< int64_t, int64_t > getRunDuration(int runnumber, bool fatal=true)
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
void init(std::string const &hosts)
static const InteractionDiamondParam & Instance()
static void updateFromString(std::string const &)
static bool parseFieldString(std::string const &fieldstring, int &fieldvalue, o2::conf::SimFieldMode &mode)
static void determineReadoutDetectors(std::vector< std::string > const &active, std::vector< std::string > const &enabledRO, std::vector< std::string > const &skippedRO, std::vector< std::string > &finalRO)
static bool determineActiveModulesList(const std::string &version, std::vector< std::string > const &input, std::vector< std::string > const &skipped, std::vector< std::string > &active)
Static class with identifiers, bitmasks and names for ALICE detectors.
static constexpr ID First
static constexpr ID Last
if extra detectors added, update this !!!
static constexpr bool alwaysTriggeredRO(DetID::ID det)
void setTimeEnd(timePoint t)
void setTimeStart(timePoint t)
void setIsMC(bool v=true)
void setNHBFPerTF(uint32_t n)
void addDetReadOut(DetID id)
add specific detector to the list of readout detectors
void addDetContinuousReadOut(DetID id)
add specific detector to the list of continuously readout detectors
void print() const
print itself
void setRunType(RunType t)
void setBeamAZ(int a, int z, beamDirection beam)
long getBeamEnergyPerZTime() const
void setBunchFillingWithTime(std::pair< long, o2::BunchFilling > p)
void setBeamEnergyPerZWithTime(std::pair< long, int32_t > p)
void setCrossingAngleWithTime(std::pair< long, o2::units::AngleRad_t > p)
void setAtomicNumberB1WithTime(std::pair< long, int32_t > p)
void setFillNumberWithTime(std::pair< long, int32_t > p)
void setInjectionSchemeWithTime(std::pair< long, std::string > p)
void setAtomicNumberB2WithTime(std::pair< long, int32_t > p)
void setDipoleCurrent(o2::units::Current_t v)
void print() const
print itself
void setL3Current(o2::units::Current_t v)
void setFieldUniformity(bool v)
GLsizei const GLchar *const * string
GLsizei const GLuint * paths
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLsizei const GLchar *const * path
std::string timestamp() noexcept
void createDirectoriesIfAbsent(std::string const &path)
std::vector< std::string > readout
std::string configKeyValues
std::vector< std::string > triggered
std::vector< std::string > skipreadout
std::vector< std::string > continuous
std::string bcPatternFile
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"