12#include <boost/program_options.hpp>
19#include <fairlogger/Logger.h>
25#include <unordered_map>
81 runStart = soreor.first;
82 runEnd = soreor.second;
90 uint64_t runStart = -1;
92 uint64_t timestamp = -1;
101 std::cout <<
"** A GRP utility **\n\n";
102 std::cout <<
"Usage: " << argv[0] <<
" subcommand [sub-command-options]\n";
104 std::cout <<
"The following subcommands are available:\n";
105 std::cout <<
"\t createGRPs : Create baseline GRP objects/file\n";
106 std::cout <<
"\t anchorGRPs : Fetch GRP objects from CCDB based on run number\n";
107 std::cout <<
"\t print_GRPECS : print a GRPECS object/file\n";
108 std::cout <<
"\t print_GRPMAG : print a GRPMagField object/file\n";
109 std::cout <<
"\t print_GRPLHC : print a GRPLHCIF object/file\n";
110 std::cout <<
"\t setROMode : modify/set readoutMode in a GRPECS file\n";
112 std::cout <<
"Sub-command options can be seen with subcommand --help\n";
118void printGRP(std::string
const&
filename, std::string
const& objtype)
120 std::cout <<
"\nPrinting " << objtype <<
" from file " <<
filename <<
"\n\n";
126 std::cerr <<
"Error loading " << objtype <<
" objects from file " <<
filename <<
"\n";
133 printGRP<o2::parameters::GRPECSObject>(
filename,
"GRPECS");
138 printGRP<o2::parameters::GRPMagField>(
filename,
"GRPMAG");
143 printGRP<o2::parameters::GRPLHCIFData>(
filename,
"GRPLHCIF");
147 std::vector<std::string>
const& triggered,
bool clear =
false)
152 std::cout <<
"no filename given\n";
157 TFile flGRP(
filename.c_str(),
"update");
158 if (flGRP.IsZombie()) {
159 LOG(error) <<
"Failed to open GRPECS file " <<
filename <<
" in update mode ";
162 std::unique_ptr<GRPECSObject> grp(
static_cast<GRPECSObject*
>(flGRP.GetObjectChecked(grpName.c_str(), GRPECSObject::Class())));
167 if (grp->isDetReadOut(
id)) {
168 grp->remDetContinuousReadOut(
id);
174 for (
auto& detstr : continuous) {
177 if (grp->isDetReadOut(
id)) {
178 grp->addDetContinuousReadOut(
id);
179 LOG(info) <<
"Setting det " << detstr <<
" to continuous RO mode";
183 for (
auto& detstr : triggered) {
186 if (grp->isDetReadOut(
id)) {
187 grp->addDetTrigger(
id);
188 LOG(info) <<
"Setting det " << detstr <<
" to trigger CTP";
192 flGRP.WriteObjectAny(grp.get(), grp->Class(), grpName.c_str());
201 if (!std::filesystem::exists(
filename)) {
202 LOG(error) <<
"Input file " <<
filename <<
"does not exist\n";
206 std::string targetdir =
path + CCDBpath;
209 }
catch (std::exception e) {
210 LOGP(error,
"Could not create local snapshot cache directory {}, reason: {}", targetdir, e.what());
214 auto targetfile = std::filesystem::path(targetdir +
"/snapshot.root");
215 auto opts = std::filesystem::copy_options::overwrite_existing;
216 std::filesystem::copy_file(
filename, targetfile, opts);
217 if (std::filesystem::exists(targetfile)) {
218 LOG(info) <<
"file " <<
filename <<
" copied/published to " << targetfile;
224bool anchor_GRPs(
Options const& opts, std::vector<std::string>
const&
paths = {
"GLO/Config/GRPECS",
"GLO/Config/GRPMagField",
"GLO/Config/GRPLHCIF"})
227 gCCDBWrapper = std::move(std::make_unique<CCDBHelper>(opts));
232 const bool preserve_path =
true;
233 const std::string
filename(
"snapshot.root");
234 std::map<std::string, std::string>
filter;
236 for (
auto& p :
paths) {
237 LOG(info) <<
"Fetching " <<
p <<
" from CCDB";
247 const char* CCDBPATH =
"/GLO/Calib/MeanVertex";
248 if (opts.
vertex ==
"ccdb") {
251 LOG(info) <<
"Creating MeanVertex object on the fly using the InteractionDiamond params";
253 const auto& xyz =
param.position;
254 const auto& sigma =
param.width;
258 std::map<std::string, std::string> meta;
259 meta[
"Created-by"] =
"Monte Carlo GRPTool";
261 gCCDBWrapper = std::move(std::make_unique<CCDBHelper>(opts));
267 std::filesystem::path directory_path = opts.
publishto + CCDBPATH;
269 std::filesystem::file_time_type latest_time = std::filesystem::file_time_type::min();
271 std::filesystem::path latest_file;
273 for (
const auto& file : std::filesystem::directory_iterator(directory_path)) {
275 if (file.is_regular_file()) {
277 std::filesystem::file_time_type mod_time = std::filesystem::last_write_time(file.path());
279 if (mod_time > latest_time) {
280 latest_time = mod_time;
281 latest_file = file.path();
285 auto oldpath = latest_file;
286 auto newpath = latest_file.parent_path();
287 newpath.append(std::string(
"snapshot.root"));
288 std::filesystem::rename(oldpath, newpath);
298 uint64_t runStart = -1;
302 LOG(info) <<
"---- creating MeanVertex ----";
308 LOG(info) <<
" --- creating GRP ECS -----";
313 auto soreor = ccdbmgr.getRunDuration(opts.
run);
314 runStart = soreor.first;
318 std::vector<std::string> modules{};
322 std::vector<std::string> readout{};
324 for (
auto& detstr : readout) {
333 grp.
setRunType(o2::parameters::GRPECSObject::RunType::PHYSICS);
336 TFile grpF(grpfilename.c_str(),
"recreate");
349 LOG(info) <<
" --- creating magfield GRP -----";
362 LOG(info) <<
"Downloading mag field directly from CCDB";
363 if (!
anchor_GRPs(opts, {
"GLO/Config/GRPMagField"})) {
364 LOG(fatal) <<
"Downloading mag field failed";
368 printGRPMAG(std::string(opts.
publishto) + std::string(
"/GLO/Config/GRPMagField/snapshot.root"));
376 const std::unordered_map<int, std::pair<int, int>> field_to_current = {{2, {12000, 6000}},
378 {-2, {-12000, -6000}},
379 {-5, {-30000, -6000}},
382 auto currents_iter = field_to_current.find(fieldvalue);
383 if (currents_iter == field_to_current.end()) {
384 LOG(error) <<
" Could not lookup currents for fieldvalue " << fieldvalue;
388 o2::units::Current_t currDip = (*currents_iter).second.second;
389 o2::units::Current_t currL3 = (*currents_iter).second.first;
397 TFile grpF(grpfilename.c_str(),
"recreate");
408 LOG(info) <<
" --- creating GRP LHCIF -----";
410 LOG(info) <<
"Downloading complete GRPLHCIF object directly from CCDB";
438 LOG(info) <<
"Initializing with default bunch filling";
448 TFile grpF(grpfilename.c_str(),
"recreate");
495 bpo::options_description global(
"Global options");
496 global.add_options()(
"command", bpo::value<std::string>(),
"command to execute")(
"subargs", bpo::value<std::vector<std::string>>(),
"Arguments for command");
497 global.add_options()(
"help,h",
"Produce help message.");
499 bpo::positional_options_description
pos;
500 pos.add(
"command", 1).add(
"subargs", -1);
502 bpo::variables_map vm;
503 bpo::parsed_options parsed{
nullptr};
505 parsed = bpo::command_line_parser(argc, argv).options(global).positional(
pos).allow_unregistered().run();
507 bpo::store(parsed, vm);
510 if (vm.count(
"help") > 0 && vm.count(
"command") == 0) {
514 }
catch (
const bpo::error& e) {
515 std::cerr << e.what() <<
"\n\n";
516 std::cerr <<
"Error parsing global options; Available options:\n";
517 std::cerr << global << std::endl;
521 auto subparse = [&parsed](
auto& desc,
auto& vm, std::string
const& command_name) {
525 std::vector<std::string> opts = bpo::collect_unrecognized(parsed.options, bpo::include_positional);
529 bpo::store(bpo::command_line_parser(opts).options(desc).run(), vm);
532 if (vm.count(
"help")) {
533 std::cout << desc << std::endl;
536 }
catch (
const bpo::error& e) {
537 std::cerr << e.what() <<
"\n\n";
538 std::cerr <<
"Error parsing options for " << command_name <<
" Available options:\n";
539 std::cerr << desc << std::endl;
545 std::string cmd = vm[
"command"].as<std::string>();
547 if (cmd ==
"anchorGRPs") {
550 bpo::options_description desc(
"anchor GRP options");
553 desc.add_options()(
"run", bpo::value<int>(&optvalues.
run)->default_value(-1),
"Run number");
554 desc.add_options()(
"print",
"print resulting GRPs");
555 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.");
556 if (!subparse(desc, vm,
"anchorGRPs")) {
559 if (vm.count(
"print") > 0) {
560 optvalues.
print =
true;
562 }
else if (cmd ==
"createGRPs") {
566 bpo::options_description desc(
"create options");
567 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");
568 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");
569 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)");
570 desc.add_options()(
"run", bpo::value<int>(&optvalues.
run)->default_value(-1),
"Run number");
571 desc.add_options()(
"hbfpertf", bpo::value<int>(&optvalues.
orbitsPerTF)->default_value(128),
"heart beat frames per timeframe (timeframelength)");
572 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");
573 desc.add_options()(
"outprefix,o", bpo::value<std::string>(&optvalues.
outprefix)->default_value(
"o2sim"),
"Prefix for GRP output files");
574 desc.add_options()(
"bcPatternFile", bpo::value<std::string>(&optvalues.
bcPatternFile)->default_value(
""),
"Interacting BC pattern file (e.g. from CreateBCPattern.C)");
575 desc.add_options()(
"lhcif-CCDB",
"take GRPLHCIF directly from CCDB");
576 desc.add_options()(
"print",
"print resulting GRPs");
577 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.");
578 desc.add_options()(
"isRun5", bpo::bool_switch(&optvalues.
isRun5),
"Whether or not to expect a Run5 detector configuration. (deprecated, use detectorList option)");
579 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");
580 desc.add_options()(
"timestamp", bpo::value<uint64_t>(&optvalues.
timestamp)->default_value(0),
"Force timestamp to be used (useful when anchoring)");
581 desc.add_options()(
"configKeyValues", bpo::value<std::string>(&optvalues.
configKeyValues)->default_value(
""),
"Semicolon separated key=value strings (e.g.: 'TPC.gasDensity=1;...')");
582 if (!subparse(desc, vm,
"createGRPs")) {
585 if (vm.count(
"print") > 0) {
586 optvalues.
print =
true;
588 if (vm.count(
"lhcif-CCDB") > 0) {
591 auto vertexmode = vm[
"vertex"].as<std::string>();
592 if (!(vertexmode ==
"ccdb" || vertexmode ==
"Diamond")) {
598 }
else if (cmd ==
"setROMode") {
601 bpo::options_description desc(
"setting detector readout modes");
602 desc.add_options()(
"file,f", bpo::value<std::string>(&optvalues.
grpfilename)->default_value(
"o2sim_grpecs.root"),
"Path to GRPECS file");
603 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");
604 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");
605 desc.add_options()(
"clear",
"clears all RO modes (prio to applying other options)");
606 if (!subparse(desc, vm,
"setROMode")) {
609 if (vm.count(
"clear") > 0) {
612 }
else if (cmd ==
"print_GRPECS") {
615 bpo::options_description desc(
"print options");
616 desc.add_options()(
"file,f", bpo::value<std::string>(&optvalues.
grpfilename),
"Path to GRP file");
617 if (!subparse(desc, vm,
"print_GRPECS")) {
620 }
else if (cmd ==
"print_GRPLHC") {
623 bpo::options_description desc(
"print options");
624 desc.add_options()(
"file,f", bpo::value<std::string>(&optvalues.
grpfilename),
"Path to GRP file");
625 if (!subparse(desc, vm,
"print_GRPECS")) {
628 }
else if (cmd ==
"print_GRPMAG") {
631 bpo::options_description desc(
"print options");
632 desc.add_options()(
"file,f", bpo::value<std::string>(&optvalues.
grpfilename),
"Path to GRP file");
633 if (!subparse(desc, vm,
"print_GRPECS")) {
637 std::cerr <<
"Error: Unknown command " << cmd << std::endl;
644int main(
int argc,
char* argv[])
650 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 getCCDBServer()
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 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"