ATLAS Offline Software
Config.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
12 #include "TrigPSC/Config.h"
13 #include "TrigPSC/PscIssues.h"
14 #include "GaudiKernel/IMessageSvc.h"
15 #include "eformat/SourceIdentifier.h"
16 #include <boost/algorithm/string.hpp>
17 #include <boost/optional.hpp>
18 #include <array>
19 #include <climits>
20 #include <iomanip>
21 #include <set>
22 #include <sstream>
23 #include <unistd.h>
24 
25 using std::string;
26 using std::array;
27 using std::ostringstream;
28 using namespace boost::property_tree;
29 
30 namespace
31 {
33  const string cf_path = "Configuration.Partition.TriggerConfiguration"
34  ".TriggerConfiguration";
35  const string hlt_path = cf_path + ".hlt";
36  const string db_path = cf_path+".TriggerDBConnection.TriggerDBConnection";
37  const string l1_path = cf_path + ".L1TriggerConfiguration"
38  ".L1TriggerConfiguration";
39  const string r2r_path = "Configuration.ROS2ROBS";
40  const string athlt_path = cf_path+".athenaHLTSpecificConfiguration";
41 
43  const ptree::value_type& getHltConfigImpl(const ptree& config)
44  {
45  const ptree& hltconf = config.get_child(hlt_path);
46  if(hltconf.size() != 1)
47  {
48  ostringstream oss;
49  oss << "Got " << hltconf.size() << " elements of HLTImplementation in the"
50  " TriggerConfiguration, when exactly 1 element was expected";
51  throw psc::ConfigurationIssue(ERS_HERE, oss.str().c_str());
52  }
53 
54  return hltconf.front();
55  }
56 
58  string plevelToStr(const ptree& level, const char delim = ';')
59  {
60  string ret;
61  for(const auto& item : level)
62  {
63  if(!ret.empty() && ret.back() != delim) {
64  ret += delim;
65  }
66  ret += item.second.data();
67  }
68 
69  return ret;
70  }
71 
73  string plevelToStr(const boost::optional<const ptree&>& level,
74  const char delim = ';')
75  {
76  return level ? plevelToStr(*level, delim) : "";
77  }
78 
80  string log_level_as_num_str(const std::string& loglevel)
81  {
82  constexpr auto size = 7ul;
83  constexpr array<const char*, size> lvl_keys = {{"VERBOSE",
84  "DEBUG",
85  "INFO",
86  "WARNING",
87  "ERROR",
88  "FATAL",
89  "ALWAYS"}};
90  constexpr array<int, size> lvl_values = {{MSG::VERBOSE,
91  MSG::DEBUG,
92  MSG::INFO,
93  MSG::WARNING,
94  MSG::ERROR,
95  MSG::FATAL,
96  MSG::ALWAYS}};
97  for(auto i = 0u; i < size; ++i)
98  if(loglevel.find(lvl_keys[i]) != string::npos) // key is a substr of level
99  return std::to_string(lvl_values[i]); // the first level that is found
100  // is the most verbose one
101 
102  return "0";
103  }
104 }
105 
108  : m_config(config)
109 {
111 
112  fill_enabled_robs(config.get_child(r2r_path));
113  fill_enabled_dets(config.get_child(r2r_path));
114 
115  const ptree::value_type& hltimpl = getHltConfigImpl(config);
116  if(hltimpl.first == "HLTImplementationJobOptions")
117  {
118  ERS_DEBUG(1, "Job Options configuration");
119  fillopt_jo(hltimpl.second);
120  }
121  else if(hltimpl.first == "HLTImplementationDB")
122  {
123  ERS_DEBUG(1, "DB configuration");
124  fillopt_db(hltimpl.second);
125  }
126  else if(hltimpl.first == "HLTImplementationDBPython")
127  {
128  ERS_DEBUG(1, "DBPY configuration");
129  ERS_PSC_WARNING("HLT configured with HLTImplementationDBPython object. This"
130  " is for offline purposes only. Do not use this for online running!");
131  fillopt_dbpy(hltimpl.second);
132  }
133  else
134  {
135  string msg = "Unknown HLTImplementation type: " + hltimpl.first;
136  throw psc::ConfigurationIssue(ERS_HERE, msg.c_str());
137  }
138 
140  setPInfo();
141 }
142 
145 {
146  updatePids();
147  updateSeed();
148 
149  optmap["DF_APPLICATIONNAME"] = args.get_child("appName").data();
150  optmap["DF_WORKER_ID"] = args.get_child("workerId").data();
151  optmap["DF_NUMBER_OF_WORKERS"] = args.get_child("numberOfWorkers").data();
152 }
153 
155 std::string psc::Config::dumpOptions() const
156 {
157  std::ostringstream ost;
158  ost << " --- Dump of all options held by Config --- total size = " << optmap.size() <<"\n";
159  unsigned pos = 0;
160  for(std::map<std::string, std::string>::const_iterator
161  it = optmap.begin(); it != optmap.end(); ++it, ++pos) {
162  ost << " # = " << std::setw(3) << pos
163  << " Option : " << "'" << it->first
164  << "' = '" << it->second << "'\n";
165  }
166 
167  // Print all enabled ROB ids
168  ost << " --- Number of enabled ROB IDs read from OKS = " << enabled_robs.size() << "\n";
169  ost << "List of enabled ROBs: [";
170  bool first = true;
171  int index(0);
172  eformat::SubDetector previous_subDet(eformat::OTHER);
173  for(auto rob : enabled_robs)
174  {
175  if(!first) ost << ", ";
176  if (eformat::helper::SourceIdentifier(rob).subdetector_id() != previous_subDet) {
177  previous_subDet = eformat::helper::SourceIdentifier(rob).subdetector_id();
178  index=0;
179  }
180  if(index%10==0) ost<<"\n" ;
181  ost << " 0x" << std::setw(6) << std::hex << rob << std::dec;
182  first = false;
183  ++index;
184  }
185  ost << "]\n";
186 
187  // Print all enabled Subdetectors ids
188  ost << " --- Number of enabled Sub Detector configured = "
189  << enabled_SubDets.size() << "\n";
190  ost << "List of enabled Sub-Detectors: [\n";
191  first = true;
192  index = 0;
193  for(auto det : enabled_SubDets)
194  {
195  if(!first)
196  ost << ",\n";
197  ++index;
198  ost << std::setw(4) << index << ": 0x" << std::setw(2) << std::hex << det << std::dec
199  << " (" << std::setw(26) << eformat::helper::SourceIdentifier((eformat::SubDetector)det,0).human_detector() << " )";
200  first = false;
201  }
202  ost << "]";
203 
204  return ost.str();
205 }
206 
208 std::string psc::Config::getOption(const std::string& key, bool quiet) const
209 {
210  std::map<std::string, std::string>::const_iterator it = optmap.find(key);
211  if (it == optmap.end()) {
212  if (!quiet) {
213  ERS_PSC_WARNING("Could not find requested option = " << key);
214  ERS_DEBUG(1, " " << dumpOptions() );
215  }
216  return "";
217  }
218  return it->second;
219 }
220 
222 std::string psc::Config::toPython(const std::string& dictName) const
223 {
224  ostringstream oss;
225  oss << dictName << " = {";
226  bool first(true);
227  std::map<std::string, std::string>::const_iterator it = optmap.begin();
228  for(;it != optmap.end(); ++it) {
229  if (!first) {
230  oss << ",";
231  }
232  oss << "'" << it->first << "':'" << it->second << "'";
233  first = false;
234  }
235  oss << "}" << std::endl;
236  return oss.str();
237 }
238 
241 {
242  return log_level_as_num_str(getOption("LOGLEVEL"));
243 }
244 
246 {
247  // Ugly since it relies on the default value being "INFO"
248  // (and wrong if the user uses explicitlty requests "INFO")
249  return getOption("LOGLEVEL").substr(0,4) != "INFO";
250 }
251 
254 {
255  optmap["LOGLEVEL"] = "INFO";
256  optmap["PRECOMMAND"] = "";
257  optmap["POSTCOMMAND"] = "";
258  optmap["MUONCALBUFFERNAME"] = "";
259  optmap["MUONCALBUFFERSIZE"] = "";
260 }
261 
264 {
265  optmap["JOBOPTIONSPATH"] = hlt.get_child("jobOptionsPath").data();
266  optmap["PYTHONSETUPFILE"] = hlt.get_child("pythonSetupFile").data();
267 
268  // Special case for running directly from JSON file
269  if (boost::algorithm::to_lower_copy(optmap["JOBOPTIONSPATH"]).ends_with(".json")) {
270  optmap["JOBOPTIONSTYPE"] = "FILE";
271  }
272  else {
273  optmap["JOBOPTIONSTYPE"] = "NONE";
274  }
275  optmap["LOGLEVEL"] = plevelToStr(hlt.get_child_optional("logLevels"),',');
276 
277  fillopt_py(hlt);
278  fillopt_common(hlt);
279 }
280 
283 {
284  const auto& db = m_config.get_child(db_path);
285  std::ostringstream s;
286  s << "server=" << db.get_child("Alias").data()
287  << ";smkey=" << db.get_child("SuperMasterKey").data()
288  << ";lvl1key=" << m_config.get_child(l1_path + ".Lvl1PrescaleKey").data()
289  << ";hltkey=" << hlt.get_child("hltPrescaleKey").data();
290 
291  optmap["JOBOPTIONSPATH"] = s.str();
292  optmap["JOBOPTIONSTYPE"] = "DB";
293 
294  fillopt_common(hlt);
295 }
296 
299 {
300  fillopt_db(hlt);
301  fillopt_py(hlt);
302 }
303 
306 {
307  optmap["PRECOMMAND"] = plevelToStr(hlt.get_child_optional("preCommands"));
308  optmap["POSTCOMMAND"] = plevelToStr(hlt.get_child_optional("postCommands"));
309 }
310 
313 {
314  boost::optional<const ptree&> circbuf = m_config.get_child_optional(
315  "Configuration.HLTMPPUApplication.MuonCalibrationConfig.CircBuffer");
316  if(circbuf)
317  {
318  optmap["MUONCALBUFFERNAME"] = circbuf->get_child("CircName").data();
319  optmap["MUONCALBUFFERSIZE"] = circbuf->get_child("CircSize").data();
320  }
321 
322  const ptree& com = hlt.get_child("HLTCommonParameters.HLTCommonParameters");
323  optmap["MESSAGESVCTYPE"] = com.get_child("messageSvcType").data();
324  optmap["JOBOPTIONSSVCTYPE"] = com.get_child("jobOptionsSvcType").data();
325 
326  optmap["DF_PARTITION_NAME"] = m_config.get_child("Configuration.Partition.UID").data();
327 
328  const ptree& hltmppu = m_config.get_child("Configuration.HLTMPPUApplication");
329  optmap["DF_APPLICATIONNAME"] = hltmppu.get_child("UID").data();
330  optmap["HARDTIMEOUT"] = hltmppu.get_child("HardTimeout").data();
331  optmap["SOFTTIMEOUTFRACTION"] = hltmppu.get_child("softTimeoutFraction").data();
332  optmap["NEVENTSLOTS"] = hltmppu.get_child("numberOfEventSlots").data();
333  optmap["NTHREADS"] = hltmppu.get_child("numberOfAthenaMTThreads").data();
334  optmap["NPROCS"] = hltmppu.get_child("numForks").data();
335  optmap["MAXEVENTSIZEMB"] = hltmppu.get_child("maximumHltResultMb").data();
336 }
337 
340 {
341  const auto& ath_hlt = m_config.get_child_optional(athlt_path);
342  if(ath_hlt)
343  {
344  const auto& llnode = ath_hlt->get_child_optional("logLevels");
345  optmap["LOGLEVEL"] = plevelToStr(llnode, ',');
346 
347  const auto& psnode = ath_hlt->get_child_optional("pythonSetupFile");
348  if(psnode)
349  optmap["PYTHONSETUPFILE"] = psnode->data();
350  }
351 }
352 
355 {
356  char cstr_host[HOST_NAME_MAX];
357  gethostname(cstr_host, sizeof(cstr_host));
358  optmap["DF_MACHINE_NAME"] = string(cstr_host);
359 
360  ostringstream oss;
361  oss << "0x" << std::hex << gethostid() ;
362  optmap["DF_HOST_ID"] = oss.str();
363 
364  updatePids();
365  updateSeed();
366 }
367 
370 {
371  std::set<uint32_t> set_enabled_robs;
372  for(const auto& ros : r2r)
373  for(const auto& rob: ros.second)
374  set_enabled_robs.insert(rob.second.get_value<uint32_t>());
375 
376  enabled_robs.reserve(set_enabled_robs.size());
377  for(const auto& it_rob: set_enabled_robs) enabled_robs.push_back(it_rob);
378 }
379 
382 {
383  std::set<eformat::SubDetector> set_enabled_subDets;
384  for(const auto& ros : r2r)
385  for(const auto& rob: ros.second)
386  set_enabled_subDets.insert(eformat::helper::SourceIdentifier(rob.second.get_value<uint32_t>()).subdetector_id());
387 
388  enabled_SubDets.reserve(set_enabled_subDets.size());
389  for(const auto& it_det: set_enabled_subDets) enabled_SubDets.push_back(it_det);
390 }
391 
394 {
395  optmap["DF_PID"] = std::to_string(getpid());
396  optmap["DF_PPID"] = std::to_string(getppid());
397 }
398 
401 {
402  // this is a string representing a number, in hexadecimal format, that fits
403  // in an int. The leftmost sizeof(int)/2 bytes of this number are the
404  // rightmost sizeof(int)/2 bytes of the host id of this machine. The rightmost
405  // sizeof(int)/2 bytes of this number are the rightmost sizeof(int)/2 bytes of
406  // this process's id.
407  //
408  // e.g. if we are running in a machine where sizeof(int) is 4, the machine's
409  // host id is 0xffffffff12344321 and this process's id is 0xabcddcba,
410  // the random seed becomes 0x4321dcba
411 
412  unsigned int extract_mask = 0;
413  for(unsigned i = 0; i < sizeof(int)/2; ++i)
414  extract_mask |= UCHAR_MAX << (i*CHAR_BIT);
415 
416  ostringstream oss;
417 
418  oss << "0x" << std::hex << (gethostid() & extract_mask)
419  << (getpid() & extract_mask);
420 
421  optmap["DF_RANDOM_SEED"] = oss.str();
422 }
psc::Config::getOption
std::string getOption(const std::string &key, bool quiet=false) const
Gets an option in a "safer" way.
Definition: Config.cxx:208
PscIssues.h
ERS Issues for PSC.
psc::Config::fillopt_db
void fillopt_db(const boost::property_tree::ptree &hlt)
Definition: Config.cxx:282
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
python.trigbs_prescaleL1.ost
ost
Definition: trigbs_prescaleL1.py:104
python.Constants.FATAL
int FATAL
Definition: Control/AthenaCommon/python/Constants.py:19
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
CxxUtils::ends_with
bool ends_with(const char *s, const char *suffix)
Test whether one null-terminated byte string ends with another.
quiet
bool quiet
Definition: TrigGlobEffCorrValidation.cxx:190
index
Definition: index.py:1
CaloCondBlobAlgs_fillNoiseFromASCII.db
db
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:43
psc::Config::updatePids
void updatePids()
Definition: Config.cxx:393
psc::Config::toPython
std::string toPython(const std::string &dictName) const
Incredibly simple minded way to access this object from python.
Definition: Config.cxx:222
skel.it
it
Definition: skel.GENtoEVGEN.py:423
psc::Config::fill_enabled_dets
void fill_enabled_dets(const boost::property_tree::ptree &ros2robs)
Definition: Config.cxx:381
ERS_PSC_WARNING
#define ERS_PSC_WARNING(message)
Definition: PscIssues.h:46
psc::Config::didUserSetLogLevel
bool didUserSetLogLevel() const
Returns whether the user specified an explicit log level.
Definition: Config.cxx:245
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:83
config
Definition: PhysicsAnalysis/AnalysisCommon/AssociationUtils/python/config.py:1
python.iconfTool.models.loaders.level
level
Definition: loaders.py:20
psc::Config::fill_enabled_robs
void fill_enabled_robs(const boost::property_tree::ptree &ros2robs)
Definition: Config.cxx:369
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
psc::Config::setup_optmap_defaults
void setup_optmap_defaults()
Definition: Config.cxx:253
TrigConf::MSGTC::ALWAYS
@ ALWAYS
Definition: Trigger/TrigConfiguration/TrigConfBase/TrigConfBase/MsgStream.h:29
lumiFormat.i
int i
Definition: lumiFormat.py:92
ret
T ret(T t)
Definition: rootspy.cxx:260
psc::Config::setPInfo
void setPInfo()
Definition: Config.cxx:354
psc::Config::fillopt_dbpy
void fillopt_dbpy(const boost::property_tree::ptree &hlt)
Definition: Config.cxx:298
WritePulseShapeToCool.det
det
Definition: WritePulseShapeToCool.py:204
psc::Config::prepareWorker
void prepareWorker(const boost::property_tree::ptree &args)
Definition: Config.cxx:144
psc::Config::Config
Config(const boost::property_tree::ptree &config)
Definition: Config.cxx:107
psc::Config::fillopt_athenaHLT
void fillopt_athenaHLT()
Definition: Config.cxx:339
maskDeadModules.ros
ros
Definition: maskDeadModules.py:35
lumiFormat.array
array
Definition: lumiFormat.py:98
ptree
boost::property_tree::ptree ptree
Definition: JsonFileLoader.cxx:16
psc::Config::fillopt_py
void fillopt_py(const boost::property_tree::ptree &hlt)
Definition: Config.cxx:305
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
Config.h
PSC Configuration type.
item
Definition: ItemListSvc.h:43
psc::Config::fillopt_common
void fillopt_common(const boost::property_tree::ptree &hlt)
Definition: Config.cxx:312
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
ConfigurationIssue
ConfigurationIssue
Definition: PscIssues.h:29
DeMoScan.index
string index
Definition: DeMoScan.py:362
psc::Config::dumpOptions
std::string dumpOptions() const
Returns a string with all options which are held in the options cache.
Definition: Config.cxx:155
LArG4ShowerLibProcessing.loglevel
loglevel
Definition: LArG4ShowerLibProcessing.py:39
DeMoScan.first
bool first
Definition: DeMoScan.py:534
DEBUG
#define DEBUG
Definition: page_access.h:11
python.PscConfig.optmap
dictionary optmap
string:string map equivalent to TrigPsc/Config.h (filled in TrigPsc.cxx)
Definition: PscConfig.py:20
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:14
python.trigTranslate.getOption
def getOption(runArgs, name, substep, first, output)
Definition: trigTranslate.py:19
psc::Config::updateSeed
void updateSeed()
Definition: Config.cxx:400
psc::Config::getLogLevelAsNumStr
std::string getLogLevelAsNumStr() const
Get a string representing the actual number value of the first LOGLEVEL in this configuration.
Definition: Config.cxx:240
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
python.CaloScaleNoiseConfig.args
args
Definition: CaloScaleNoiseConfig.py:80
psc::Config::fillopt_jo
void fillopt_jo(const boost::property_tree::ptree &hlt)
Definition: Config.cxx:263
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37