ATLAS Offline Software
CDIReader.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // CDIReader.h, (c) ATLAS Detector software
8 
10 
11 #include <nlohmann/json.hpp>
12 
14 
15 Analysis::CDIReader::CDIReader(const std::string& cdipath, bool verbose) : m_use_json(false), m_cdipath(cdipath), m_CDIFile(TFile::Open(m_cdipath.c_str(), "READ"))
16 {
17  TObjString* s;
18  m_CDIFile->GetObject("VersionInfo/BuildNumber", s);
19  if (s && verbose){
20  std::cout << " CDI file build number: " << s->GetName() << std::endl;
21  }
22  TList* taggerkeys = m_CDIFile->GetListOfKeys();
23  for (const auto tagger : *taggerkeys){
24  const char* taggername = tagger->GetName();
25  if(strcmp(taggername, "VersionInfo") != 0){
26  // now we have the top-level tagger name, we want to add this to our overall meta data
27  TDirectoryFile* taggerDir = (TDirectoryFile*)m_CDIFile->Get(taggername);
28  record_metadata(taggername, 0);
29  crawlCDI(taggerDir, 0, taggername);
30  }
31  }
32 }
33 
34 
35 void Analysis::CDIReader::crawlCDI(TDirectoryFile* parentDir, int depth, const std::string& metamap){
36  TList* keys = parentDir->GetListOfKeys(); // get directories
37  if(isWPdirectory(keys)){
38  // now that we are at the level of the individual label directories
39  // interact with them, and extract the data they store
40 
41  TList* labelkeys = parentDir->GetListOfKeys();
42  Data theseData; // labels, systematics, DSIDS, etc.
43  Labels theseLabels;
44  std::set<std::string> DSID_set; // record all DSID names in the flavour configuration
45  std::set<std::string> systematics_set; // record all uncertainties met in flavour configuration
46 
47  Labels path = split(metamap);
48  std::string taggername = path.at(0);
49  std::string jetcollname = path.at(1);
50  std::string workingpointname = path.at(2);
51 
52  // For each "label" stored in the working point directory,
53  // we need to access the contents of the label directory
54  // and construct the metadata map
55  for(const auto label : *labelkeys){
56  std::string labelname = label->GetName();
57  if(labelname == "cutvalue" || labelname.find("fraction") != std::string::npos) continue;
58  m_labels.insert(labelname);
59  theseLabels.push_back(labelname);
60 
61  // now enter the directory to access uncertainty info for this flavour
62  TDirectoryFile* flavourDir = (TDirectoryFile*)parentDir->Get(labelname.c_str());
63  if(flavourDir){
64  Labels uncertainties; // flavour specific uncertainties
65  TList* DSIDkeys = flavourDir->GetListOfKeys(); // this is the list of all the items in the flavour (DSID etc)
66  for(const auto CDHistCont : *DSIDkeys){
67  std::string DSIDname = CDHistCont->GetName();
68  DSID_set.insert(DSIDname);
69  m_DSIDs.insert(DSIDname);
70  if(DSIDname == "default_SF"){ // let's access the systematic uncertainties
71  // construct the total path
72  std::string dir = taggername + "/" + jetcollname + "/" + workingpointname + "/" + labelname + "/default_SF";
74  m_CDIFile->GetObject(dir.c_str(), cont);
75  if(!cont){
76  std::cout << "No default_SF CalibrationDataHistogramContainer?" << std::endl;
77  } else {
78  uncertainties = cont->listUncertainties();
79  for(std::string s : uncertainties){
80  systematics_set.insert(s);
81  }
82  }
83  // add the flavour specific uncertainties here
84  std::string flav_spec_unc_name = labelname + "_syst";
85  theseData[flav_spec_unc_name] = uncertainties;
86  }
87  }
88  } else {
89  std::cout << "No flavour directory?" << std::endl;
90  }
91  }
92  // sort and add the labels to the Data object
93  std::sort(theseLabels.begin(), theseLabels.end());
94  theseData["labels"] = theseLabels;
95  // convert DSID set to vector of strings
96  Labels theseDSIDs(DSID_set.size());
97  std::copy(DSID_set.begin(), DSID_set.end(), theseDSIDs.begin());
98  theseData["DSIDs"] = theseDSIDs;
99  // convert systematic set to vector of strings
100  Labels theseSystematics(systematics_set.size());
101  std::copy(systematics_set.begin(), systematics_set.end(), theseSystematics.begin());
102  theseData["systematics"] = theseSystematics;
103  // Construct this branch of the metadata map
104  // and record the Data object
105  record_metadata_map(theseData, metamap);
106  } else {
107  for(const auto coll: *keys){
108  std::string collname = coll->GetName();
109  // track the metadata as you traverse
110  record_metadata(collname, depth+1);
111  TDirectoryFile* collDir = (TDirectoryFile*)parentDir->Get(collname.c_str());
112  if(collDir && collname != "VersionInfo"){
113  std::string nextmap = metamap + ";" + collname;
114  crawlCDI(collDir, depth+1, nextmap); // traverse further
115  } else {
116  std::cout << "No collection directory?" << std::endl;
117  }
118  }
119  }
120 }
121 
122 
123 
124 
125 void Analysis::CDIReader::printMetadata(int tagger, int jetcoll, int wpoint, int label){
126  /*
127  This method prints subsets of the available metadata collected from the CDI file.
128 
129  The CDI data is organized in a hierarchical directory structure, where taggers contain jet-collections, and jet-collections
130  contain working points, etc.
131 
132  This method prints wildcard data such as:
133  - tagger / *
134  - tagger / jetcoll/ *
135  - tagger / jetcoll/ wpoint / *
136  - tagger / jetcoll / wpoint / label
137 
138  The method operates on simple integer inputs, to indicate what to print out:
139  - Positive integer values for tagger, jetcoll, wpoint, and label (up to the number of available items of each)
140  will print out information specific to that particular entry (e.g. tagger == 1 will print tagger #1 specific info)
141  - Negative integer values indicate a wildcard, and will print out all available items of this type.
142  - Zero indicates to print nothing for that category.
143  */
144  int current_tagger = (tagger < 0) ? -1 : 0;
145  int current_jetcoll = (jetcoll < 0) ? -1 : 0;
146  int current_wpoint = (wpoint < 0) ? -1 : 0;
147  int current_label = (label < 0) ? -1 : 0;
148 
149  for (const auto& [tag, jets] : m_metadata){
150  if(current_tagger != -1) current_tagger += 1;
151  if(tagger != current_tagger || tagger == 0) continue;
152 
153  std::cout << "| " << tag << std::endl; // print only the tagger you're interested in
154 
155  for (const auto& [jet, wps] : jets){
156  if(current_jetcoll != -1) current_jetcoll += 1;
157  if(jetcoll != current_jetcoll || jetcoll == 0) continue;
158 
159  std::cout << "|\\__ " << jet << std::endl;
160 
161  int num_wps = wps.size();
162  int num_wp_seen = 0;
163  for(const auto& [wp, labels] : wps){
164  if(current_wpoint != -1) current_wpoint += 1;
165  if(wpoint != current_wpoint || wpoint == 0) continue;
166  num_wp_seen += 1;
167  if(num_wp_seen != num_wps){
168  std::cout << "| |\\__" << wp << std::endl;
169  } else {
170  std::cout << "| \\__" << wp << std::endl;
171  }
172 
173  int label_index = 0;
174  Data d = labels;
175  for(const std::string& l : d["labels"]){
176  if(current_label != -1) current_label += 1;
177  if(label != current_label || label == 0) continue;
178  if(num_wp_seen != num_wps && label_index == 0){
179  std::cout << "| | \\___" << " (" << label_index << ") " << l << std::endl;
180  } else if(label_index != 0 && num_wp_seen != num_wps) {
181  std::cout << "| | \\___" << " (" << label_index << ") " << l << std::endl;
182  } else {
183  std::cout << "| \\___" << " (" << label_index << ") " << l << std::endl;
184  }
185  label_index += 1;
186  }
187  }
188  }
189  }
190 }
191 
192 bool Analysis::CDIReader::checkConfig(const std::string& tagger, const std::string& jetcoll, const std::string& wp, bool verbose){
193  // this method checks if your config is correct or not
194  // returns true if correct, false if not
195  // if not correct, it will also print a helpful message
196  bool configured = false;
197  // get the number that would correspond to the index of the tagger/jetcoll/wp
198  // if these were each stored in a vector of strings, sorted alphanumerically
199  // which happens already by default in the (ordered) map
200  int tagger_ind = 0;
201  int jetcoll_ind = 0;
202  int wp_ind = 0;
203 
204  if(m_metadata.count(tagger) > 0){
205  // get the tagger index
206  for(const auto& tag : m_metadata){
207  tagger_ind += 1;
208  if(tag.first == tagger) break;
209  }
210  if(m_metadata[tagger].count(jetcoll) > 0){
211  // get the jet collection index
212  for(const auto& jet : m_metadata[tagger]){
213  jetcoll_ind += 1;
214  if(jet.first == jetcoll) break;
215  }
216  if(m_metadata[tagger][jetcoll].count(wp) > 0){
217  // get the working point index
218  for(const auto& wpoint : m_metadata[tagger][jetcoll]){
219  wp_ind += 1;
220  if(wpoint.first == wp) break;
221  }
222  if (verbose) std::cout << " Your configuration looks good! Available labels are : " << std::endl;
223  if (verbose) printMetadata(tagger_ind, jetcoll_ind, wp_ind, -1);
224  // construct vector of labels
225  for(std::string flavour_label : m_metadata[tagger][jetcoll][wp]["labels"]){
226  m_label_vec.push_back(flavour_label);
227  }
228  // sort the vector of labels
229  std::sort(m_label_vec.begin(), m_label_vec.end());
230  configured = true;
231  } else {
232  if (verbose) std::cout << "Couldn't find \"" << wp << "\" for " << tagger << " / " << jetcoll << " in this CDI file!" << std::endl;
233  if (verbose) std::cout << "Here are your options :" << std::endl;
234  if (verbose) printMetadata(tagger_ind, jetcoll_ind, -1, 0);
235  }
236  } else {
237  if (verbose) std::cout << "Couldn't find \"" << jetcoll << "\" under " << tagger << " in this CDI file!" << std::endl;
238  if (verbose) std::cout << "Here are your options :" << std::endl;
239  if (verbose) printMetadata(tagger_ind, -1, 0, 0);
240  }
241  } else {
242  if (verbose) std::cout << "Couldn't find \"" << tagger << "\" in this CDI file" << std::endl;
243  if (verbose) std::cout << "Here are your options :" << std::endl;
244  if (verbose) printMetadata(-1,0,0,0);
245  }
246 
247  if(m_use_json){
248  // let's make a json object from the nlohmann package and save it to file
249  json json_metadata(m_metadata);
250  // get cwd to save in
251  std::filesystem::path cwd = std::filesystem::current_path();
252  std::filesystem::path filepath = cwd / "CDI.json";
253  std::ofstream output(filepath);
254  output << std::setw(4) << json_metadata << std::endl;
255  }
256 
257  m_initialized = configured;
258  return configured;
259 }
260 
261 
262 std::vector<std::string> Analysis::CDIReader::getDSIDs(const std::string& tagger, const std::string& jetcollection, const std::string& workingpoint){
263  if(!m_initialized){
264  std::cout << " CDIReader :: You need to validate your configuration before working with (flavour) labels!" << std::endl;
265  }
266  Labels DSIDs;
267  if (tagger.empty() || jetcollection.empty() || workingpoint.empty()){
268  // unless specified, return the vector of all known DSIDs from this CDI file
269  Labels DSID_vec(m_DSIDs.size());
270  std::copy(m_DSIDs.begin(), m_DSIDs.end(), DSID_vec.begin());
271  DSIDs = DSID_vec;
272  //} else if(std::find(m_taggers.begin(), m_taggers.end(), tagger) == m_taggers.end()){
273  } else if(m_taggers.find(tagger) == m_taggers.end()){
274  std::cout << " The tagger [" << tagger << "] doesn't exist in this CDI file!" << std::endl;
275  //} else if(std::find(m_jetcollections.begin(), m_jetcollections.end(), jetcollection) == m_jetcollections.end()){
276  } else if(m_jetcollections.find(jetcollection) == m_jetcollections.end()){
277  std::cout << " The jet collection [" << jetcollection << "] doesn't exist in " << tagger << " this CDI file!" << std::endl;
278  //} else if(std::find(m_workingpoints.begin(), m_workingpoints.end(), workingpoint) == m_workingpoints.end()){
279  } else if(m_workingpoints.find(workingpoint) == m_workingpoints.end()){
280  std::cout << " The working point [" << workingpoint << "] doesn't exist in " << tagger << "/" << jetcollection << " this CDI file!" << std::endl;
281  } else {
282  for (const std::string& DSID : m_metadata[tagger][jetcollection][workingpoint]["DSIDs"]){
283  DSIDs.push_back(DSID);
284  }
285  }
286  return DSIDs;
287 }
288 
289 std::vector<std::string> Analysis::CDIReader::getLabels(const std::string& tagger, const std::string& jetcollection, const std::string& workingpoint){
290  if(!m_initialized){
291  std::cout << " CDIReader :: You need to validate your configuration before working with (flavour) labels!" << std::endl;
292  }
293  Labels labels;
294  if (tagger.empty() || jetcollection.empty() || workingpoint.empty()){
295  // unless specified, return the vector of all flavour labels
296  labels = m_label_vec;
297  } else if(m_taggers.find(tagger) == m_taggers.end()){
298  std::cout << " The tagger [" << tagger << "] doesn't exist in this CDI file!" << std::endl;
299  } else if(m_jetcollections.find(jetcollection) == m_jetcollections.end()){
300  std::cout << " The jet collection [" << jetcollection << "] doesn't exist in " << tagger << " this CDI file!" << std::endl;
301  } else if(m_workingpoints.find(workingpoint) == m_workingpoints.end()){
302  std::cout << " The working point [" << workingpoint << "] doesn't exist in " << tagger << "/" << jetcollection << " this CDI file!" << std::endl;
303  } else {
304  for (std::string label : m_metadata[tagger][jetcollection][workingpoint]["labels"]){
305  labels.push_back(label);
306  }
307  }
308  return labels;
309 }
310 
311 std::vector<std::string> Analysis::CDIReader::getJetCollections(const std::string& tagger){
312  Labels jetcolls;
313  if (tagger.empty()){
314  // unless specified, return the vector of all jet collections
315  jetcolls.assign(m_jetcollections.begin(), m_jetcollections.end());
316  } else if (m_taggers.find(tagger) == m_taggers.end()) {
317  std::cout << " The tagger [" << tagger << "] doesn't exist in this CDI file!" << std::endl;
318  } else {
319  // return the jetcollections of this tagger
320  for(const auto& jet : m_metadata[tagger]){
321  jetcolls.push_back(jet.first);
322  }
323  }
324  return jetcolls;
325 }
326 
327 
328 std::vector<std::string> Analysis::CDIReader::getWorkingPoints(const std::string& tagger, const std::string& jetcollection){
329  Labels wps;
330  if (tagger.empty() || jetcollection.empty()){
331  // unless specified, return the vector of all working points
332  wps.assign(m_workingpoints.begin(), m_workingpoints.end());
333  } else if(m_taggers.find(tagger) == m_taggers.end()){
334  std::cout << " The tagger [" << tagger << "] doesn't exist in this CDI file!" << std::endl;
335  } else if(m_jetcollections.find(jetcollection) == m_jetcollections.end()){
336  std::cout << " The jet collection [" << jetcollection << "] doesn't exist in " << tagger << " this CDI file!" << std::endl;
337  } else {
338  for(const auto& wp : m_metadata[tagger][jetcollection]){
339  wps.push_back(wp.first);
340  }
341  }
342  return wps;
343 }
344 
345 std::vector<std::string> Analysis::CDIReader::getTaggers(){
346  Labels taggers;
347  taggers.assign(m_taggers.begin(), m_taggers.end());
348  return taggers;
349 }
TrigJetMonitorAlgorithm.jetcoll
jetcoll
Definition: TrigJetMonitorAlgorithm.py:1161
Analysis::CDIReader::getLabels
Labels getLabels(const std::string &tagger="", const std::string &jetcollection="", const std::string &workingpoint="")
Definition: CDIReader.cxx:289
egammaParameters::depth
@ depth
pointing depth of the shower as calculated in egammaqgcld
Definition: egammaParamDefs.h:276
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:126
json
nlohmann::json json
Definition: HistogramDef.cxx:9
CDIReader.h
Analysis::CDIReader::checkConfig
bool checkConfig(const std::string &tagger, const std::string &jetcoll, const std::string &wp, bool verbose=false)
Definition: CDIReader.cxx:192
Analysis::CDIReader::getWorkingPoints
Labels getWorkingPoints(const std::string &tagger, const std::string &jetcollection)
Definition: CDIReader.cxx:328
hist_file_dump.d
d
Definition: hist_file_dump.py:137
PlotCalibFromCool.label
label
Definition: PlotCalibFromCool.py:78
json
nlohmann::json json
Definition: CDIReader.cxx:13
Analysis::CDIReader::Labels
std::vector< std::string > Labels
Definition: CDIReader.h:41
Analysis::CDIReader::getDSIDs
Labels getDSIDs(const std::string &tagger="", const std::string &jetcollection="", const std::string &workingpoint="")
Definition: CDIReader.cxx:262
ParseInputs.flavourDir
flavourDir
Definition: Final2012/ParseInputs.py:46
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
beamspotnt.labels
list labels
Definition: bin/beamspotnt.py:1447
jet
Definition: JetCalibTools_PlotJESFactors.cxx:23
Analysis::CalibrationDataContainer::listUncertainties
std::vector< std::string > listUncertainties() const
retrieve the list of "uncertainties" accessible to this object.
Definition: CalibrationDataContainer.cxx:120
Analysis::CDIReader::crawlCDI
void crawlCDI(TDirectoryFile *parentDir, int depth=0, const std::string &metamap="")
Definition: CDIReader.cxx:35
GetAllXsec.DSID
tuple DSID
Definition: GetAllXsec.py:53
PlotSFuncertainty.wp
wp
Definition: PlotSFuncertainty.py:112
Analysis::CDIReader::m_CDIFile
std::unique_ptr< TFile > m_CDIFile
Definition: CDIReader.h:104
beamspotman.dir
string dir
Definition: beamspotman.py:623
merge.output
output
Definition: merge.py:17
Analysis::CDIReader::getJetCollections
Labels getJetCollections(const std::string &tagger)
Definition: CDIReader.cxx:311
Analysis::CalibrationDataHistogramContainer
Definition: CalibrationDataContainer.h:247
cwd
std::string cwd
Definition: listroot.cxx:38
Analysis::CDIReader::printMetadata
void printMetadata(int tagger=-1, int jetcoll=-1, int wpoint=-1, int label=-1)
Definition: CDIReader.cxx:125
Analysis::CDIReader::record_metadata
void record_metadata(const std::string &datum, int depth=0)
Definition: CDIReader.h:113
Analysis::CDIReader::Data
std::map< std::string, Labels > Data
Definition: CDIReader.h:42
python.TriggerHandler.verbose
verbose
Definition: TriggerHandler.py:297
defineDB.jets
list jets
Definition: JetTagCalibration/share/defineDB.py:24
python.Bindings.keys
keys
Definition: Control/AthenaPython/python/Bindings.py:790
calibdata.copy
bool copy
Definition: calibdata.py:27
CaloCondBlobAlgs_fillNoiseFromASCII.tag
string tag
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:24
Analysis::CDIReader::getTaggers
Labels getTaggers()
Definition: CDIReader.cxx:345
Analysis::CDIReader::CDIReader
CDIReader(const std::string &cdipath, bool verbose=false)
normal constructor.
Definition: CDIReader.cxx:15
Trk::split
@ split
Definition: LayerMaterialProperties.h:38