12#include <boost/program_options.hpp>
18#include <fairlogger/Logger.h>
24#include <unordered_map>
63 std::string
ccdbhost =
"http://alice-ccdb.cern.ch";
80 runStart = soreor.first;
81 runEnd = soreor.second;
89 uint64_t runStart = -1;
91 uint64_t timestamp = -1;
100 std::cout <<
"** A GRP utility **\n\n";
101 std::cout <<
"Usage: " << argv[0] <<
" subcommand [sub-command-options]\n";
103 std::cout <<
"The following subcommands are available:\n";
104 std::cout <<
"\t createGRPs : Create baseline GRP objects/file\n";
105 std::cout <<
"\t anchorGRPs : Fetch GRP objects from CCDB based on run number\n";
106 std::cout <<
"\t print_GRPECS : print a GRPECS object/file\n";
107 std::cout <<
"\t print_GRPMAG : print a GRPMagField object/file\n";
108 std::cout <<
"\t print_GRPLHC : print a GRPLHCIF object/file\n";
109 std::cout <<
"\t setROMode : modify/set readoutMode in a GRPECS file\n";
111 std::cout <<
"Sub-command options can be seen with subcommand --help\n";
117void printGRP(std::string
const&
filename, std::string
const& objtype)
119 std::cout <<
"\nPrinting " << objtype <<
" from file " <<
filename <<
"\n\n";
125 std::cerr <<
"Error loading " << objtype <<
" objects from file " <<
filename <<
"\n";
132 printGRP<o2::parameters::GRPECSObject>(
filename,
"GRPECS");
137 printGRP<o2::parameters::GRPMagField>(
filename,
"GRPMAG");
142 printGRP<o2::parameters::GRPLHCIFData>(
filename,
"GRPLHCIF");
146 std::vector<std::string>
const& triggered,
bool clear =
false)
151 std::cout <<
"no filename given\n";
156 TFile flGRP(
filename.c_str(),
"update");
157 if (flGRP.IsZombie()) {
158 LOG(error) <<
"Failed to open GRPECS file " <<
filename <<
" in update mode ";
161 std::unique_ptr<GRPECSObject> grp(
static_cast<GRPECSObject*
>(flGRP.GetObjectChecked(grpName.c_str(), GRPECSObject::Class())));
166 if (grp->isDetReadOut(
id)) {
167 grp->remDetContinuousReadOut(
id);
173 for (
auto& detstr : continuous) {
176 if (grp->isDetReadOut(
id)) {
177 grp->addDetContinuousReadOut(
id);
178 LOG(info) <<
"Setting det " << detstr <<
" to continuous RO mode";
182 for (
auto& detstr : triggered) {
185 if (grp->isDetReadOut(
id)) {
186 grp->addDetTrigger(
id);
187 LOG(info) <<
"Setting det " << detstr <<
" to trigger CTP";
191 flGRP.WriteObjectAny(grp.get(), grp->Class(), grpName.c_str());
200 if (!std::filesystem::exists(
filename)) {
201 LOG(error) <<
"Input file " <<
filename <<
"does not exist\n";
205 std::string targetdir =
path + CCDBpath;
208 }
catch (std::exception e) {
209 LOGP(error,
"Could not create local snapshot cache directory {}, reason: {}", targetdir, e.what());
213 auto targetfile = std::filesystem::path(targetdir +
"/snapshot.root");
214 auto opts = std::filesystem::copy_options::overwrite_existing;
215 std::filesystem::copy_file(
filename, targetfile, opts);
216 if (std::filesystem::exists(targetfile)) {
217 LOG(info) <<
"file " <<
filename <<
" copied/published to " << targetfile;
223bool anchor_GRPs(
Options const& opts, std::vector<std::string>
const&
paths = {
"GLO/Config/GRPECS",
"GLO/Config/GRPMagField",
"GLO/Config/GRPLHCIF"})
226 gCCDBWrapper = std::move(std::make_unique<CCDBHelper>(opts));
231 const bool preserve_path =
true;
232 const std::string
filename(
"snapshot.root");
233 std::map<std::string, std::string>
filter;
235 for (
auto& p :
paths) {
236 LOG(info) <<
"Fetching " << p <<
" from CCDB";
246 const char* CCDBPATH =
"/GLO/Calib/MeanVertex";
247 if (opts.
vertex ==
"ccdb") {
250 LOG(info) <<
"Creating MeanVertex object on the fly using the InteractionDiamond params";
252 const auto& xyz =
param.position;
253 const auto& sigma =
param.width;
257 std::map<std::string, std::string> meta;
258 meta[
"Created-by"] =
"Monte Carlo GRPTool";
260 gCCDBWrapper = std::move(std::make_unique<CCDBHelper>(opts));
266 std::filesystem::path directory_path = opts.
publishto + CCDBPATH;
268 std::filesystem::file_time_type latest_time = std::filesystem::file_time_type::min();
270 std::filesystem::path latest_file;
272 for (
const auto&
file : std::filesystem::directory_iterator(directory_path)) {
274 if (
file.is_regular_file()) {
276 std::filesystem::file_time_type mod_time = std::filesystem::last_write_time(
file.path());
278 if (mod_time > latest_time) {
279 latest_time = mod_time;
280 latest_file =
file.path();
284 auto oldpath = latest_file;
285 auto newpath = latest_file.parent_path();
286 newpath.append(std::string(
"snapshot.root"));
287 std::filesystem::rename(oldpath, newpath);
297 uint64_t runStart = -1;
301 LOG(info) <<
"---- creating MeanVertex ----";
307 LOG(info) <<
" --- creating GRP ECS -----";
312 auto soreor = ccdbmgr.getRunDuration(opts.
run);
313 runStart = soreor.first;
317 std::vector<std::string> modules{};
321 std::vector<std::string> readout{};
323 for (
auto& detstr : readout) {
332 grp.
setRunType(o2::parameters::GRPECSObject::RunType::PHYSICS);
335 TFile grpF(grpfilename.c_str(),
"recreate");
348 LOG(info) <<
" --- creating magfield GRP -----";
361 LOG(info) <<
"Downloading mag field directly from CCDB";
362 if (!
anchor_GRPs(opts, {
"GLO/Config/GRPMagField"})) {
363 LOG(fatal) <<
"Downloading mag field failed";
367 printGRPMAG(std::string(opts.
publishto) + std::string(
"/GLO/Config/GRPMagField/snapshot.root"));
375 const std::unordered_map<int, std::pair<int, int>> field_to_current = {{2, {12000, 6000}},
377 {-2, {-12000, -6000}},
378 {-5, {-30000, -6000}},
381 auto currents_iter = field_to_current.find(fieldvalue);
382 if (currents_iter == field_to_current.end()) {
383 LOG(error) <<
" Could not lookup currents for fieldvalue " << fieldvalue;
387 o2::units::Current_t currDip = (*currents_iter).second.second;
388 o2::units::Current_t currL3 = (*currents_iter).second.first;
396 TFile grpF(grpfilename.c_str(),
"recreate");
407 LOG(info) <<
" --- creating GRP LHCIF -----";
409 LOG(info) <<
"Downloading complete GRPLHCIF object directly from CCDB";
437 LOG(info) <<
"Initializing with default bunch filling";
447 TFile grpF(grpfilename.c_str(),
"recreate");
494 bpo::options_description global(
"Global options");
495 global.add_options()(
"command", bpo::value<std::string>(),
"command to execute")(
"subargs", bpo::value<std::vector<std::string>>(),
"Arguments for command");
496 global.add_options()(
"help,h",
"Produce help message.");
498 bpo::positional_options_description
pos;
499 pos.add(
"command", 1).add(
"subargs", -1);
501 bpo::variables_map vm;
502 bpo::parsed_options parsed{
nullptr};
504 parsed = bpo::command_line_parser(argc, argv).options(global).positional(
pos).allow_unregistered().run();
506 bpo::store(parsed, vm);
509 if (vm.count(
"help") > 0 && vm.count(
"command") == 0) {
513 }
catch (
const bpo::error& e) {
514 std::cerr << e.what() <<
"\n\n";
515 std::cerr <<
"Error parsing global options; Available options:\n";
516 std::cerr << global << std::endl;
520 auto subparse = [&parsed](
auto& desc,
auto& vm, std::string
const& command_name) {
524 std::vector<std::string> opts = bpo::collect_unrecognized(parsed.options, bpo::include_positional);
528 bpo::store(bpo::command_line_parser(opts).options(desc).run(), vm);
531 if (vm.count(
"help")) {
532 std::cout << desc << std::endl;
535 }
catch (
const bpo::error& e) {
536 std::cerr << e.what() <<
"\n\n";
537 std::cerr <<
"Error parsing options for " << command_name <<
" Available options:\n";
538 std::cerr << desc << std::endl;
544 std::string cmd = vm[
"command"].as<std::string>();
546 if (cmd ==
"anchorGRPs") {
549 bpo::options_description desc(
"anchor GRP options");
552 desc.add_options()(
"run", bpo::value<int>(&optvalues.
run)->default_value(-1),
"Run number");
553 desc.add_options()(
"print",
"print resulting GRPs");
554 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.");
555 if (!subparse(desc, vm,
"anchorGRPs")) {
558 if (vm.count(
"print") > 0) {
559 optvalues.
print =
true;
561 }
else if (cmd ==
"createGRPs") {
565 bpo::options_description desc(
"create options");
566 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");
567 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");
568 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)");
569 desc.add_options()(
"run", bpo::value<int>(&optvalues.
run)->default_value(-1),
"Run number");
570 desc.add_options()(
"hbfpertf", bpo::value<int>(&optvalues.
orbitsPerTF)->default_value(128),
"heart beat frames per timeframe (timeframelength)");
571 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");
572 desc.add_options()(
"outprefix,o", bpo::value<std::string>(&optvalues.
outprefix)->default_value(
"o2sim"),
"Prefix for GRP output files");
573 desc.add_options()(
"bcPatternFile", bpo::value<std::string>(&optvalues.
bcPatternFile)->default_value(
""),
"Interacting BC pattern file (e.g. from CreateBCPattern.C)");
574 desc.add_options()(
"lhcif-CCDB",
"take GRPLHCIF directly from CCDB");
575 desc.add_options()(
"print",
"print resulting GRPs");
576 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.");
577 desc.add_options()(
"isRun5", bpo::bool_switch(&optvalues.
isRun5),
"Whether or not to expect a Run5 detector configuration. (deprecated, use detectorList option)");
578 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");
579 desc.add_options()(
"timestamp", bpo::value<uint64_t>(&optvalues.
timestamp)->default_value(0),
"Force timestamp to be used (useful when anchoring)");
580 desc.add_options()(
"configKeyValues", bpo::value<std::string>(&optvalues.
configKeyValues)->default_value(
""),
"Semicolon separated key=value strings (e.g.: 'TPC.gasDensity=1;...')");
581 if (!subparse(desc, vm,
"createGRPs")) {
584 if (vm.count(
"print") > 0) {
585 optvalues.
print =
true;
587 if (vm.count(
"lhcif-CCDB") > 0) {
590 auto vertexmode = vm[
"vertex"].as<std::string>();
591 if (!(vertexmode ==
"ccdb" || vertexmode ==
"Diamond")) {
597 }
else if (cmd ==
"setROMode") {
600 bpo::options_description desc(
"setting detector readout modes");
601 desc.add_options()(
"file,f", bpo::value<std::string>(&optvalues.
grpfilename)->default_value(
"o2sim_grpecs.root"),
"Path to GRPECS file");
602 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");
603 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");
604 desc.add_options()(
"clear",
"clears all RO modes (prio to applying other options)");
605 if (!subparse(desc, vm,
"setROMode")) {
608 if (vm.count(
"clear") > 0) {
611 }
else if (cmd ==
"print_GRPECS") {
614 bpo::options_description desc(
"print options");
615 desc.add_options()(
"file,f", bpo::value<std::string>(&optvalues.
grpfilename),
"Path to GRP file");
616 if (!subparse(desc, vm,
"print_GRPECS")) {
619 }
else if (cmd ==
"print_GRPLHC") {
622 bpo::options_description desc(
"print options");
623 desc.add_options()(
"file,f", bpo::value<std::string>(&optvalues.
grpfilename),
"Path to GRP file");
624 if (!subparse(desc, vm,
"print_GRPECS")) {
627 }
else if (cmd ==
"print_GRPMAG") {
630 bpo::options_description desc(
"print options");
631 desc.add_options()(
"file,f", bpo::value<std::string>(&optvalues.
grpfilename),
"Path to GRP file");
632 if (!subparse(desc, vm,
"print_GRPECS")) {
636 std::cerr <<
"Error: Unknown command " << cmd << std::endl;
643int main(
int argc,
char* argv[])
649 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 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"