ATLAS Offline Software
MonitoringFile.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3  */
4 
8 
9 #include <cmath>
10 #include <cstdio>
11 #include <exception>
12 #include <fstream>
13 #include <iostream>
14 #include <memory>
15 #include <set>
16 #include <sstream>
17 #include <vector>
18 #include <map>
19 
20 #include <boost/algorithm/string/split.hpp>
21 #include <boost/algorithm/string/classification.hpp>
22 #include <boost/lexical_cast.hpp>
23 #include <regex>
24 #include <TSystem.h>
25 
26 #include <TDirectory.h>
27 
28 #include <TGraph.h>
29 #include <TH2.h>
30 #include <TIterator.h>
31 #include <TKey.h>
32 #include <TROOT.h>
33 #include <TTree.h>
34 #include <TEfficiency.h>
35 #include "TTreeReader.h"
36 #include "TTreeReaderArray.h"
37 
39 
40 
41 namespace dqutils {
42  bool histOKToMerge(TH1* h) {
43  Long_t arrsize, computedsize;
44 
45  switch (h->GetDimension()) {
46  case 1:
47  computedsize = h->GetNbinsX() + 2;
48  break;
49 
50  case 2:
51  computedsize = (h->GetNbinsX() + 2) * (h->GetNbinsY() + 2);
52  break;
53 
54  case 3:
55  computedsize = (h->GetNbinsX() + 2) * (h->GetNbinsY() + 2) * (h->GetNbinsZ() + 2);
56  break;
57 
58  default:
59  std::cerr << "Unable to handle dimension of " << h->GetName() << "; refusing to merge";
60  return false;
61  }
62  TArray* arrptr = dynamic_cast<TArray*>(h);
63  if (!arrptr) {
64  std::cerr << "Unable to cast TH1 to TArray for " << h->GetName() << " - saying it's OK and hoping for the best" <<
65  std::endl;
66  return true;
67  }
68  arrsize = arrptr->GetSize();
69  if (computedsize != arrsize) {
70  std::cout << "Sizes: computed " << computedsize << " array " << arrsize << std::endl;
71  }
72  return computedsize == arrsize;
73  }
74 
75 // *********************************************************************
76 // Public Methods
77 // *********************************************************************
78 
81  : m_metadata(metadata) {
82  makeBranch("Name", "Name/C");
83  makeBranch("Interval", "Interval/C");
84  makeBranch("TriggerChain", "TriggerChain/C");
85  makeBranch("MergeMethod", "MergeMethod/C");
86  }
87 
88  void
90  makeBranch(const char* branchName, const char* branchstr) {
91  if (!m_metadata->GetBranch(branchName)) {
92  m_metadata->Branch(branchName, (void*) nullptr, branchstr);
93  }
94  }
95 
96  void
98  fill(const std::string& theName,
99  const std::string& theInterval,
100  const std::string& theChain,
101  const std::string& theMerge) {
102  std::string name = theName;
103  std::string interval = theInterval;
104  std::string chain = theChain;
105  std::string merge = theMerge;
106  m_metadata->SetBranchAddress("Name", name.data());
107  m_metadata->SetBranchAddress("Interval", interval.data());
108  m_metadata->SetBranchAddress("TriggerChain", chain.data());
109  m_metadata->SetBranchAddress("MergeMethod", merge.data());
110  m_metadata->Fill();
111  }
112 
117  m_debugLevel = 0;
120  }
121 
123  MonitoringFile(const std::string& fileName)
126  m_debugLevel = 0;
130  }
131 
135 
136  delete m_file;
137  delete m_mergeMatchDirRE;
138  delete m_mergeMatchHistoRE;
139  }
140 
141  bool MonitoringFile::setHistogramRegEx(const std::string& re) {
142  if (re.empty()) {
143  std::cerr << __PRETTY_FUNCTION__ << "Warning empty regular expression string is given. Old RegEx \"" <<
144  m_mergeMatchHistoREString << "\" is not changed" << std::endl;
145  std::cerr << __PRETTY_FUNCTION__ <<
146  "See http://www.boost.org/doc/libs/1_42_0/libs/regex/doc/html/boost_regex/syntax.html for allowed regular expression syntax"
147  << std::endl;
148  return false;
149  }
150  std::regex* reNew = 0;
151  try{
152  reNew = new std::regex(re);
153  // this should fail if there are any problems with re!
154  std::string test("Test String");
155  std::regex_match(test, *reNew);
156  }catch (std::exception& e) {
157  std::cerr << __PRETTY_FUNCTION__ << "Invalid RegEx string \"" << re << "\". Old RegEx \"" <<
158  m_mergeMatchHistoREString << "\" is not changed" << std::endl;
159  std::cerr << __PRETTY_FUNCTION__ <<
160  "See http://www.boost.org/doc/libs/1_42_0/libs/regex/doc/html/boost_regex/syntax.html for allowed regular expression syntax"
161  << std::endl;
162  delete reNew;
163  return false;
164  }
165  delete m_mergeMatchHistoRE;
167  m_mergeMatchHistoRE = reNew;
168  //delete reNew;
169  m_useRE = true;
170  return true;
171  }
172 
173  bool MonitoringFile::setDirectoryRegEx(const std::string& re) {
174  if (re.empty()) {
175  std::cerr << __PRETTY_FUNCTION__ << "Warning empty regular expression string is given. Old RegEx \"" <<
176  m_mergeMatchDirREString << "\" is not changed" << std::endl;
177  std::cerr << __PRETTY_FUNCTION__ <<
178  "See http://www.boost.org/doc/libs/1_42_0/libs/regex/doc/html/boost_regex/syntax.html for allowed regular expression syntax"
179  << std::endl;
180  return false;
181  }
182  std::regex* reNew = 0;
183  try{
184  reNew = new std::regex(re);
185  std::regex_match("Test string", *reNew);
186  }catch (std::exception& e) {
187  std::cerr << __PRETTY_FUNCTION__ << "Invalid RegEx string \"" << re << "\". Old RegEx \"" <<
188  m_mergeMatchDirREString << "\" is not changed" << std::endl;
189  std::cerr << __PRETTY_FUNCTION__ <<
190  "See http://www.boost.org/doc/libs/1_42_0/libs/regex/doc/html/boost_regex/syntax.html for allowed regular expression syntax"
191  << std::endl;
192  delete reNew;
193  return false;
194  }
195  delete m_mergeMatchDirRE;
197  m_mergeMatchDirRE = reNew;
198  //delete reNew;
199  m_useRE = true;
200  return true;
201  }
202 
203  void
205  getAllDirs(DirMap_t& dirmap, TDirectory* dir, const std::string& dirName) {
206  if (dir == 0) return;
207 
208  if (dirName != "") {
209  DirMap_t::value_type dirmapVal(dirName, dir);
210  dirmap.insert(dirmapVal);
211  }
212 
213  TIter next(dir->GetListOfKeys());
214  TKey* key;
215  while ((key = dynamic_cast<TKey*>(next())) != 0) {
216  // don't delete TDirectories
217  TObject* obj = key->ReadObj();
218  TDirectory* subdir = dynamic_cast<TDirectory*>(obj);
219  if (subdir != 0) {
220  std::string subdirName(subdir->GetName());
221  std::string fName("");
222  if (dirName != "") {
223  fName += dirName;
224  fName += '/';
225  }
226  fName += subdirName;
227  getAllDirs(dirmap, subdir, fName);
228  } else {
229  delete obj;
230  }
231  }
232  }
233 
234  TDirectory*
236  createDir(DirMap_t& dirmap, TDirectory* dir, const std::string& parent, const std::string& path) {
237  if (dir == 0) return 0;
238 
239  TDirectory* subdir(0);
240  DirMap_t::const_iterator diter;
241  std::string::size_type i = path.find_first_of('/');
242  std::string fName("");
243  if (parent != "") {
244  fName += parent;
245  fName += '/';
246  }
247 
248  if (i != std::string::npos) {
249  std::string dName(path, 0, i);
250  std::string pName(path, i + 1, std::string::npos);
251  fName += dName;
252  if (dName != "") {
253  diter = dirmap.find(fName);
254  if (diter != dirmap.end()) {
255  subdir = diter->second;
256  } else {
257  subdir = dir->mkdir(dName.c_str());
258  DirMap_t::value_type dirmapVal(fName, subdir);
259  dirmap.insert(dirmapVal);
260  }
261  } else {
262  subdir = dir;
263  }
264  return createDir(dirmap, subdir, fName, pName);
265  }
266 
267  fName += path;
268 
269  diter = dirmap.find(fName);
270  if (diter != dirmap.end()) {
271  return diter->second;
272  }
273 
274  subdir = dir->mkdir(path.c_str());
275  DirMap_t::value_type dirmapVal(fName, subdir);
276  dirmap.insert(dirmapVal);
277  return subdir;
278  }
279 
280  TKey*
282  getObjKey(TDirectory* dir, const std::string& path) {
283  if (dir == 0) return 0;
284 
285  TKey* key(0);
286 
287  std::string::size_type i = path.find_first_of('/');
288  if (i != std::string::npos) {
289  std::string dName(path, 0, i);
290  std::string pName(path, i + 1, std::string::npos);
291  if (dName != "") {
292  key = dir->FindKey(dName.c_str());
293  if (key != 0) {
294  TDirectory* subDir = dynamic_cast<TDirectory*>(key->ReadObj());
295  if (subDir) {
296  return getObjKey(subDir, pName);
297  } // else fall through
298  }
299  return 0;
300  }
301  return getObjKey(dir, pName);
302  }
303 
304  return dir->FindKey(path.c_str());
305  }
306 
307  std::string getInputDirectory(const std::string& outputDirName, TFile* input, bool has_multiple_runs,
308  std::map< TFile*, std::string >* prefixes) {
309  if (!has_multiple_runs) {
310  return outputDirName;
311  } else {
312  std::string retval(outputDirName);
313  std::string::size_type sepi = retval.find("run_multiple");
314  if (sepi != std::string::npos && prefixes->find(input) != prefixes->end()) {
315  retval.replace(sepi, 12, (*prefixes)[input]);
316  }
317  return retval;
318  }
319  }
320 
321  std::string getOutputDirectory(const std::string& inputDirName, TFile* input, bool has_multiple_runs,
322  std::map< TFile*, std::string >* prefixes) {
323  if (!has_multiple_runs) {
324  return inputDirName;
325  } else {
326  std::string retval(inputDirName);
327  if (prefixes->find(input) == prefixes->end()) {
328  return retval;
329  }
330  std::string::size_type sepi = retval.find((*prefixes)[input]);
331  if (sepi != std::string::npos) {
332  retval.replace(sepi, (*prefixes)[input].length(), "run_multiple");
333  }
334  return retval;
335  }
336  }
337 
338  std::string getOutputDirectory(TKey* key, TFile* input, bool has_multiple_runs, std::map< TFile*,
339  std::string >* prefixes) {
340  if (TClass::GetClass(key->GetClassName())->InheritsFrom("TDirectory")) {
341  return getOutputDirectory(key->GetName(), input, has_multiple_runs, prefixes);
342  } else {
343  return key->GetName();
344  }
345  }
346 
347 // This function will populate a mapping between key names and vectors of cycles
348  void populateKeyMapping(TDirectory* dir, keycyclemap& kcmap) {
349  TIter nextKey(dir->GetListOfKeys());
350  TKey* key;
351 
352  std::string keyName("");
353  while ((key = dynamic_cast<TKey*>(nextKey())) != 0) {
354  kcmap[key->GetName()].push_back(key->GetCycle());
355  }
356  }
357 
358 // This function will merge objects given a name, a vector of cycles,
359 // a directory, a merge type, and optionally an object to merge into.
360 // Return value is a merged object.
361  void MonitoringFile::mergeObjsMultiCycles(const std::string& keyname,
362  const std::vector<int>& cycles,
363  TDirectory* dir,
364  const std::string& mergeType,
365  std::unique_ptr<TObject>& obj) {
366  if (cycles.size() == 0) {
367  return;
368  }
369  int start_idx = 0;
370  if (obj == nullptr) {
371  TKey* key(dir->GetKey(keyname.c_str(), cycles[0]));
372  obj.reset(key->ReadObj());
373  start_idx = 1;
374  TH1* h = dynamic_cast<TH1*>(obj.get());
375  if (h && !histOKToMerge(h)) {
376  // histogram is damaged goods
377  std::cerr << "WARNING: HISTOGRAM " << h->GetName() << " IS INTERNALLY INCONSISTENT, NOT MERGING" << std::endl;
378  return;
379  }
380  }
381  for (std::vector<int>::size_type idx = start_idx;
382  idx < cycles.size(); ++idx) {
383  TKey* nextKey = dir->GetKey(keyname.c_str(), cycles[idx]);
384  if (nextKey != 0) {
385  std::unique_ptr<TObject> nextObj(nextKey->ReadObj());
386  if (nextObj.get() == 0) {
387  std::cerr << "MonitoringFile::mergeObjsMultiCycles(): "
388  << "In directory \"" << dir->GetPath() << "\",\n"
389  << " Object \"" << keyname << "\" cannot be read from file: skipping\n";
390  continue;
391  }
392  TH1* h = dynamic_cast<TH1*>(nextObj.get());
393  if (h && !histOKToMerge(h)) {
394  // histogram is damaged goods; even deleting it may be dangerous
395  std::cerr << "WARNING: HISTOGRAM " << h->GetName() << " IS INTERNALLY INCONSISTENT, NOT MERGING" << std::endl;
396  (void) nextObj.release();
397  continue;
398  }
399  // next: if current "target" histogram exists, but is empty, reset it to the next object.
400  // works around
401  h = dynamic_cast<TH1*>(obj.get());
402  if (h && h->GetEntries() == 0 && h->GetSumOfWeights() == 0) {
403  // just take over nextObj as obj
404  obj.reset(nextObj.release());
405  continue;
406  }
407  if (h && (obj->IsA() != h->IsA())) {
408  // problem: class types have changed ...
409  std::cerr << "WARNING: CHANGE OF CLASS TYPES FOR " << h->GetName() << ", NOT MERGING" << std::endl;
410  continue;
411  }
413  nextObj.get(), mergeType,
414  m_debugLevel >
416  } else {
417  std::cerr << "MonitoringFile::mergeObjsMultiCycles(): NULL KEY; corrupt file?" << std::endl;
418  }
419  }
420  return;
421  }
422 
423  void getListOfKeysWithName(TDirectory* dir, const std::string& keyname,
424  TCollection* target) {
425  target->Clear();
426  TIter keyit(dir->GetListOfKeys());
427  TKey* key;
428  while ((key = dynamic_cast<TKey*>(keyit())) != 0) {
429  if (keyname == key->GetName()) {
430  target->Add(key);
431  }
432  }
433  }
434 
435  void populateCycleVector(const TCollection& source, std::vector<int>& target) {
436  TKey* key;
437  TIter keyit(&source);
438 
439  while ((key = dynamic_cast<TKey*>(keyit())) != 0) {
440  target.push_back(key->GetCycle());
441  }
442  }
443 
444 // 'mergeDirectory(...)' is based on 'MergeRootfile(...)' in the hadd.cxx utility in ROOT, using
445 // the same algorithm for looping over files, directories and histograms.
446 
447  void
449  mergeDirectory(TDirectory* outputDir, const std::vector<TFile*>& inputFiles, bool has_multiple_runs,
450  std::map< TFile*, std::string >* prefixes) {
451  typedef std::set< std::string > ObjNameSet_t;
452  typedef std::map< std::string, MetaData > MetaDataMap_t;
453 
454  if (outputDir == 0) {
455  return;
456  }
457 
458  gROOT->cd();
459 
460  std::string outputDirPath(outputDir->GetPath());
461  std::string outputDirName(outputDirPath);
462  std::string::size_type sepi = outputDirPath.find_last_of(':');
463  if (sepi != std::string::npos) {
464  outputDirName = std::string(outputDirPath, sepi + 2, std::string::npos);
465  }
466  //std::cout << outputDirName << std::endl;
467  bool metadataInDir = false;
468  bool targetDir = !m_useRE;
469  if (m_useRE && (std::regex_search(outputDirName, *m_mergeMatchDirRE))) {
470  //std::cout<<"Found target dir \""<<outputDirName<<"\""<<std::endl;
471  targetDir = true;
472  }
473  TTree* mdTree = new TTree("metadata", "Monitoring Metadata");
474  mdTree->SetDirectory(0);
475  OutputMetadata outputmd(mdTree);
476 
477  ObjNameSet_t mergedObjs;
478  MetaDataMap_t mdMap;
479 
480  std::vector<TFile*>::const_iterator inputFilesEnd = inputFiles.end();
481  for (std::vector<TFile*>::const_iterator i = inputFiles.begin(); i != inputFilesEnd; ++i) {
482  TFile* inputFile = *i;
483  TDirectory* inputDir =
484  inputFile->GetDirectory(getInputDirectory(outputDirName, inputFile, has_multiple_runs, prefixes).c_str());
485  if (inputDir == 0) {
486  // Directory is not present in this file; try next file
487  continue;
488  }
489  //std::cout<<"inputdir=\""<<inputDir->GetPath()<<"\""<<std::endl;
490  if (inputDir == outputDir) {
491  continue;
492  }
493 
494  inputDir->cd();
495  fillMetaDataMap(mdMap, inputDir);
496  gROOT->cd();
497 
498  TIter nextKey(inputDir->GetListOfKeys());
499  TKey* key;
500  std::string keyName("");
501  keycyclemap kcmap;
503 
504  for (keycyclemap::iterator kcit = kcmap.begin();
505  kcit != kcmap.end();
506  ++kcit) {
507  key = inputDir->GetKey(kcit->first.c_str(), kcit->second.back());
508  if (!key) {
509  std::cout << "Key " << kcit->first.c_str() << ";" << kcit->second.back() << " not readable" << std::endl;
510  continue;
511  }
512  kcit->second.pop_back();
513  keyName = getOutputDirectory(key, inputFile, has_multiple_runs, prefixes);
514  ObjNameSet_t::iterator obji = mergedObjs.find(keyName);
515  if (obji != mergedObjs.end()) {
516  // Object has already been processed
517  continue;
518  }
519  // we only need to read the non-dir objects below target directory. skip the rest
520  bool isDir = false;
521  if (m_useRE && key->IsFolder()) {
522  //std::cout<<"Key "<<keyName<<" is a folder"<<std::endl;
523  if (keyName != "metadata") isDir = true; //metadata is not going to be merged, treat it as a regular obj
524  }
525  if (!targetDir && !isDir) {
526  //std::cerr<<"Skipping keyname "<keyname<<std::endl;
527  continue; //skip everything except directories
528  }
529  std::unique_ptr<TObject> obj(key->ReadObj());
530  if (obj.get() == 0) {
531  std::cerr << "MonitoringFile::mergeDirectory(): "
532  << "In directory \"" << inputDir->GetPath() << "\",\n"
533  << " Object \"" << key->GetName() << "\" cannot be read from file: skipping\n";
534  continue;
535  }
536 
537  // we actually have an object, and it hasn't been done before
538  mergedObjs.insert(keyName);
539 
540  TH1* h(0);
541  TGraph* g(0);
542  TEfficiency* e(0);
543  TDirectory* d(0);
544  TTree* t(0);
545  //moved inside if to speedup
546 // h = dynamic_cast<TH1*>( obj.get() );
547 // d = dynamic_cast<TDirectory*>( obj.get() );
548 // g = dynamic_cast<TGraph*>( obj.get() );
549 // t = dynamic_cast<TTree*>( obj.get() );
550 
551  //merge only objects below target directory
552  if ((targetDir) && ((h = dynamic_cast<TH1*>(obj.get()))
553  || (g = dynamic_cast<TGraph*>(obj.get()))
554  || ((t = dynamic_cast<TTree*>(obj.get())) && (keyName != "metadata"))
555  || (e = dynamic_cast<TEfficiency*>(obj.get()))
556  )
557  ) {
558  //skip cases where regexp doesn't match object name, all directories are processed by default
559  if (m_useRE) {
560  if (!std::regex_search(keyName, *m_mergeMatchHistoRE)) {
561  //std::cerr<<" skipping keyName=\""<<outputDirName+'/'+keyName<<"\""<<std::endl;
562  continue; // not the histogram we want
563  }
564  }
565  std::string mergeType("<default>");
566  MetaDataMap_t::iterator mdi = mdMap.find(keyName);
567  if (mdi != mdMap.end()) {
568  metadataInDir = true;
569  const MetaData& md = mdi->second;
570  if (has_multiple_runs &&
571  (md.interval != "run" &&
572  md.interval != "fill" &&
573  md.interval != "all" &&
574  md.interval != "file")) {
575  continue;
576  }
577  outputmd.fill(md.name, md.interval, md.chain, md.merge);
578  mergeType = md.merge;
579  if (g && (md.merge != "<default>")) {
580  std::cerr << "MonitoringFile::mergeDirectory(): "
581  << "In directory \"" << inputDir->GetPath() << "\",\n"
582  << " TGraph \"" << keyName << "\" requests merging type " << mergeType
583  << " but only default merging implemented for TGraphs\n";
584  }
585  if (t && (md.merge != "<default>")) {
586  std::cerr << "MonitoringFile::mergeDirectory(): "
587  << "In directory \"" << inputDir->GetPath() << "\",\n"
588  << " TTree \"" << keyName << "\" requests merging type " << mergeType
589  << " but only default merging implemented for TTrees\n";
590  }
591  if (e && (md.merge != "<default>")) {
592  std::cerr << "MonitoringFile::mergeDirectory(): "
593  << "In directory \"" << inputDir->GetPath() << "\",\n"
594  << " TEfficiency \"" << keyName << "\" requests merging type " << mergeType
595  << " but only default merging implemented for TEfficiency\n";
596  }
597  } else {
598  std::cerr << "MonitoringFile::mergeDirectory(): "
599  << "In directory \"" << inputDir->GetPath() << "\",\n"
600  << " object \"" << keyName << "\" has no metadata\n";
601  }
602  if (t) {
603  TDirectory* currentDir = gDirectory;
604  outputDir->cd();
605  TTree* t2 = t->CloneTree();
606  // this disconnects parent tree
607  obj.reset(t2);
608  currentDir->cd();
609  }
610  mergeObjsMultiCycles(keyName, kcit->second, inputDir,
611  mergeType, obj);
612  for (std::vector<TFile*>::const_iterator j = i + 1; j != inputFilesEnd; ++j) {
613  TFile* nextInputFile = *j;
614  TDirectory* nextInputDir =
615  nextInputFile->GetDirectory(getInputDirectory(outputDirName, *j, has_multiple_runs, prefixes).c_str());
616  if (nextInputDir == 0) {
617  // Directory is not present in this file; try next file
618  continue;
619  }
620 
621  TObjArray tl;
622  std::vector<int> nextCycles;
623  getListOfKeysWithName(nextInputDir, kcit->first, &tl);
624  populateCycleVector(tl, nextCycles);
625 
626  mergeObjsMultiCycles(kcit->first, nextCycles,
627  nextInputDir, mergeType, obj);
628  }
629  outputDir->cd();
630  if ((h = dynamic_cast<TH1*>(obj.get()))) {
631  h->SetDirectory(outputDir);
632  }
633 
634  obj->Write();
635  } else if ((targetDir) && (t = dynamic_cast<TTree*>(obj.get()))) {
636  // do not merge metadata
637  } else if ((d = dynamic_cast<TDirectory*>(obj.get()))) {
638  // Do not run the multicycle merge on directories;
639  // haven't seen one yet that has multiple keys...
640  // Merge TDirectory
641  outputDir->cd();
642  std::string outputSubDirName(getOutputDirectory(d->GetName(), inputFile, has_multiple_runs, prefixes));
643  TDirectory* outputSubDir = outputDir->mkdir(outputSubDirName.c_str(), d->GetTitle());
644  mergeDirectory(outputSubDir, inputFiles, has_multiple_runs, prefixes);
645  } else {
646  std::cout << "MonitoringFile::mergeDirectory(): "
647  << "In directory \"" << inputDir->GetPath() << "\",\n"
648  << " Object \"" << key->GetName() << "\" will not be merged\n";
649  }
650  }
651  }
652 
653  // Write metadata TTree to output directory
654  if (metadataInDir) {
655  outputDir->cd();
656  mdTree->SetDirectory(outputDir);
657  mdTree->Write();
658  }
659  delete mdTree;
660  }
661 
662  void
664  fillMetaDataMap(std::map<std::string, dqutils::MonitoringFile::MetaData>& mdMap, TDirectory* dir) {
665  if (dir == 0) return;
666 
667  TTree* md = dynamic_cast<TTree*>(dir->Get("metadata"));
668  if (md == 0) return;
669 
670  TTreeReader reader(md);
671  TTreeReaderArray<char> i_name(reader, "Name");
672  TTreeReaderArray<char> i_interval(reader, "Interval");
673  TTreeReaderArray<char> i_chain(reader, "TriggerChain");
674  TTreeReaderArray<char> i_merge(reader, "MergeMethod");
675 
676  while (reader.Next()) {
677  const std::string nameStr(static_cast<char*>(i_name.GetAddress()));
678  if (mdMap.find(nameStr) == mdMap.end()) {
679  MetaData md(nameStr,
680  static_cast<char*>(i_interval.GetAddress()),
681  static_cast<char*>(i_chain.GetAddress()),
682  static_cast<char*>(i_merge.GetAddress()));
683  std::map<std::string, MetaData>::value_type mdVal(nameStr, md);
684  mdMap.insert(mdVal);
685  }
686  }
687 
688  delete md;
689  }
690 
691 // 'mergeFiles(...)' is based on the hadd.cxx utility distributed with ROOT
692 
693  void
695  mergeFiles(const std::string& outFileName, const std::vector<std::string>& files) {
697  TH1::AddDirectory(false);
698  if (m_useRE) {
699  std::cout << " ========== Using regular expressions for selective merging ========== " << std::endl;
700  std::cout << " Directory selection RE=\"" << m_mergeMatchDirREString << "\"" << std::endl;
701  std::cout << " Object selection RE=\"" << m_mergeMatchHistoREString << "\"" << std::endl;
702  }
703  typedef std::vector<TFile*> TFileList_t;
704  typedef std::map<TFile*, std::string> PrefixIgnore_t;
705 
706  std::unique_ptr<TFile> outfile(TFile::Open(outFileName.c_str(), "RECREATE",
708  if (outfile.get() == 0) {
709  std::cerr << "MonitoringFile::mergeFiles(): "
710  << "Output file not opened\n";
711  return;
712  }
713 
714  TFileList_t tfiles;
715  PrefixIgnore_t prefix_ignore;
716 
717  std::vector< std::string >::const_iterator filesEnd = files.end();
718  std::vector< std::string >::const_iterator fi;
719  for (fi = files.begin(); fi != filesEnd; ++fi) {
720  std::cout << "Opening file: " << *fi << "\n";
721  TFile* f = TFile::Open(fi->c_str());
722  if (f == 0 || !f->IsOpen()) {
723  std::cerr << "MonitoringFile::mergeFiles(): "
724  << "Input file not opened\n";
725  delete f;
726  continue;
727  }
728  TList* keys = f->GetListOfKeys();
729  if (keys->GetSize() == 0) {
730  std::cerr << "MonitoringFile::mergeFiles(): "
731  << "Input file " << *fi << " has no keys!"
732  << std::endl;
733  delete f;
734  continue;
735  }
736  std::vector< std::string > runkeys;
737  TIter keyitr(keys);
738  TKey* key;
739 
740  while ((key = dynamic_cast<TKey*>(keyitr())) != 0) {
741  std::string keyname(key->GetName());
742  if (keyname.substr(0, 4) == "run_") {
743  runkeys.push_back(keyname);
744  }
745  }
746  if (runkeys.size() > 1) {
747  std::cerr << "MonitoringFile::mergeFiles():\n"
748  << " Input root file " << *fi << " has multiple top-level run_* keys\n"
749  << " Assuming " << runkeys[0] << " is the run key"
750  << std::endl;
751  }
752  if (runkeys.size() > 0) {
753  prefix_ignore[f] = runkeys[0];
754  }
755  tfiles.push_back(f);
756  }
757 
758  // check to see if all run keys are the same
759  bool has_multiple_runs = false;
760  std::string prev_key_name("");
761 
762  for (PrefixIgnore_t::const_iterator pi_it = prefix_ignore.begin();
763  pi_it != prefix_ignore.end();
764  ++pi_it) {
765  if (prev_key_name != pi_it->second) {
766  if (prev_key_name == "") {
767  prev_key_name = pi_it->second;
768  } else {
769  has_multiple_runs = true;
770  break;
771  }
772  }
773  }
774 
775  if (has_multiple_runs) {
776  std::cout << "Multiple runs detected in input files.\n"
777  << "Will merge ONLY RUN, FILL, FILE, or ALL histograms to run_multiple directory.\n"
778  << "(That is, no event block, lumi block, lowStat, medStat,\n"
779  << "or higStat histograms will be in the output.)"
780  << std::endl;
781  }
782 
783  std::cout << "Writing file: " << outFileName << "\n";
784  std::cout << "\nWarning messages from merging follow:\n\n";
785 
786  mergeDirectory(outfile.get(), tfiles, has_multiple_runs, &prefix_ignore);
787 
788  outfile->Close();
789 
790  TFileList_t::const_iterator tfilesEnd = tfiles.end();
791  TFileList_t::const_iterator tfi;
792  for (tfi = tfiles.begin(); tfi != tfilesEnd; ++tfi) {
793  TFile* tf = *tfi;
794  tf->Delete("");
795  tf->Close();
796  delete tf;
797  }
798 
799  std::cout << "\n";
800  std::cout << "****************************************\n\n";
801  }
802 
803  void
805  mergeFiles(const std::string& outFileName, const std::string& listFileName) {
806  typedef std::vector< std::string > FileList_t;
807 
808  const unsigned int nFilesAtOnce = 50;
809 
810  FileList_t allFiles;
811  bool success = setListFromFile(allFiles, listFileName);
812  if (!success) {
813  std::cerr << "MonitoringFile::mergeFiles(): Cannot merge files\n";
814  return;
815  }
816 
817  if (allFiles.size() <= nFilesAtOnce) {
819  return;
820  }
821 
822  FileList_t procFiles, tmpIntermediateFiles;
823 
824 
825  FileList_t::const_iterator filesEnd = allFiles.end();
826  FileList_t::const_iterator fi = allFiles.begin();
827 
828  unsigned int counter = 0;
829  std::string tmpInputFile("");
830  std::string tmpOutputFile("");
831 
832  // new logic: merge intermediately, then merge intermediate files
833  while (fi != filesEnd) {
834  procFiles.push_back(*fi);
835  ++counter;
836  ++fi;
837  if (counter % nFilesAtOnce == 0 || fi == filesEnd) {
838  std::ostringstream nameStream;
839  nameStream << "tmp_merge_" << counter << ".root";
840  tmpOutputFile = nameStream.str();
841  tmpIntermediateFiles.push_back(tmpOutputFile);
842  mergeFiles(tmpOutputFile, procFiles);
843  procFiles.clear();
844  }
845  /*
846  if( counter == 0 ) {
847  tmpOutputFile = *fi;
848  }
849 
850  ++counter;
851  ++fi;
852 
853  if( counter % nFilesAtOnce == 0 || fi == filesEnd ) {
854  tmpInputFile = tmpOutputFile;
855  procFiles.push_back( tmpInputFile );
856  std::ostringstream nameStream;
857  nameStream << "tmp_merge_" << counter << ".root";
858  tmpOutputFile = nameStream.str();
859  mergeFiles( tmpOutputFile, procFiles );
860  if( counter > nFilesAtOnce ) {
861  std::remove( tmpInputFile.c_str() );
862  }
863  procFiles.clear();
864  }
865 
866  if( fi != filesEnd ) {
867  procFiles.push_back( *fi );
868  }
869  */
870  }
871 
872  /*
873  if( std::rename(tmpOutputFile.c_str(),outFileName.c_str()) == 0 ) {
874  std::cout << "Renaming " << tmpOutputFile << " as " << outFileName << "\n";
875  }
876  else {
877  std::cerr << "Cannot rename " << tmpOutputFile << " as " << outFileName << "\n";
878  }
879  */
880  mergeFiles(outFileName, tmpIntermediateFiles);
881  for (const auto& tmpFile : tmpIntermediateFiles) {
882  int retCode = std::remove(tmpFile.c_str());
883  if (retCode != 0) {
884  std::cerr << "MonitoringFile::mergeFiles; file " << tmpFile << " was not deleted.\n";
885  }
886  }
887  }
888 
889  bool
891  setFile(const std::string& fileName) {
892  clearData();
893  m_file = TFile::Open(fileName.c_str());
894  if (m_file != 0) return true;
895 
896  return false;
897  }
898 
899  void
902  if (m_file == 0) {
903  std::cerr << "MonitoringFile::printDirectories(): "
904  << "No input file is open\n";
905  return;
906  }
907 
908  DirMap_t indirmap;
909 
910  getAllDirs(indirmap, m_file, "");
911 
912  DirMap_t::const_iterator idirend = indirmap.end();
913  for (DirMap_t::const_iterator idir = indirmap.begin(); idir != idirend; ++idir) {
914  std::string idirName = idir->first;
915  std::cout << idirName << "\n";
916  }
917  }
918 
919  void
922  if (m_file == 0) {
923  std::cerr << "MonitoringFile::printStatistics(): "
924  << "No input file is open\n";
925  return;
926  }
927 
928  DirMap_t indirmap;
929 
930  getAllDirs(indirmap, m_file, "");
931 
932  DirMap_t::const_iterator idirend = indirmap.end();
933  for (DirMap_t::const_iterator idir = indirmap.begin(); idir != idirend; ++idir) {
934  std::string idirName = idir->first;
935 
936  GatherStatistics stat_shift(idirName);
937  GatherStatistics stat_all(idirName);
938 
939  loopOnHistogramsInMetadata(stat_shift, idir->second);
940  loopOnHistograms(stat_all, idir->second);
941 
942  std::cout.setf(std::ios_base::left, std::ios_base::adjustfield);
943  std::cout.width(80);
944  std::cout << idirName << " ";
945 
946  std::cout.setf(std::ios_base::right, std::ios_base::adjustfield);
947  std::cout << " shift: ";
948  std::cout.width(3);
949  std::cout << stat_shift.m_nHist1D << " ";
950  std::cout.width(5);
951  std::cout << stat_shift.m_nHist1DBins << " ";
952  std::cout.width(3);
953  std::cout << stat_shift.m_nHist2D << " ";
954  std::cout.width(7);
955  std::cout << stat_shift.m_nHist2DBins << " ";
956  std::cout.width(3);
957  std::cout << stat_shift.m_nGraph << " ";
958  std::cout.width(5);
959  std::cout << stat_shift.m_nGraphPoints << " ";
960 
961 
962  std::cout << " all: ";
963  std::cout.width(3);
964  std::cout << stat_all.m_nHist1D << " ";
965  std::cout.width(5);
966  std::cout << stat_all.m_nHist1DBins << " ";
967  std::cout.width(3);
968  std::cout << stat_all.m_nHist2D << " ";
969  std::cout.width(7);
970  std::cout << stat_all.m_nHist2DBins << " ";
971  std::cout.width(3);
972  std::cout << stat_all.m_nGraph << " ";
973  std::cout.width(5);
974  std::cout << stat_all.m_nGraphPoints << "\n";
975 
976  std::cout << std::flush;
977  }
978  }
979 
980  bool
982  copyHistograms(const std::string& outFileName, const std::string& dirName) {
984  // bool useRecursiveDelete = gROOT->MustClean();
985  // gROOT->SetMustClean(false);
986 
987  if (m_file == 0) {
988  std::cerr << "MonitoringFile::copyHistograms(): "
989  << "No input file is open\n";
990  return false;
991  }
992 
993  DirMap_t indirmap;
994  DirMap_t reducedmap;
995  DirMap_t outdirmap;
996 
997  if (dirName != "all") {
998  TKey* dkey = getObjKey(m_file, dirName);
999  if (dkey == 0) {
1000  std::cerr << "MonitoringFile::copyHistograms(): "
1001  << "Directory \'" << dirName << "\' not found in input file\n";
1002  return false;
1003  }
1004 
1005  TDirectory* fromDir = dynamic_cast<TDirectory*>(dkey->ReadObj());
1006 
1007  DirMap_t::value_type dirmapVal(dirName, fromDir);
1008  indirmap.insert(dirmapVal);
1009  } else {
1010  std::cout << "Building list of all TDirectories in file...\n" << std::flush;
1011  getAllDirs(indirmap, m_file, "");
1012  }
1013 
1014  DirMap_t::const_iterator idirend = indirmap.end();
1015  for (DirMap_t::const_iterator idir = indirmap.begin(); idir != idirend; ++idir) {
1016  std::string idirName = idir->first;
1017  std::cout << "Checking " << idirName << "\n" << std::flush;
1018  //std::string::size_type j = idirName.find( "L1Calo/1_PPr_EmFADCTiming" );
1019  //if( j != std::string::npos ) {
1020  // std::cerr << "Skipping directory \"" << idirName << "\"\n";
1021  // std::cerr << std::flush;
1022  // continue;
1023  //}
1024 
1025  if (!dirHasHistogramsInMetadata(idir->second)) {
1026  continue;
1027  }
1028 
1029  reducedmap.insert(*idir);
1030  }
1031 
1032  std::unique_ptr<TFile> outfile(TFile::Open(outFileName.c_str(), "RECREATE",
1034  if (outfile.get() == 0) {
1035  std::cerr << "MonitoringFile::copyHistograms(): "
1036  << "Output file not opened\n";
1037  return false;
1038  }
1039 
1040  idirend = reducedmap.end();
1041  for (DirMap_t::const_iterator idir = reducedmap.begin(); idir != idirend; ++idir) {
1042  std::string idirName = idir->first;
1043  std::cout << "Processing " << idirName << "\n" << std::flush;
1044 
1045  TDirectory* toDir = createDir(outdirmap, outfile.get(), "", idirName);
1046  if (toDir == 0) {
1047  std::cerr << "MonitoringFile::copyHistograms(): "
1048  << "Directory \'" << idirName << "\' not created in output file\n";
1049  return false;
1050  }
1051 
1052  CopyHistogram copyFcn(toDir, idirName);
1053 
1054  loopOnHistogramsInMetadata(copyFcn, idir->second);
1055  }
1056 
1057  outfile->Write();
1058  outfile->Close();
1059 
1060  // gROOT->SetMustClean(useRecursiveDelete);
1061  return true;
1062  }
1063 
1064  std::string
1066  getHanResults(const std::string& hanResultsDir, const std::string& input,
1067  const std::string& hcfg, const std::string& hcfg_lowStat, const std::string& hcfg_medStat) {
1068  //DisableMustClean disabled;
1069 
1070  std::cout << "\nUsing han configurations:\n"
1071  << " entire run: " << hcfg << "\n"
1072  << " low stat interval: " << hcfg_lowStat << "\n"
1073  << " medium stat interval: " << hcfg_medStat << "\n\n" << std::flush;
1074 
1075 
1076  TFile* infile = TFile::Open(input.c_str());
1077  if (infile == 0) {
1078  std::cerr << "MonitoringFile::getHanResults(): "
1079  << "Cannot open input file \"" << input << "\"\n";
1080  return "";
1081  }
1082 
1083  std::vector<std::string> run_dirs;
1084  std::vector<std::string> lowStat_dirs;
1085  std::vector<std::string> medStat_dirs;
1086 
1087  TIter next_run(infile->GetListOfKeys());
1088  TKey* key_run(0);
1089  while ((key_run = dynamic_cast<TKey*>(next_run())) != 0) {
1090  TObject* obj_run = key_run->ReadObj();
1091  TDirectory* tdir_run = dynamic_cast<TDirectory*>(obj_run);
1092  if (tdir_run != 0) {
1093  std::string tdir_run_name(tdir_run->GetName());
1094  if (tdir_run_name.find("run") != std::string::npos) {
1095  run_dirs.push_back(tdir_run_name);
1096  TIter next_minutes(tdir_run->GetListOfKeys());
1097  TKey* key_minutes(0);
1098  while ((key_minutes = dynamic_cast<TKey*>(next_minutes())) != 0) {
1099  TObject* obj_minutes = key_minutes->ReadObj();
1100  TDirectory* tdir_minutes = dynamic_cast<TDirectory*>(obj_minutes);
1101  if (tdir_minutes != 0) {
1102  std::string tdir_minutes_name(tdir_minutes->GetName());
1103  if (tdir_minutes_name.find("lowStat") != std::string::npos) {
1104  lowStat_dirs.push_back(tdir_run_name + '/' + tdir_minutes_name);
1105  } else if (tdir_minutes_name.find("medStat") != std::string::npos) {
1106  medStat_dirs.push_back(tdir_run_name + '/' + tdir_minutes_name);
1107  }
1108  }
1109  delete obj_minutes;
1110  }
1111  }
1112  }
1113  delete obj_run;
1114  }
1115 
1116  delete infile;
1117 
1118  dqi::HanApp han;
1119 
1120  std::string fileList = " ";
1121  std::vector<std::string>::const_iterator dirs_end;
1122  std::vector<std::string>::const_iterator dir;
1123 
1124  dirs_end = run_dirs.end();
1125  for (dir = run_dirs.begin(); dir != dirs_end; ++dir) {
1126  const std::string& tdir_run_name = *dir;
1127  std::string han_output_run = hanResultsDir + '/' + tdir_run_name + "_han.root";
1128  std::cout << "Calling han( " << hcfg << ", " << input << ", " << tdir_run_name
1129  << ", " << han_output_run << " ):\n" << std::flush;
1130  han.Analyze(hcfg, input, han_output_run, tdir_run_name);
1131  std::cout << "\n";
1132  fileList += han_output_run + " " + tdir_run_name + "\n";
1133  }
1134 
1135  dirs_end = lowStat_dirs.end();
1136  for (dir = lowStat_dirs.begin(); dir != dirs_end; ++dir) {
1137  const std::string& tdir_minutes_path = *dir;
1138 
1139  std::string tdir_minutes_underscore = tdir_minutes_path;
1140  std::string::size_type tdir_minutes_i = tdir_minutes_underscore.find('/');
1141  tdir_minutes_underscore.replace(tdir_minutes_i, 1, "_");
1142 
1143  std::string han_output_lowStat = hanResultsDir + '/' + tdir_minutes_underscore + "_han.root";
1144  std::cout << "Running han, writing to " << han_output_lowStat << ":\n" << std::flush;
1145  han.Analyze(hcfg_lowStat, input, han_output_lowStat, tdir_minutes_path);
1146  std::cout << "\n";
1147  std::string subdirname(tdir_minutes_path, tdir_minutes_i + 1, std::string::npos);
1148  std::string dirname(tdir_minutes_path, 0, tdir_minutes_i);
1149  fileList += han_output_lowStat + " " + subdirname + " " + dirname + " " + subdirname + "\n";
1150  }
1151 
1152  dirs_end = medStat_dirs.end();
1153  for (dir = medStat_dirs.begin(); dir != dirs_end; ++dir) {
1154  const std::string& tdir_minutes_path = *dir;
1155 
1156  std::string tdir_minutes_underscore = tdir_minutes_path;
1157  std::string::size_type tdir_minutes_i = tdir_minutes_underscore.find('/');
1158  tdir_minutes_underscore.replace(tdir_minutes_i, 1, "_");
1159 
1160  std::string han_output_medStat = hanResultsDir + '/' + tdir_minutes_underscore + "_han.root";
1161  std::cout << "Running han, writing to " << han_output_medStat << ":\n" << std::flush;
1162  han.Analyze(hcfg_medStat, input, han_output_medStat, tdir_minutes_path);
1163  std::cout << "\n";
1164  std::string subdirname(tdir_minutes_path, tdir_minutes_i + 1, std::string::npos);
1165  std::string dirname(tdir_minutes_path, 0, tdir_minutes_i);
1166  fileList += han_output_medStat + " " + subdirname + " " + dirname + " " + subdirname + "\n";
1167  }
1168 
1169  return fileList;
1170  }
1171 
1172  void
1174  printHanConfig() {
1175  if (m_file == 0) {
1176  std::cerr << "MonitoringFile::printHanConfig(): "
1177  << "No input file is open\n";
1178  return;
1179  }
1180 
1181  DirMap_t indirmap;
1182 
1183  getAllDirs(indirmap, m_file, "");
1184 
1185  std::string indent, indent_p, indent_c;
1186  std::string idirName_p;
1187  DirMap_t::const_iterator idirend = indirmap.end();
1188  for (DirMap_t::const_iterator idir = indirmap.begin(); idir != idirend; ++idir) {
1189  std::string idirName = idir->first;
1190  std::string::size_type shortNameIndex = idirName.rfind('/');
1191  std::string shortName = idirName.substr(shortNameIndex + 1, std::string::npos);
1192 
1193  std::string::size_type fsIndex = idirName.find('/');
1194  std::string shortPath;
1195  if (fsIndex != shortNameIndex) shortPath = idirName.substr(fsIndex + 1, shortNameIndex);
1196  else shortPath = idirName.substr(fsIndex + 1, std::string::npos);
1197 
1198  std::cout << idirName << "\n";
1199  std::cout << shortPath << ", " << shortName << "\n";
1200  /*
1201  indent = getIndentation(idirName,"");
1202  if(int(indent.size())==in_p){
1203  std::cout << indent << "} \n";
1204  std::cout << indent << "dir " << shortName << " { \n";
1205  std::cout << indent << " output " << idirName << "\n";
1206  std::cout << indent << " hist all_in_dir { \n " << indent << " } \n";
1207  }
1208  else if (int(indent.size()) > in_p){
1209  std::cout << indent << "dir " << shortName << " { \n";
1210  std::cout << indent << " output " << idirName << "\n";
1211  std::cout << indent << " hist all_in_dir { \n " << indent << " } \n";
1212  }
1213  else{
1214  //find common part + number of common '/'
1215  std::string common = FindCommon(idirName,idirName_p);
1216  indent_c = getIndentation(common,"");
1217  int counter = (indent_p.size() - indent_c.size())/2;
1218  for (int i = counter; i>0; i--){
1219  std::string temp = indent_c;
1220  for (int j = 0; j< i; j++){
1221  temp+=" ";
1222  }
1223  std::cout << temp << "} \n" ;
1224  }
1225  std::cout << indent << "} \n";
1226  std::cout << indent << "dir " << shortName << " { \n";
1227  std::cout << indent << " output " << idirName << "\n";
1228  std::cout << indent << " hist all_in_dir { \n " << indent << " } \n";
1229  }
1230  indent_p = indent;
1231  in_p = indent_p.size();
1232  idirName_p = idirName;
1233  */
1234  }
1235  }
1236 
1237  std::string
1239  getIndentation(const std::string& pathName, const std::string& leadingSpace) {
1240  std::string space = leadingSpace;
1241  std::string::size_type i = pathName.find_first_of('/');
1242  if (i != std::string::npos) {
1243  std::string subPath(pathName, i + 1, std::string::npos);
1244  space += " ";
1245  return getIndentation(subPath, space);
1246  }
1247  return space;
1248  }
1249 
1250  std::string
1252  FindCommon(const std::string& name1, const std::string& name2) const {
1253  int length = (name1.size() < name2.size()) ? name1.size() : name2.size();
1254  bool found = true;
1255  int count = 0;
1256 
1257  while (found == true && count < length) {
1258  if (name1[count] == name2[count]) {
1259  count++;
1260  } else {
1261  found = false;
1262  }
1263  }
1264  return(name1.substr(0, count));
1265  }
1266 
1267 // *********************************************************************
1268 // Protected Methods
1269 // *********************************************************************
1270 
1272  CopyHistogram(TDirectory* target, const std::string& dirName)
1273  : m_target(target)
1274  , m_dirName(dirName)
1275  , m_metadata(0) {
1276  m_metadata = new TTree("metadata", "Monitoring Metadata");
1277  m_metadata->SetDirectory(0);
1278  m_metadata->Branch("Name", (void*) nullptr, "Name/C");
1279  m_metadata->Branch("Interval", (void*) nullptr, "Interval/C");
1280  m_metadata->Branch("TriggerChain", (void*) nullptr, "TriggerChain/C");
1281  m_metadata->Branch("MergeMethod", (void*) nullptr, "MergeMethod/C");
1282  }
1283 
1285  ~CopyHistogram() {
1286  m_target->cd();
1287  m_metadata->SetDirectory(m_target);
1288  m_metadata->Write();
1289  delete m_metadata;
1290  }
1291 
1292  bool
1294  execute(TH1* hist) {
1295  m_target->cd();
1296  hist->SetDirectory(m_target);
1297  hist->Write();
1298 
1299  return true;
1300  }
1301 
1302  bool
1304  execute(TGraph* graph) {
1305  m_target->cd();
1306  graph->Write();
1307 
1308  return true;
1309  }
1310 
1311  bool MonitoringFile::CopyHistogram::execute(TEfficiency* eff) {
1312  m_target->cd();
1313  eff->Write();
1314  return true;
1315  }
1316 
1317  void
1319  fillMD(const MetaData& md) {
1320  std::string name(md.name);
1321  std::string interval(md.interval);
1322  std::string chain(md.chain);
1323  std::string merge(md.merge);
1324  m_metadata->SetBranchAddress("Name", name.data());
1325  m_metadata->SetBranchAddress("Interval", interval.data());
1326  m_metadata->SetBranchAddress("TriggerChain", chain.data());
1327  m_metadata->SetBranchAddress("MergeMethod", merge.data());
1328  m_metadata->Fill();
1329  }
1330 
1331  bool
1333  executeMD(TH1* hist, const MetaData& md) {
1334  m_target->cd();
1335  hist->SetDirectory(m_target);
1336  hist->Write();
1337 
1338  fillMD(md);
1339 
1340  return true;
1341  }
1342 
1343  bool
1345  executeMD(TGraph* graph, const MetaData& md) {
1346  m_target->cd();
1347  graph->Write();
1348 
1349  fillMD(md);
1350 
1351  return true;
1352  }
1353 
1354  bool MonitoringFile::CopyHistogram::executeMD(TEfficiency* eff, const MetaData& md) {
1355  m_target->cd();
1356  eff->Write();
1357  fillMD(md);
1358  return true;
1359  }
1360 
1362  GatherStatistics(const std::string& dirName)
1363  : m_dirName(dirName)
1364  , m_nHist1D(0)
1365  , m_nHist1DBins(0)
1366  , m_nGraph(0)
1367  , m_nGraphPoints(0)
1368  , m_nHist2D(0)
1369  , m_nHist2DBins(0) {
1370  }
1371 
1372  bool
1374  execute(TH1* hist) {
1375  TH2* hist2d = dynamic_cast<TH2*>(hist);
1376 
1377  if (hist2d != 0) {
1378  ++m_nHist2D;
1379  m_nHist2DBins += (hist2d->GetNbinsX() * hist2d->GetNbinsY());
1380  return true;
1381  }
1382  ++m_nHist1D;
1383  m_nHist1DBins += hist->GetNbinsX();
1384  return true;
1385  }
1386 
1387  bool
1389  execute(TGraph* graph) {
1390  ++m_nGraph;
1391  m_nGraphPoints += graph->GetMaxSize();
1392  return true;
1393  }
1394 
1395  bool MonitoringFile::GatherStatistics::execute(TEfficiency* eff) {
1396  ++m_nEfficiency;
1397 
1398  TH1* h_total = eff->GetCopyPassedHisto();
1399  TH2* h_total2D = dynamic_cast<TH2*>(h_total);
1400 
1401  if (h_total2D != 0) {
1402  m_nEfficiencyBins += (h_total2D->GetNbinsX() * h_total2D->GetNbinsY());
1403  return true;
1404  } else {
1405  m_nEfficiencyBins += h_total->GetNbinsX();
1406  return true;
1407  }
1408  }
1409 
1411  GatherNames() {
1412  }
1413 
1414  bool
1416  execute(TH1* hist) {
1417  m_names.push_back(std::string(hist->GetName()));
1418  return true;
1419  }
1420 
1421  bool
1423  execute(TGraph* graph) {
1424  m_names.push_back(std::string(graph->GetName()));
1425  return true;
1426  }
1427 
1428  bool MonitoringFile::GatherNames::execute(TEfficiency* eff) {
1429  m_names.push_back(std::string(eff->GetName()));
1430  return true;
1431  }
1432 
1433  void
1435  clearData() {
1437 
1438  delete m_file;
1439  m_file = 0;
1440  m_debugLevel = 0;
1442  delete m_mergeMatchHistoRE;
1443  delete m_mergeMatchDirRE;
1445  m_mergeMatchDirREString = ".*";
1448  m_useRE = false;
1449  }
1450 
1451  bool
1453  dirHasHistogramsInMetadata(TDirectory* dir) {
1454  dir->cd();
1455 
1456  TKey* mdKey = dir->FindKey("metadata");
1457  if (mdKey == 0) {
1458  return false;
1459  }
1460 
1461  TTree* md = dynamic_cast<TTree*>(mdKey->ReadObj());
1462  if (md == 0) {
1463  return false;
1464  }
1465 
1466  int counter = 0;
1467  int nEntries = int( md->GetEntries());
1468 
1469  while (counter < nEntries) {
1470  try {
1471  md->GetEntry(counter);
1472  }
1473  catch (const std::exception& e) {
1474  std::cerr << "Exception: \"" << e.what() << "\" in directory \""
1475  << dir->GetName() << "\"\n" << std::flush;
1476  return false;
1477  }
1478 
1479  return true;
1480  //program never reaches this line, the counter is never incremented;
1481  }
1482 
1483  return false;
1484  }
1485 
1486  void
1488  loopOnHistograms(HistogramOperation& fcn, TDirectory* dir) {
1489  TIter next(dir->GetListOfKeys());
1490  TKey* key;
1491 
1492  while ((key = dynamic_cast<TKey*>(next())) != 0) {
1493  TObject* obj = key->ReadObj();
1494  TH1* h(0);
1495  TGraph* g(0);
1496  TEfficiency* e(0);
1497  if ((h = dynamic_cast<TH1*>(obj))) {
1498  fcn.execute(h);
1499  } else if ((g = dynamic_cast<TGraph*>(obj))) {
1500  fcn.execute(g);
1501  } else if ((e = dynamic_cast<TEfficiency*>(obj))) {
1502  fcn.execute(e);
1503  }
1504  delete obj;
1505  }
1506  }
1507 
1508  bool
1510  loopOnHistogramsInMetadata(HistogramOperation& fcn, TDirectory* dir) {
1511  dir->cd();
1512  TKey* mdKey = dir->FindKey("metadata");
1513  if (mdKey == 0) {
1514  return false;
1515  }
1516 
1517  TTree* md = dynamic_cast<TTree*>(mdKey->ReadObj());
1518  if (md == 0) {
1519  return false;
1520  }
1521 
1522  TKey* i_key;
1523 
1524  TTreeReader reader(md);
1525  TTreeReaderArray<char> i_name(reader, "Name");
1526  TTreeReaderArray<char> i_interval(reader, "Interval");
1527  TTreeReaderArray<char> i_chain(reader, "TriggerChain");
1528  TTreeReaderArray<char> i_merge(reader, "MergeMethod");
1529 
1530  while (reader.Next()) {
1531  const std::string nameStr(static_cast<char*>(i_name.GetAddress()));
1532  dir->cd();
1533  i_key = dir->FindKey(static_cast<char*>(i_name.GetAddress()));
1534  if (i_key == 0) {
1535  std::cerr << "MonitoringFile::loopOnHistogramsInMetadata(): "
1536  << "No \'" << nameStr << "\' object found\n";
1537  return false;
1538  }
1539  MetaData md(nameStr,
1540  static_cast<char*>(i_interval.GetAddress()),
1541  static_cast<char*>(i_chain.GetAddress()),
1542  static_cast<char*>(i_merge.GetAddress()));
1543  TObject* obj = i_key->ReadObj();
1544  TH1* h = dynamic_cast<TH1*>(obj);
1545  if (h != 0) {
1546  fcn.executeMD(h, md);
1547  } else {
1548  TGraph* g = dynamic_cast<TGraph*>(obj);
1549  if (g != 0) {
1550  fcn.executeMD(g, md);
1551  }
1552  }
1553  delete obj;
1554  }
1555 
1556  delete md;
1557 
1558  return true;
1559  }
1560 
1561  bool
1563  setListFromFile(std::vector<std::string>& filelist, const std::string& listFileName) {
1564  using namespace std;
1565 
1566  filelist.clear();
1567 
1568  ifstream listfile(listFileName.c_str());
1569  if (!listfile) {
1570  cerr << "MonitoringFile::setListFromFile(): "
1571  << "cannot read from file: " << listFileName << "\n";
1572  return false;
1573  }
1574 
1575  string line;
1576  char c;
1577  string filename;
1578  while (getline(listfile, line)) {
1579  istringstream linestream(line);
1580  while (linestream.get(c)) {
1581  if (!isspace(c)) {
1582  // ignore comments
1583  if (c == '#') {
1584  break;
1585  }
1586 
1587  linestream.putback(c);
1588  linestream >> filename;
1589  if (!linestream) {
1590  cerr << "MonitoringFile::setListFromFile(): "
1591  << "badly formatted line: " << line << "\n";
1592  break;
1593  }
1594 
1595  filelist.push_back(filename);
1596  }
1597  }
1598  }
1599 
1600  return true;
1601  }
1602 
1603  int MonitoringFile::mergeObjs(TObject* objTarget, TObject* obj, const std::string& mergeType,
1605  // merge obj into objTarget based on method specified in mergeType
1606  // copied in large parts from mergeDirectory
1607  std::string name("mergeObjs");
1608  if (!objTarget) {
1609  std::cerr << name << ": empty target object pointer" << std::endl;
1610  return -1;
1611  }
1612  if (!obj) {
1613  std::cerr << name << ": empty object pointer" << std::endl;
1614  return -1;
1615  }
1616 
1617  if (debugLevel >=
1618  VERBOSE) std::cout << name << ": obj->GetName() = " << obj->GetName() << ", mergeType = " << mergeType <<
1619  ", class = " << obj->IsA()->GetName() << std::endl;
1620 
1621  TH1* h = 0, * nextH = 0;
1622  TH2* h2 = 0, * nextH2 = 0;
1623  TGraph* g = 0;
1624  TTree* t = 0;
1625  TEfficiency* e = 0;
1626 
1627 // h = dynamic_cast<TH1*>( objTarget );
1628 // g = dynamic_cast<TGraph*>( objTarget );
1629 // t = dynamic_cast<TTree*>( objTarget );
1630  if ((h = dynamic_cast<TH1*>(objTarget))) { // we are dealing with histograms
1631  /* if ( debugLevel >= DEBUG )
1632  std::cout << " --> " << name << " is a histogram */
1633  nextH = dynamic_cast<TH1*>(obj);
1634  if (!nextH) {
1635  std::cerr << objTarget->GetName() << " is a TH1, but " << obj->GetName() << " is not: skip merging" <<
1636  std::endl;
1637  return -1;
1638  }
1639  if (mergeType == "effAsPerCent") {
1640  if ((h2 = dynamic_cast<TH2*>(objTarget)) && (nextH2 = dynamic_cast<TH2*>(nextH))) {
1641  merge_effAsPerCent(*h2, *nextH2);
1642  } else {
1643  merge_effAsPerCentAlt(*h, *nextH);
1644  }
1645  } else if (mergeType == "perBinEffPerCent") {
1646  merge_perBinEffPerCent(*h, *nextH);
1647  } else if (mergeType == "weightedAverage") {
1648  merge_weightedAverage(*h, *nextH);
1649  } else if (mergeType == "weightedAverage2D") {
1650  //if( h2 && nextH2 ) merge_weightedAverage( *h2, *nextH2 );
1651  merge_weightedAverage(*h, *nextH);
1652  } else if (mergeType == "weightedEff") {
1653  merge_weightedEff(*h, *nextH);
1654  } else if (mergeType == "mergeRebinned") {
1655  merge_Rebinned(*h, *nextH);
1656  } else if (mergeType == "eventSample") {
1657  if ((h2 = dynamic_cast<TH2*>(objTarget)) && (nextH2 = dynamic_cast<TH2*>(nextH))) {
1658  merge_eventSample(*h2, *nextH2);
1659  }
1660  } else if (mergeType == "mergeRMS") {
1661  merge_RMS(*h, *nextH);
1662  } else if (mergeType == "RMSpercentDeviation") {
1663  merge_RMSpercentDeviation(*h, *nextH);
1664  } else if (mergeType == "lowerLB") {
1665  merge_lowerLB(*h, *nextH);
1666  } else if (mergeType == "identical") {
1667  merge_identical(*h, *nextH);
1668  } else if (mergeType == "merge") {
1669  TList tl;
1670  tl.Add(nextH);
1671  h->Merge(&tl);
1672  } else {
1673  if (!h->Add(nextH)) {
1674  std::cerr << "Histogram " << h->GetName() <<
1675  " should NOT be using Add: needs to specify a merge method (e.g. merge) in its metadata";
1676  }
1677  }
1678  } else if ((g = dynamic_cast<TGraph*>(objTarget))) { // TGraphs
1679  if (mergeType != "<default>") {
1680  std::cerr << name << ": TGraph " << obj->GetName() << " request mergeType = " << mergeType
1681  << " but only default merging implemented for TGraphs\n";
1682  }
1683  TGraph* nextG = dynamic_cast<TGraph*>(obj);
1684  TList listG;
1685  listG.Add(nextG);
1686  g->Merge(&listG);
1687  listG.Clear();
1688  } else if ((e = dynamic_cast<TEfficiency*>(objTarget))) { // TEfficiencies
1689  if (mergeType != "<default>") {
1690  std::cerr << name << ": TEfficiency " << obj->GetName() << " request mergeType = " << mergeType
1691  << " but only default merging implemented for TEfficiencies.\n";
1692  }
1693  TEfficiency* nextE = dynamic_cast<TEfficiency*>(obj);
1694  TList listE;
1695  listE.Add(nextE);
1696  e->Merge(&listE);
1697  listE.Clear();
1698  } else if ((t = dynamic_cast<TTree*>(objTarget))) { // TTrees
1699  if (debugLevel >= VERBOSE) {
1700  std::cout << "Merging Tree " << obj->GetName() << std::endl;
1701  }
1702  if (mergeType != "<default>") {
1703  std::cerr << name << ": TTree " << obj->GetName() << " request mergeType = " << mergeType
1704  << " but only default merging implemented for TTrees\n";
1705  }
1706  TTree* nextT = dynamic_cast<TTree*>(obj);
1707  TList listT;
1708  listT.Add(nextT);
1709  t->Merge(&listT);
1710  listT.Clear();
1711  } else {
1712  std::cerr << name << ": object is not a histogram or graph, merging not implemented" << std::endl;
1713  }
1714  return 0;
1715  }
1716 
1717  int MonitoringFile::mergeLB_recursiveDirCopy(TDirectory* dir_top_out, TDirectory* dir_out, TDirectory* cwd,
1718  std::vector<std::string>& v_dirsSub, debugLevel_t& debugLevel) {
1719  // store in v_dirsSub the paths (relative to dir_top_out) of all subdirectories of cwd
1720  // copy the subfolder structure from cwd to dir_out
1721  std::string name("mergeLB_recursiveDirCopy");
1722  if (!cwd) {
1723  std::cerr << name << ": empty directory pointer cwd" << std::endl;
1724  return -1;
1725  }
1726  if (!dir_top_out) {
1727  std::cerr << name << ": empty directory pointer dir_top_out" << std::endl;
1728  return -1;
1729  }
1730  if (!dir_out) {
1731  std::cerr << name << ": empty directory pointer dir_out" << std::endl;
1732  return -1;
1733  }
1734 
1735  TIter next(cwd->GetListOfKeys());
1736  TKey* key;
1737  while ((key = (TKey*) next())) {
1738  std::string keyClassName(key->GetClassName());
1739  if ((keyClassName.size() > 9) && (keyClassName.substr(0, 10) == "TDirectory")) {
1740  TDirectory* dir = (TDirectory*) cwd->Get(key->GetName());
1741  if (!dir) {
1742  std::cerr << name << ": could not retrieve directory " << key->GetName() <<
1743  " from " << cwd->GetPath() << std::endl;
1744  continue;
1745  }
1746  dir_out->cd();
1747  std::string p_top(dir_top_out->GetPath());
1748  std::string p(gDirectory->GetPath());
1749  if (p_top.size() < p.size()) {
1750  p = p.substr(p_top.size() + 1, p.size() - p_top.size() - 1); // strip off the top directory part
1751  p = p + '/';
1752  } else p = "";
1753 
1754  // is this directory already in the list of subdirectories?
1756  for (it = v_dirsSub.begin(); it != v_dirsSub.end(); ++it) {
1757  if (*it == (p + dir->GetName())) break;
1758  }
1759  if (it == v_dirsSub.end()) {
1760  // no
1761  v_dirsSub.push_back(p + dir->GetName());
1762  }
1763 
1764  TKey* test_key = dir_out->FindKey(dir->GetName());
1765  TDirectory* dir_out_new(0);
1766  if (!test_key) {
1767  if (debugLevel >= DEBUG) {
1768  std::cout << name << ": creating subdirectory " << dir->GetName();
1769  if (p.size() != 0) std::cout << " in " << p << std::endl;
1770  else std::cout << std::endl;
1771  }
1772  dir_out_new = (TDirectory*) gDirectory->mkdir(dir->GetName());
1773  if (!dir_out_new) {
1774  std::cerr << name << ": could not create directory " << dir->GetName()
1775  << " in " << gDirectory->GetPath() << std::endl;
1776  }
1777  } else {
1778  if (debugLevel >=
1779  DEBUG) std::cout << name << ": " << dir_out->GetPath() << '/' << dir->GetName() << " exists already" <<
1780  std::endl;
1781 
1782  dir_out_new = (TDirectory*) dir_out->Get(test_key->GetName());
1783  if (!dir_out_new) {
1784  std::cerr << name << ": could not retrieve directory " << test_key->GetName()
1785  << " from " << dir_out->GetPath() << std::endl;
1786  }
1787  }
1788  // go one level deeper in the directory tree
1789  if (dir_out_new) mergeLB_recursiveDirCopy(dir_top_out, dir_out_new, dir, v_dirsSub, debugLevel);
1790  }
1791  }
1792  return 0;
1793  }
1794 
1795  int MonitoringFile::mergeLB_createListOfHistos(TDirectory* dir_top, TDirectory* cwd,
1796  std::vector<std::string>& v_histos, debugLevel_t& debugLevel) {
1797  // get paths relative to dir_top of all histograms and graphs in cwd
1798  std::string name("mergeLB_createListOfHistos");
1799  if (!cwd) {
1800  std::cerr << name << ": empty directory pointer" << std::endl;
1801  return -1;
1802  }
1803 
1804  TIter next(cwd->GetListOfKeys());
1805  TKey* key;
1806  while ((key = (TKey*) next())) {
1807  std::string keyClassName(key->GetClassName());
1808  if (((keyClassName.size() > 2) &&
1809  ((keyClassName.substr(0, 3) == "TH1") || (keyClassName.substr(0, 3) == "TH2"))) ||
1810  ((keyClassName.size() > 7) && ((keyClassName.substr(0, 8) == "TProfile"))) ||
1811  ((keyClassName.size() > 5) && ((keyClassName.substr(0, 6) == "TGraph"))) ||
1812  ((keyClassName.size() > 10) && ((keyClassName.substr(0, 11) == "TEfficiency")))) {
1813  if (debugLevel >= VERBOSE) std::cout << name << ": found object: " << key->GetName();
1814 
1815  // add to v_histos if not already in it
1816  std::string p_top(dir_top->GetPath());
1817  std::string p(cwd->GetPath());
1818  if (p_top.size() < p.size()) {
1819  p = p.substr(p_top.size() + 1, p.size() - p_top.size() - 1); // strip off the top directory part
1820  p = p + '/';
1821  } else p = "";
1822 
1824  for (it = v_histos.begin(); it != v_histos.end(); ++it) {
1825  if (*it == (p + key->GetName())) break;
1826  }
1827 
1828  if (it == v_histos.end()) {
1829  std::string objName(p + key->GetName());
1830  v_histos.push_back(objName);
1831  if (debugLevel >= VERBOSE) std::cout << ", added to list: " << p + key->GetName() << std::endl;
1832  } else {
1833  if (debugLevel >= VERBOSE) std::cout << ", already in list" << std::endl;
1834  }
1835  }
1836  }
1837  return 0;
1838  }
1839 
1840  int MonitoringFile::mergeLB_processLBinterval(std::vector<TDirectory*>& v_dirsStat, TDirectory* dir_run,
1842  // create a directory for merged histograms in dir_run
1843  // loop over v_dirsStat directories (=different LB intervals)
1844  // and merge all histograms and graphs (preserving the subdirectory structure)
1845  std::string name("mergeLB_processLBinterval");
1846 
1847  if (v_dirsStat.size() == 0) return 0;
1848 
1849  if (!dir_run) {
1850  std::cerr << name << ": empty pointer dir_run" << std::endl;
1851  return -1;
1852  }
1853 
1854  if (!v_dirsStat[0]) {
1855  std::cerr << name << ": empty first directory pointer" << std::endl;
1856  return -1;
1857  }
1858 
1859 /*
1860  // create top-level merged directory
1861  std::string label((v_dirsStat[0])->GetName());
1862  label = label.substr(0,3);
1863  std::string dirMergedName("merged_" + label + "Stat");
1864  TDirectory *dir_merged = dir_run->mkdir(dirMergedName.c_str());
1865  if( !dir_merged ) {
1866  std::cerr << name << ": could not create directory " << dirMergedName << std::endl;
1867  return -1;
1868  }
1869  if( debugLevel >= DEBUG )
1870  std::cout << name << ": created new directory " << dir_merged->GetPath() << std::endl;
1871  */
1872  TDirectory* dir_merged = dir_run;
1873 
1874  // Histograms can be booked on demand in AthenaMonitoring.
1875  // So a histogram might be present in lowStat_LB21-30 but not
1876  // in lowStat_LB1-10. Also entire directories might be missing
1877  // in certain LB intervals.
1878  // Hence, to cope with on-demand-booking have to loop over all
1879  // LB intervals to identify all histograms.
1880 
1881  // To limit memory usage, instead of holding all merged histograms in
1882  // memory, build a list of histogram names (including full path because
1883  // can have same name in different subfolders, like Jets/Topo/JetP and
1884  // Jets/Tower/JetP).
1885 
1886  // Build this list only per subfolder. Then loop over list, merge the
1887  // histograms, write them to ROOT file, and delete them from memory.
1888 
1889  // instead of a list, create a map which also holds the merging type
1890  // (whether simply TH1F::Add() or more complicated function) from metadata.
1891 
1892  std::vector<TDirectory*>::const_iterator i;
1893  // loop over LB intervals:
1894  // - get list of subdirectories
1895  // - and create subdirectory structure in merged directory
1896  std::vector<std::string> v_dirsSub;
1897  for (i = v_dirsStat.begin(); i != v_dirsStat.end(); ++i) {
1898  TDirectory* dirStat = *i;
1899  if (debugLevel >= DEBUG)
1900  if (dirStat) std::cout << name << ": getting input from directory " << dirStat->GetPath() << std::endl;
1901  mergeLB_recursiveDirCopy(dir_merged, dir_merged, dirStat, v_dirsSub, debugLevel);
1902  // v_dirsSub are paths relative to dir_merged
1903  }
1904 
1905  // loop over subdirectories:
1906  if (v_dirsSub.size() == 0) {
1907  if (debugLevel >= DEBUG) std::cout << name << ": no subdirectories found" << std::endl;
1908  return 0;
1909  }
1910  // - create list of histograms
1911  // - loop over all LB intervals because of on-demand-booking
1912  // - loop over histogram list
1913  // - loop over LB intervals
1914  // - merge histograms
1915  // - write merged histogram to file and delete it from memory
1916  std::vector<std::string>::const_iterator it_string;
1917  for (it_string = v_dirsSub.begin(); it_string != v_dirsSub.end(); ++it_string) {
1918  std::string dirFullName = *it_string;
1919  std::vector<std::string> v_histos;
1920  if (debugLevel >= DEBUG) std::cout << name << ": processing " << dirFullName << std::endl;
1921  for (i = v_dirsStat.begin(); i != v_dirsStat.end(); ++i) {
1922  TDirectory* dirStat = *i;
1923  TDirectory* dir = (TDirectory*) dirStat->Get(dirFullName.c_str());
1924  if (!dir) {
1925  std::cerr << name << ": could not retrieve directory " << dirFullName <<
1926  " from " << dirStat->GetPath() << std::endl;
1927  continue;
1928  }
1929  if (debugLevel >= DEBUG) std::cout << name << ": processing LB folder " << dir->GetPath() << std::endl;
1930  mergeLB_createListOfHistos(dirStat, dir, v_histos, debugLevel);
1931  }
1932 
1933  if (v_histos.size() == 0) {
1934  if (debugLevel >= DEBUG) std::cout << name << ": no objects found" << std::endl;
1935  continue;
1936  }
1937 
1938  TDirectory* dir_out = (TDirectory*) dir_merged->Get(dirFullName.c_str());
1939  if (!dir_out) {
1940  std::cerr << name << ": could not retrieve directory " << dirFullName <<
1941  " from " << dir_merged->GetPath() << std::endl;
1942  continue;
1943  }
1944 
1945  // create new metadata tree for current merged directory if not already extant
1946  typedef std::map< std::string, MetaData > MetaDataMap_t;
1947  TTree* mdTree = dynamic_cast<TTree*>(dir_out->Get("metadata"));
1948  if (!mdTree) {
1949  mdTree = new TTree("metadata", "Monitoring Metadata");
1950  }
1951  mdTree->SetDirectory(0);
1952  OutputMetadata outputmd(mdTree);
1953 
1954  // get metadata from one of the input directories
1955  // this is for caching, could also read the metadata directly from tree in the
1956  // current directory when accessing the histogram
1957  MetaDataMap_t mdMap;
1958  TDirectory* dir_in = (TDirectory*) v_dirsStat[0]->Get(dirFullName.c_str());
1959  if (!dir_in) {
1960  std::cerr << name << ": could not retrieve directory " << dirFullName <<
1961  " from " << v_dirsStat[0]->GetPath() << std::endl;
1962  continue;
1963  }
1964  fillMetaDataMap(mdMap, dir_in);
1965 
1966  // histogram loop
1967  std::vector<std::string>::const_iterator it_string2;
1968  for (it_string2 = v_histos.begin(); it_string2 != v_histos.end(); ++it_string2) {
1969  std::string histFullName = *it_string2; // something like Jets/Tower/JetP
1970 
1971  TObject* objMerged(0);
1972  std::string mergeType("<default>");
1973  // LB interval loop
1974  bool key_checked = false;
1975  for (i = v_dirsStat.begin(); i != v_dirsStat.end(); ++i) {
1976  // retrieve histogram for current LB interval
1977  TDirectory* dir_current = (*i);
1978  std::unique_ptr<TObject> objThis((TObject*)dir_current->Get(histFullName.c_str()));
1979 
1980  if (!objThis.get()) { // histogram does not exist in this LB interval
1981  continue;
1982  }
1983 
1984  // test if histogram exists already in dir_out
1985  if (!key_checked) {
1986  TKey* test_key = dir_out->FindKey(objThis->GetName());
1987  if (test_key) {
1988  if (debugLevel >= DEBUG) std::cout << name << ": " << dir_out->GetPath() << '/' << objThis->GetName()
1989  << " exists already, not written" << std::endl;
1990  break;
1991  }
1992  key_checked = true;
1993  }
1994 
1995  if (!objMerged) {
1996  // clone the current histogram
1997  objMerged = objThis->Clone();
1998  // retrieve metadata
1999  MetaDataMap_t::iterator mdi = mdMap.find(objThis->GetName());
2000  const MetaData* md(0);
2001  if (mdi != mdMap.end()) {
2002  md = &(mdi->second);
2003  } else {
2004  // it could be that we had just been unlucky (on-demand-booking)
2005  // and this histogram was not available in v_dirsStat[0]
2006  // (or the directory for which we created the map last here).
2007  // remake metadatamap
2008  mdMap.clear();
2009  fillMetaDataMap(mdMap, dir_current);
2010  mdi = mdMap.find(objThis->GetName());
2011  if (mdi != mdMap.end()) {
2012  md = &(mdi->second);
2013  }
2014  }
2015 
2016  if (!md) {
2017  std::cerr << name << ": no metadata for " << histFullName << std::endl;
2018  std::cerr << name << ": => using default merging" << std::endl;
2019  } else {
2020  outputmd.fill(md->name, md->interval, md->chain, md->merge);
2021  mergeType = md->merge;
2022  }
2023  } else {
2024  // objMerged already exists, merge with objThis
2025  // but only if objMerged isn't empty ... otherwise swap
2026  TH1* h = dynamic_cast<TH1*>(objMerged);
2027  if (h && h->GetEntries() == 0 && h->GetSumOfWeights() == 0) {
2028  delete objMerged;
2029  objMerged = objThis->Clone();
2030  } else {
2031  mergeObjs(objMerged, objThis.get(), mergeType, debugLevel);
2032  }
2033  }
2034  //delete objThis;
2035  }
2036 
2037  dir_out->cd();
2038  // write histogram to file and delete it from memory
2039  if (objMerged) {
2040  objMerged->Write();
2041  if (debugLevel >=
2042  DEBUG) std::cout << name << ": wrote " << dir_out->GetPath() << '/' << objMerged->GetName() << std::endl;
2043  delete objMerged;
2044  }
2045  }
2046  // write metadata tree
2047  dir_out->cd();
2048  mdTree->SetDirectory(dir_out);
2049  mdTree->Write(0, kOverwrite);
2050  delete mdTree;
2051  }
2052 
2053  return 0;
2054  }
2055 
2056  void MonitoringFile::buildLBToIntervalMap(std::vector<TDirectory*>& v_dirLBs,
2057  std::vector<TDirectory*>& v_dirsInterval, map_dir_vdir& mapping,
2059  std::vector<std::string> v_splits;
2060  typedef std::vector<std::pair<TDirectory*, std::pair<int, int> > > range_t;
2061  range_t v_ranges;
2062  for (std::vector<TDirectory*>::const_iterator dirit = v_dirsInterval.begin();
2063  dirit != v_dirsInterval.end();
2064  ++dirit) {
2065  std::string dirname((*dirit)->GetName());
2066  std::string corename(dirname.substr(10, std::string::npos));
2067  boost::split(v_splits, corename, boost::algorithm::is_any_of(std::string("-")));
2068  if (v_splits.size() != 2) {
2069  std::cerr << "Unable to properly parse " << (*dirit)->GetName() << std::endl;
2070  continue;
2071  }
2072  if (debugLevel >= DEBUG) std::cout << "Found " << dirname << " "
2073  << v_splits[0] << " "
2074  << v_splits[1] << std::endl;
2075  try {
2076  v_ranges.push_back(std::make_pair(*dirit,
2077  std::make_pair(boost::lexical_cast<int>(v_splits[0]),
2078  boost::lexical_cast<int>(v_splits[1]))));
2079  } catch (boost::bad_lexical_cast& e) {
2080  std::cerr << "Unable to cast to integers: " << v_splits[0] << " "
2081  << v_splits[1] << std::endl;
2082  }
2083  }
2084  for (std::vector<TDirectory*>::const_iterator dirit = v_dirLBs.begin();
2085  dirit != v_dirLBs.end();
2086  ++dirit) {
2087  std::string dirname((*dirit)->GetName());
2088  int lbnum = boost::lexical_cast<int>(dirname.substr(3, std::string::npos));
2089  for (range_t::const_iterator rangeit = v_ranges.begin();
2090  rangeit != v_ranges.end(); ++rangeit) {
2091  if ((*rangeit).second.first <= lbnum && lbnum <= (*rangeit).second.second) {
2092  map_dir_vdir::iterator mapit = mapping.find((*rangeit).first);
2093  if (mapit == mapping.end()) continue;
2094  (*mapit).second.push_back(*dirit);
2095  }
2096  }
2097  }
2098  }
2099 
2100  int MonitoringFile::mergeLB_processLB(std::vector<TDirectory*>& v_dirLBs, std::vector<TDirectory*>& v_dirsInterval,
2102  std::map<TDirectory*, std::vector<TDirectory*> > mapping;
2103  for (std::vector<TDirectory*>::const_iterator dirit = v_dirsInterval.begin();
2104  dirit != v_dirsInterval.end(); ++dirit) {
2105  mapping[*dirit] = std::vector<TDirectory*>();
2106  }
2107  buildLBToIntervalMap(v_dirLBs, v_dirsInterval, mapping, debugLevel);
2108 
2109  for (map_dir_vdir::iterator mapit = mapping.begin();
2110  mapit != mapping.end(); ++mapit) {
2111  mergeLB_processLBinterval((*mapit).second, (*mapit).first, debugLevel);
2112  }
2113 
2114  return 0;
2115  }
2116 
2117  int MonitoringFile::mergeLB_processRun(TDirectory* dir_run, debugLevel_t& debugLevel) {
2118  // get lists of "lowStat_", "medStat_", "higStat_" subdirectories in dir_run
2119  // call mergeLB_processLBinterval for each of these lists
2120  std::string name("mergeLB_processRun");
2121  if (!dir_run) {
2122  std::cerr << name << ": empty pointer to run directory" << std::endl;
2123  return -1;
2124  }
2125 
2126  if (debugLevel >= DEBUG) std::cout << name << ": processing dir " << dir_run->GetName() << std::endl;
2127 
2128  std::vector<TDirectory*> v_dirsLowStat, v_dirsMedStat, v_dirsHigStat,
2129  v_dirsLB;
2130 
2131  TIter next(dir_run->GetListOfKeys());
2132  TKey* key;
2133  while ((key = (TKey*) next())) {
2134  std::string keyClassName(key->GetClassName());
2135  if ((keyClassName.size() > 9) && (keyClassName.substr(0, 10) == "TDirectory")) {
2136  TDirectory* dir = (TDirectory*) dir_run->Get(key->GetName());
2137  if (!dir) {
2138  std::cerr << name << ": could not retrieve " << key->GetName() << " from " << dir_run->GetPath() << std::endl;
2139  continue;
2140  }
2141  std::string dirName(dir->GetName());
2142  if (dirName.substr(0, 3) == "lb_") {
2143  v_dirsLB.push_back(dir);
2144  } else if (dirName.size() > 7) {
2145  if (dirName.substr(0, 8) == "lowStat_") {
2146  v_dirsLowStat.push_back(dir);
2147  } else if (dirName.substr(0, 8) == "medStat_") {
2148  v_dirsMedStat.push_back(dir);
2149  } else if (dirName.substr(0, 8) == "higStat_") {
2150  v_dirsHigStat.push_back(dir);
2151  }
2152  }
2153  }
2154  }
2155 
2156  if (debugLevel >= DEBUG) std::cout << "\n" << name << ": processing LB directories" << std::endl;
2157  if (v_dirsLB.size() > 0) mergeLB_processLB(v_dirsLB, v_dirsLowStat, debugLevel);
2158 
2159  if (debugLevel >= DEBUG) std::cout << "\n" << name << ": processing lowStat directories" << std::endl;
2160  if (v_dirsLowStat.size() > 0) mergeLB_processLBinterval(v_dirsLowStat, dir_run, debugLevel);
2161 
2162  if (debugLevel >= DEBUG) std::cout << "\n" << name << ": processing medStat directories" << std::endl;
2163  if (v_dirsMedStat.size() > 0) mergeLB_processLBinterval(v_dirsMedStat, dir_run, debugLevel);
2164 
2165  if (debugLevel >= DEBUG) std::cout << "\n" << name << ": processing higStat directories" << std::endl;
2166  if (v_dirsHigStat.size() > 0) mergeLB_processLBinterval(v_dirsHigStat, dir_run, debugLevel);
2167 
2168  return 0;
2169  }
2170 
2171  int MonitoringFile::mergeLBintervals(const std::string& inFilename, const std::string& inDebugLevel) {
2172  // open merged file, call mergeLB_processRun for each "run_" directory
2173  // in file, close file
2174  std::string name("mergeLBintervals");
2175 
2177  if (inDebugLevel.empty()) {
2179  } else {
2180  if (inDebugLevel == "DEBUG") debugLevel = DEBUG;
2181  else if (inDebugLevel == "VERBOSE") debugLevel = VERBOSE;
2182  }
2183 
2184  //TFile &f = *(TFile::Open(inFilename.c_str(), "UPDATE")); // does a copy and leaks memory
2185  TFile* f = (TFile::Open(inFilename.c_str(), "UPDATE", inFilename.c_str(), m_fileCompressionLevel));
2186 
2187  TIter next(f->GetListOfKeys());
2188  TKey* key;
2189  while ((key = (TKey*) next())) {
2190  std::string keyClassName(key->GetClassName());
2191  if ((keyClassName.size() > 9) && (keyClassName.substr(0, 10) == "TDirectory")) {
2192  TDirectory* dir = (TDirectory*) f->Get(key->GetName());
2193  if (!dir) {
2194  std::cerr << name << ": could not retrieve " << key->GetName()
2195  << " from top level directory of " << inFilename << std::endl;
2196  continue;
2197  }
2198  std::string dirName(dir->GetName());
2199  if ((dirName.size() > 3) && (dirName.substr(0, 4) == "run_")) {
2200  if (debugLevel == DEBUG) std::cout << name << ": found run dir " << dirName << std::endl;
2201  // process this run
2203  }
2204  }
2205  }
2206 
2207  f->Close();
2208  return 0;
2209  }
2210 
2211  bool
2213  CheckHistogram(TFile* f, const char* HistoName) {
2214  std::unique_ptr<TObject> obj(f->Get(HistoName));
2215  if (!obj.get()) {
2216  //std::cerr<<"No such histogram \""<< HistoName << "\"\n";
2217  return false;
2218  } else return true;
2219  }
2220 
2223  std::atomic<int> MonitoringFile::m_fileCompressionLevel = 1;
2224  std::atomic<int> MonitoringFile::m_debugLevel = 0;
2225 
2226  std::string MonitoringFile::getPath(TDirectory* dir) {
2227  std::string path = dir->GetPath();
2228  if (path.find(':') != std::string::npos) path = path.substr(path.rfind(':') + 1);
2229 
2230  return path;
2231  }
2232 } // namespace dqutils
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
dqutils::MonitoringFile::merge_effAsPerCentAlt
static void merge_effAsPerCentAlt(TH1 &a, const TH1 &b)
Definition: MonitoringFile_MergeAlgs.cxx:212
dqutils::MonitoringFile::getAllDirs
static void getAllDirs(DirMap_t &dirmap, TDirectory *dir, const std::string &dirName)
HanApp.h
python.CaloRecoConfig.f
f
Definition: CaloRecoConfig.py:127
dqutils::MonitoringFile::copyHistograms
virtual bool copyHistograms(const std::string &outFileName, const std::string &dirName="all")
Copy the indicated set of histograms to an output file.
dqutils::MonitoringFile::VERBOSE
@ VERBOSE
Definition: MonitoringFile.h:425
checkFileSG.line
line
Definition: checkFileSG.py:75
ReadCellNoiseFromCool.name1
name1
Definition: ReadCellNoiseFromCool.py:233
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
dqutils::MonitoringFile::mergeObjs
static int mergeObjs(TObject *, TObject *, const std::string &, debugLevel_t debugLevel=none)
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:126
runLayerRecalibration.chain
chain
Definition: runLayerRecalibration.py:175
dqutils::MonitoringFile::createDir
static TDirectory * createDir(DirMap_t &dirmap, TDirectory *dir, const std::string &parent, const std::string &path)
dqutils::MonitoringFile
Definition: MonitoringFile.h:54
run.infile
string infile
Definition: run.py:13
dqutils::MonitoringFile::setDebugLevel
static void setDebugLevel(int level)
FullCPAlgorithmsTest_eljob.flush
flush
Definition: FullCPAlgorithmsTest_eljob.py:168
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
dqutils::MonitoringFile::GatherNames::GatherNames
GatherNames()
dqutils::MonitoringFile::CheckHistogram
static bool CheckHistogram(TFile *f, const char *HistoName)
rootconvert.fName
string fName
Definition: rootconvert.py:5
TestSUSYToolsAlg.inputDir
string inputDir
Definition: TestSUSYToolsAlg.py:76
dqutils::MonitoringFile::printHanConfig
virtual void printHanConfig()
dqutils::MonitoringFile::CopyHistogram::execute
virtual bool execute(TH1 *hist)
hist_file_dump.d
d
Definition: hist_file_dump.py:137
plotmaker.hist
hist
Definition: plotmaker.py:148
Epos_Base_Fragment.inputFiles
string inputFiles
Definition: Epos_Base_Fragment.py:18
dqutils::MonitoringFile::merge_effAsPerCent
static void merge_effAsPerCent(TH2 &a, const TH2 &b)
Definition: MonitoringFile_MergeAlgs.cxx:64
dqutils::MonitoringFile::m_mergeMatchDirREString
std::string m_mergeMatchDirREString
Definition: MonitoringFile.h:447
skel.it
it
Definition: skel.GENtoEVGEN.py:423
dqutils::MonitoringFile::merge_lowerLB
static void merge_lowerLB(TH1 &a, const TH1 &b)
Definition: MonitoringFile_MergeAlgs.cxx:647
dirname
std::string dirname(std::string name)
Definition: utils.cxx:200
dqutils::MonitoringFile::CopyHistogram::executeMD
virtual bool executeMD(TH1 *hist, const MetaData &md)
dqutils::MonitoringFile::CopyHistogram::CopyHistogram
CopyHistogram(TDirectory *target, const std::string &dirName)
dqutils::MonitoringFile::merge_Rebinned
static void merge_Rebinned(TH1 &a, TH1 &b)
Definition: MonitoringFile_MergeAlgs.cxx:478
dqutils::MonitoringFile::getDebugLevel
static int getDebugLevel()
CscCalibQuery.fileList
fileList
Definition: CscCalibQuery.py:330
dqutils::MonitoringFile::clearData
virtual void clearData()
TrigInDetValidation_Base.test
test
Definition: TrigInDetValidation_Base.py:144
dqutils::MonitoringFile::DirMap_t
std::map< std::string, TDirectory * > DirMap_t
Definition: MonitoringFile.h:88
dqutils::MonitoringFile::mergeLB_processLBinterval
static int mergeLB_processLBinterval(std::vector< TDirectory * > &, TDirectory *, debugLevel_t &)
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
python.base_data.hcfg
hcfg
Definition: base_data.py:22
dqutils::MonitoringFile::getObjKey
static TKey * getObjKey(TDirectory *dir, const std::string &path)
dqi::DisableMustClean
Definition: HanUtils.h:30
01SubmitToGrid.mergeType
mergeType
Definition: 01SubmitToGrid.py:34
dqutils::MonitoringFile::CopyHistogram::fillMD
void fillMD(const MetaData &md)
find_tgc_unfilled_channelids.mapping
mapping
Definition: find_tgc_unfilled_channelids.py:17
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
dqutils::MonitoringFile::MonitoringFile
MonitoringFile()
dqutils::keycyclemap
std::map< std::string, std::vector< int > > keycyclemap
Definition: MonitoringFile.h:51
python.iconfTool.models.loaders.level
level
Definition: loaders.py:20
dqutils::MonitoringFile::getHanResults
static std::string getHanResults(const std::string &hanResultsDir, const std::string &input, const std::string &hcfg, const std::string &hcfg_min10, const std::string &hcfg_min30)
dqutils::MonitoringFile::~MonitoringFile
virtual ~MonitoringFile()
PrepareReferenceFile.regex
regex
Definition: PrepareReferenceFile.py:43
LArCellBinning_test.retval
def retval
Definition: LArCellBinning_test.py:112
python.checkMetadata.metadata
metadata
Definition: checkMetadata.py:175
PixelModuleFeMask_create_db.remove
string remove
Definition: PixelModuleFeMask_create_db.py:83
dqutils::MonitoringFile::m_debugLevel
static std::atomic< int > m_debugLevel
Definition: MonitoringFile.h:449
DumpGeoConfig.outFileName
string outFileName
Definition: DumpGeoConfig.py:238
dqutils::MonitoringFile::fillMetaDataMap
static void fillMetaDataMap(std::map< std::string, dqutils::MonitoringFile::MetaData > &mdMap, TDirectory *dir)
dqutils::MonitoringFile::loopOnHistograms
static void loopOnHistograms(HistogramOperation &fcn, TDirectory *dir)
dqutils::MonitoringFile::loopOnHistogramsInMetadata
static bool loopOnHistogramsInMetadata(HistogramOperation &fcn, TDirectory *dir)
Get
T * Get(TFile &f, const std::string &n, const std::string &dir="", const chainmap_t *chainmap=0, std::vector< std::string > *saved=0)
get a histogram given a path, and an optional initial directory if histogram is not found,...
Definition: comparitor.cxx:178
FortranAlgorithmOptions.fileName
fileName
Definition: FortranAlgorithmOptions.py:13
covarianceTool.pathName
pathName
Definition: covarianceTool.py:704
dqutils::MonitoringFile::OutputMetadata::makeBranch
void makeBranch(const char *branchName, const char *branchstr)
dqutils::MonitoringFile::CopyHistogram::~CopyHistogram
virtual ~CopyHistogram()
geometry_dat_to_json.indent
indent
Definition: geometry_dat_to_json.py:18
dqutils::populateKeyMapping
void populateKeyMapping(TDirectory *, keycyclemap &)
fillPileUpNoiseLumi.next
next
Definition: fillPileUpNoiseLumi.py:52
CaloCondBlobAlgs_fillNoiseFromASCII.inputFile
string inputFile
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:17
ParseInputs.gDirectory
gDirectory
Definition: Final2012/ParseInputs.py:133
dqutils::MonitoringFile::OutputMetadata::fill
virtual void fill(const std::string &name, const std::string &interval, const std::string &chain, const std::string &merge)
lumiFormat.i
int i
Definition: lumiFormat.py:92
dqutils::MonitoringFile::m_file
TFile * m_file
Definition: MonitoringFile.h:419
h
python.CaloCondTools.g
g
Definition: CaloCondTools.py:15
dqutils::MonitoringFile::map_dir_vdir
std::map< TDirectory *, std::vector< TDirectory * > > map_dir_vdir
Definition: MonitoringFile.h:427
HanUtils.h
extractSporadic.h
list h
Definition: extractSporadic.py:97
dqutils::MonitoringFile::setHistogramRegEx
bool setHistogramRegEx(const std::string &re)
PlotPulseshapeFromCool.input
input
Definition: PlotPulseshapeFromCool.py:106
dqutils::MonitoringFile::m_mergeMatchHistoREString
std::string m_mergeMatchHistoREString
Definition: MonitoringFile.h:446
getLatestRuns.interval
interval
Definition: getLatestRuns.py:24
generateReferenceFile.files
files
Definition: generateReferenceFile.py:12
calibdata.exception
exception
Definition: calibdata.py:496
dqutils::getOutputDirectory
std::string getOutputDirectory(const std::string &inputDirName, TFile *input, bool has_multiple_runs, std::map< TFile *, std::string > *prefixes)
test_pyathena.parent
parent
Definition: test_pyathena.py:15
dqutils::MonitoringFile::getPath
static std::string getPath(TDirectory *dir)
dqutils::MonitoringFile::mergeLB_processRun
static int mergeLB_processRun(TDirectory *, debugLevel_t &)
SCT_Monitoring::disabled
@ disabled
Definition: SCT_MonitoringNumbers.h:60
dqutils::getInputDirectory
std::string getInputDirectory(const std::string &outputDirName, TFile *input, bool has_multiple_runs, std::map< TFile *, std::string > *prefixes)
DQHistogramMerge.debugLevel
debugLevel
Definition: DQHistogramMerge.py:40
index.currentDir
currentDir
Definition: index.py:37
plotmaker.keyName
keyName
Definition: plotmaker.py:145
dqutils
Definition: CoolMdt.h:76
TH2
Definition: rootspy.cxx:373
fcn
void fcn(int &, double *, double &result, double par[], int)
this is where we write out chi2
Definition: Chi2LJets.cxx:183
skel.allFiles
list allFiles
Definition: skel.GENtoEVGEN.py:762
CscCalibQuery.outputDir
string outputDir
Definition: CscCalibQuery.py:261
dqutils::MonitoringFile::mergeLB_recursiveDirCopy
static int mergeLB_recursiveDirCopy(TDirectory *, TDirectory *, TDirectory *, std::vector< std::string > &, debugLevel_t &)
dqutils::MonitoringFile::none
@ none
Definition: MonitoringFile.h:425
beamspotman.dir
string dir
Definition: beamspotman.py:623
dqutils::MonitoringFile::debugLevel_t
debugLevel_t
Definition: MonitoringFile.h:424
dqt_zlumi_alleff_HIST.lbnum
lbnum
Definition: dqt_zlumi_alleff_HIST.py:106
dqutils::MonitoringFile::merge_RMS
static void merge_RMS(TH1 &a, const TH1 &b)
Definition: MonitoringFile_MergeAlgs.cxx:534
dqutils::MonitoringFile::merge_weightedAverage
static void merge_weightedAverage(TH1 &a, const TH1 &b)
Definition: MonitoringFile_MergeAlgs.cxx:290
dqutils::MonitoringFile::buildLBToIntervalMap
static void buildLBToIntervalMap(std::vector< TDirectory * > &, std::vector< TDirectory * > &, map_dir_vdir &, debugLevel_t &)
dqutils::MonitoringFile::GatherStatistics::GatherStatistics
GatherStatistics(const std::string &dirName)
han
Definition: han.py:1
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
dqutils::MonitoringFile::mergeLB_processLB
static int mergeLB_processLB(std::vector< TDirectory * > &, std::vector< TDirectory * > &, debugLevel_t &)
runegammaMonitoring.isDir
isDir
Definition: runegammaMonitoring.py:37
dqi::HanApp
Definition: HanApp.h:21
dqutils::MonitoringFile::mergeObjsMultiCycles
static void mergeObjsMultiCycles(const std::string &, const std::vector< int > &, TDirectory *, const std::string &, std::unique_ptr< TObject > &)
dqutils::MonitoringFile::dirHasHistogramsInMetadata
static bool dirHasHistogramsInMetadata(TDirectory *dir)
dqutils::MonitoringFile::m_mergeMatchHistoRE
std::regex * m_mergeMatchHistoRE
Definition: MonitoringFile.h:444
dqutils::MonitoringFile::printDirectories
virtual void printDirectories()
dqutils::MonitoringFile::GatherNames::execute
virtual bool execute(TH1 *hist)
dqutils::MonitoringFile::OutputMetadata::OutputMetadata
OutputMetadata(TTree *metadata)
cwd
std::string cwd
Definition: listroot.cxx:38
ALFA_EventTPCnv_Dict::t2
std::vector< ALFA_RawDataContainer_p1 > t2
Definition: ALFA_EventTPCnvDict.h:44
dqutils::MonitoringFile::setDirectoryRegEx
bool setDirectoryRegEx(const std::string &re)
MonitoringFile.h
dqutils::MonitoringFile::DEBUG
@ DEBUG
Definition: MonitoringFile.h:425
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
dqutils::MonitoringFile::mergeLBintervals
static int mergeLBintervals(const std::string &, const std::string &debugLevel="none")
DiTauMassTools::MMCFitMethodV2::shortName
const std::string shortName[MAX]
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:44
h
CondAlgsOpts.found
int found
Definition: CondAlgsOpts.py:101
dqutils::MonitoringFile::mergeDirectory
void mergeDirectory(TDirectory *outputDir, const std::vector< TFile * > &inputFiles, bool has_multiple_runs=false, std::map< TFile *, std::string > *prefixes=0)
dqutils::MonitoringFile::m_fileCompressionLevel
static std::atomic< int > m_fileCompressionLevel
Definition: MonitoringFile.h:450
dqutils::MonitoringFile::merge_identical
static void merge_identical(TH1 &a, const TH1 &b)
Definition: MonitoringFile_MergeAlgs.cxx:694
python.envutil.filelist
filelist
print ("Checking files %s..." % fullfile)
Definition: envutil.py:152
TH1
Definition: rootspy.cxx:268
re
const boost::regex re(r_e)
python.utility.LHE.merge
def merge(input_file_pattern, output_file)
Merge many input LHE files into a single output file.
Definition: LHE.py:17
dqutils::MonitoringFile::mergeFiles
void mergeFiles(const std::string &outFileName, const std::vector< std::string > &files)
dqutils::MonitoringFile::OutputMetadata::m_metadata
TTree * m_metadata
Definition: MonitoringFile.h:78
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
CaloCellTimeCorrFiller.filename
filename
Definition: CaloCellTimeCorrFiller.py:24
python.base_data.hanResultsDir
hanResultsDir
Definition: base_data.py:32
dqutils::MonitoringFile::FindCommon
virtual std::string FindCommon(const std::string &name1, const std::string &name2) const
checkFileSG.fi
fi
Definition: checkFileSG.py:65
dqutils::MonitoringFile::GatherStatistics::execute
virtual bool execute(TH1 *hist)
ClassImp
ClassImp(dqutils::MonitoringFile) namespace dqutils
Definition: MonitoringFile.cxx:38
dqutils::MonitoringFile::getIndentation
static std::string getIndentation(const std::string &pathName, const std::string &leadingSpace="")
dqt_zlumi_alleff_HIST.eff
int eff
Definition: dqt_zlumi_alleff_HIST.py:113
python.Bindings.keys
keys
Definition: Control/AthenaPython/python/Bindings.py:790
dqutils::MonitoringFile::printStatistics
virtual void printStatistics()
dqt_zlumi_alleff_HIST.tl
tl
Definition: dqt_zlumi_alleff_HIST.py:73
dqutils::MonitoringFile::merge_perBinEffPerCent
static void merge_perBinEffPerCent(TH1 &a, const TH1 &b)
Definition: MonitoringFile_MergeAlgs.cxx:126
dqutils::MonitoringFile::mergeLB_createListOfHistos
static int mergeLB_createListOfHistos(TDirectory *, TDirectory *, std::vector< std::string > &, debugLevel_t &)
dqutils::MonitoringFile::m_useRE
bool m_useRE
Definition: MonitoringFile.h:448
COOLRates.target
target
Definition: COOLRates.py:1106
collisions.reader
reader
read the goodrunslist xml file(s)
Definition: collisions.py:22
python.LumiCalcRecover.subdir
subdir
Definition: LumiCalcRecover.py:25
test_pyathena.counter
counter
Definition: test_pyathena.py:15
dqBeamSpot.nEntries
int nEntries
Definition: dqBeamSpot.py:73
python.PyAthena.obj
obj
Definition: PyAthena.py:135
dqutils::MonitoringFile::merge_weightedEff
static void merge_weightedEff(TH1 &a, const TH1 &b)
Definition: MonitoringFile_MergeAlgs.cxx:401
PrepareReferenceFile.outfile
outfile
Definition: PrepareReferenceFile.py:42
python.compressB64.c
def c
Definition: compressB64.py:93
length
double length(const pvec &v)
Definition: FPGATrackSimLLPDoubletHoughTransformTool.cxx:26
dqutils::MonitoringFile::setFile
virtual bool setFile(const std::string &fileName)
Clears all previous data and opens the file with the given name for analysis, returning a boolean ind...
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
dqutils::MonitoringFile::merge_RMSpercentDeviation
static void merge_RMSpercentDeviation(TH1 &a, const TH1 &b)
Definition: MonitoringFile_MergeAlgs.cxx:589
merge
Definition: merge.py:1
dqutils::MonitoringFile::setListFromFile
static bool setListFromFile(std::vector< std::string > &filelist, const std::string &listFileName)
dqutils::MonitoringFile::merge_eventSample
static void merge_eventSample(TH2 &a, const TH2 &b)
Definition: MonitoringFile_MergeAlgs.cxx:497
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
dqutils::MonitoringFile::m_mergeMatchDirRE
std::regex * m_mergeMatchDirRE
Definition: MonitoringFile.h:445