42 bool histOKToMerge(TH1*
h) {
43 Long_t arrsize, computedsize;
45 switch (
h->GetDimension()) {
47 computedsize =
h->GetNbinsX() + 2;
51 computedsize = (
h->GetNbinsX() + 2) * (
h->GetNbinsY() + 2);
55 computedsize = (
h->GetNbinsX() + 2) * (
h->GetNbinsY() + 2) * (
h->GetNbinsZ() + 2);
59 std::cerr <<
"Unable to handle dimension of " <<
h->GetName() <<
"; refusing to merge";
62 TArray* arrptr =
dynamic_cast<TArray*
>(
h);
64 std::cerr <<
"Unable to cast TH1 to TArray for " <<
h->GetName() <<
" - saying it's OK and hoping for the best" <<
68 arrsize = arrptr->GetSize();
69 if (computedsize != arrsize) {
70 std::cout <<
"Sizes: computed " << computedsize <<
" array " << arrsize << std::endl;
72 return computedsize == arrsize;
79 MonitoringFile::OutputMetadata::
82 makeBranch(
"Name",
"Name/C");
83 makeBranch(
"Interval",
"Interval/C");
84 makeBranch(
"TriggerChain",
"TriggerChain/C");
85 makeBranch(
"MergeMethod",
"MergeMethod/C");
89 MonitoringFile::OutputMetadata::
90 makeBranch(
const char* branchName,
const char* branchstr) {
91 if (!m_metadata->GetBranch(branchName)) {
92 m_metadata->Branch(branchName, (
void*)
nullptr, branchstr);
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;
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());
115 :
m_file(0), m_mergeMatchHistoRE(0), m_mergeMatchDirRE(0),
116 m_mergeMatchHistoREString(
".*"), m_mergeMatchDirREString(
".*") {
118 m_fileCompressionLevel = 1;
119 MonitoringFile::clearData();
123 MonitoringFile(
const std::string&
fileName)
124 :
m_file(0), m_mergeMatchHistoRE(0), m_mergeMatchDirRE(0),
125 m_mergeMatchHistoREString(
".*"), m_mergeMatchDirREString(
".*") {
127 m_fileCompressionLevel = 1;
128 MonitoringFile::clearData();
137 delete m_mergeMatchDirRE;
138 delete m_mergeMatchHistoRE;
141 bool MonitoringFile::setHistogramRegEx(
const std::string&
re) {
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"
154 std::string
test(
"Test String");
155 std::regex_match(
test, *reNew);
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"
165 delete m_mergeMatchHistoRE;
166 m_mergeMatchHistoREString =
re;
167 m_mergeMatchHistoRE = reNew;
173 bool MonitoringFile::setDirectoryRegEx(
const std::string&
re) {
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"
185 std::regex_match(
"Test string", *reNew);
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"
195 delete m_mergeMatchDirRE;
196 m_mergeMatchDirREString =
re;
197 m_mergeMatchDirRE = reNew;
205 getAllDirs(DirMap_t& dirmap, TDirectory*
dir,
const std::string& dirName) {
206 if (
dir == 0)
return;
209 DirMap_t::value_type dirmapVal(dirName,
dir);
210 dirmap.insert(dirmapVal);
213 TIter
next(
dir->GetListOfKeys());
215 while ((
key =
dynamic_cast<TKey*
>(
next())) != 0) {
217 TObject*
obj =
key->ReadObj();
218 TDirectory*
subdir =
dynamic_cast<TDirectory*
>(
obj);
220 std::string subdirName(
subdir->GetName());
221 std::string
fName(
"");
236 createDir(DirMap_t& dirmap, TDirectory*
dir,
const std::string&
parent,
const std::string&
path) {
237 if (
dir == 0)
return 0;
240 DirMap_t::const_iterator diter;
241 std::string::size_type
i =
path.find_first_of(
'/');
242 std::string
fName(
"");
248 if (
i != std::string::npos) {
249 std::string dName(
path, 0,
i);
250 std::string pName(
path,
i + 1, std::string::npos);
253 diter = dirmap.find(
fName);
254 if (diter != dirmap.end()) {
259 dirmap.insert(dirmapVal);
269 diter = dirmap.find(
fName);
270 if (diter != dirmap.end()) {
271 return diter->second;
276 dirmap.insert(dirmapVal);
283 if (
dir == 0)
return 0;
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);
292 key =
dir->FindKey(dName.c_str());
294 TDirectory* subDir =
dynamic_cast<TDirectory*
>(
key->ReadObj());
304 return dir->FindKey(
path.c_str());
308 std::map< TFile*, std::string >* prefixes) {
309 if (!has_multiple_runs) {
310 return outputDirName;
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()) {
322 std::map< TFile*, std::string >* prefixes) {
323 if (!has_multiple_runs) {
326 std::string
retval(inputDirName);
327 if (prefixes->find(
input) == prefixes->end()) {
330 std::string::size_type sepi =
retval.find((*prefixes)[
input]);
331 if (sepi != std::string::npos) {
339 std::string >* prefixes) {
340 if (TClass::GetClass(
key->GetClassName())->InheritsFrom(
"TDirectory")) {
343 return key->GetName();
349 TIter nextKey(
dir->GetListOfKeys());
353 while ((
key =
dynamic_cast<TKey*
>(nextKey())) != 0) {
354 kcmap[
key->GetName()].push_back(
key->GetCycle());
361 void MonitoringFile::mergeObjsMultiCycles(
const std::string& keyname,
362 const std::vector<int>& cycles,
365 std::unique_ptr<TObject>&
obj) {
366 if (cycles.size() == 0) {
370 if (
obj ==
nullptr) {
371 TKey*
key(
dir->GetKey(keyname.c_str(), cycles[0]));
372 obj.reset(
key->ReadObj());
374 TH1*
h =
dynamic_cast<TH1*
>(
obj.get());
375 if (
h && !histOKToMerge(
h)) {
377 std::cerr <<
"WARNING: HISTOGRAM " <<
h->GetName() <<
" IS INTERNALLY INCONSISTENT, NOT MERGING" << std::endl;
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]);
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";
392 TH1*
h =
dynamic_cast<TH1*
>(nextObj.get());
393 if (
h && !histOKToMerge(
h)) {
395 std::cerr <<
"WARNING: HISTOGRAM " <<
h->GetName() <<
" IS INTERNALLY INCONSISTENT, NOT MERGING" << std::endl;
396 (void) nextObj.release();
401 h =
dynamic_cast<TH1*
>(
obj.get());
402 if (
h &&
h->GetEntries() == 0 &&
h->GetSumOfWeights() == 0) {
404 obj.reset(nextObj.release());
407 if (
h && (
obj->IsA() !=
h->IsA())) {
409 std::cerr <<
"WARNING: CHANGE OF CLASS TYPES FOR " <<
h->GetName() <<
", NOT MERGING" << std::endl;
412 MonitoringFile::mergeObjs(
obj.get(),
417 std::cerr <<
"MonitoringFile::mergeObjsMultiCycles(): NULL KEY; corrupt file?" << std::endl;
423 void getListOfKeysWithName(TDirectory*
dir,
const std::string& keyname,
426 TIter keyit(
dir->GetListOfKeys());
428 while ((
key =
dynamic_cast<TKey*
>(keyit())) != 0) {
429 if (keyname ==
key->GetName()) {
435 void populateCycleVector(
const TCollection& source, std::vector<int>&
target) {
437 TIter keyit(&source);
439 while ((
key =
dynamic_cast<TKey*
>(keyit())) != 0) {
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;
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);
467 bool metadataInDir =
false;
468 bool targetDir = !m_useRE;
469 if (m_useRE && (std::regex_search(outputDirName, *m_mergeMatchDirRE))) {
473 TTree* mdTree =
new TTree(
"metadata",
"Monitoring Metadata");
474 mdTree->SetDirectory(0);
475 OutputMetadata outputmd(mdTree);
477 ObjNameSet_t mergedObjs;
480 std::vector<TFile*>::const_iterator inputFilesEnd =
inputFiles.end();
481 for (std::vector<TFile*>::const_iterator
i =
inputFiles.begin();
i != inputFilesEnd; ++
i) {
498 TIter nextKey(
inputDir->GetListOfKeys());
507 key =
inputDir->GetKey(kcit->first.c_str(), kcit->second.back());
509 std::cout <<
"Key " << kcit->first.c_str() <<
";" << kcit->second.back() <<
" not readable" << std::endl;
512 kcit->second.pop_back();
515 if (obji != mergedObjs.end()) {
521 if (m_useRE &&
key->IsFolder()) {
525 if (!targetDir && !
isDir) {
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";
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()))
560 if (!std::regex_search(
keyName, *m_mergeMatchHistoRE)) {
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")) {
577 outputmd.fill(md.name, md.interval, md.chain, md.merge);
579 if (
g && (md.merge !=
"<default>")) {
580 std::cerr <<
"MonitoringFile::mergeDirectory(): "
581 <<
"In directory \"" <<
inputDir->GetPath() <<
"\",\n"
583 <<
" but only default merging implemented for TGraphs\n";
585 if (
t && (md.merge !=
"<default>")) {
586 std::cerr <<
"MonitoringFile::mergeDirectory(): "
587 <<
"In directory \"" <<
inputDir->GetPath() <<
"\",\n"
589 <<
" but only default merging implemented for TTrees\n";
591 if (
e && (md.merge !=
"<default>")) {
592 std::cerr <<
"MonitoringFile::mergeDirectory(): "
593 <<
"In directory \"" <<
inputDir->GetPath() <<
"\",\n"
595 <<
" but only default merging implemented for TEfficiency\n";
598 std::cerr <<
"MonitoringFile::mergeDirectory(): "
599 <<
"In directory \"" <<
inputDir->GetPath() <<
"\",\n"
600 <<
" object \"" <<
keyName <<
"\" has no metadata\n";
605 TTree*
t2 =
t->CloneTree();
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) {
622 std::vector<int> nextCycles;
623 getListOfKeysWithName(nextInputDir, kcit->first, &
tl);
624 populateCycleVector(
tl, nextCycles);
626 mergeObjsMultiCycles(kcit->first, nextCycles,
630 if ((
h =
dynamic_cast<TH1*
>(
obj.get()))) {
635 }
else if ((targetDir) && (
t =
dynamic_cast<TTree*
>(
obj.get()))) {
637 }
else if ((
d =
dynamic_cast<TDirectory*
>(
obj.get()))) {
643 TDirectory* outputSubDir =
outputDir->mkdir(outputSubDirName.c_str(),
d->GetTitle());
644 mergeDirectory(outputSubDir,
inputFiles, has_multiple_runs, prefixes);
646 std::cout <<
"MonitoringFile::mergeDirectory(): "
647 <<
"In directory \"" <<
inputDir->GetPath() <<
"\",\n"
648 <<
" Object \"" <<
key->GetName() <<
"\" will not be merged\n";
664 fillMetaDataMap(std::map<std::string, dqutils::MonitoringFile::MetaData>& mdMap, TDirectory*
dir) {
665 if (
dir == 0)
return;
667 TTree* md =
dynamic_cast<TTree*
>(
dir->Get(
"metadata"));
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");
677 const std::string nameStr(
static_cast<char*
>(i_name.GetAddress()));
678 if (mdMap.find(nameStr) == mdMap.end()) {
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);
697 TH1::AddDirectory(
false);
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;
703 typedef std::vector<TFile*> TFileList_t;
704 typedef std::map<TFile*, std::string> PrefixIgnore_t;
709 std::cerr <<
"MonitoringFile::mergeFiles(): "
710 <<
"Output file not opened\n";
715 PrefixIgnore_t prefix_ignore;
717 std::vector< std::string >::const_iterator filesEnd =
files.end();
718 std::vector< std::string >::const_iterator
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";
728 TList*
keys =
f->GetListOfKeys();
729 if (
keys->GetSize() == 0) {
730 std::cerr <<
"MonitoringFile::mergeFiles(): "
731 <<
"Input file " << *
fi <<
" has no keys!"
736 std::vector< std::string > runkeys;
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);
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"
752 if (runkeys.size() > 0) {
753 prefix_ignore[
f] = runkeys[0];
759 bool has_multiple_runs =
false;
760 std::string prev_key_name(
"");
762 for (PrefixIgnore_t::const_iterator pi_it = prefix_ignore.begin();
763 pi_it != prefix_ignore.end();
765 if (prev_key_name != pi_it->second) {
766 if (prev_key_name ==
"") {
767 prev_key_name = pi_it->second;
769 has_multiple_runs =
true;
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.)"
783 std::cout <<
"Writing file: " <<
outFileName <<
"\n";
784 std::cout <<
"\nWarning messages from merging follow:\n\n";
786 mergeDirectory(
outfile.get(), tfiles, has_multiple_runs, &prefix_ignore);
790 TFileList_t::const_iterator tfilesEnd = tfiles.end();
791 TFileList_t::const_iterator tfi;
792 for (tfi = tfiles.begin(); tfi != tfilesEnd; ++tfi) {
800 std::cout <<
"****************************************\n\n";
806 typedef std::vector< std::string > FileList_t;
808 const unsigned int nFilesAtOnce = 50;
811 bool success = setListFromFile(
allFiles, listFileName);
813 std::cerr <<
"MonitoringFile::mergeFiles(): Cannot merge files\n";
817 if (
allFiles.size() <= nFilesAtOnce) {
822 FileList_t procFiles, tmpIntermediateFiles;
825 FileList_t::const_iterator filesEnd =
allFiles.end();
826 FileList_t::const_iterator
fi =
allFiles.begin();
829 std::string tmpInputFile(
"");
830 std::string tmpOutputFile(
"");
833 while (
fi != filesEnd) {
834 procFiles.push_back(*
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);
881 for (
const auto& tmpFile : tmpIntermediateFiles) {
884 std::cerr <<
"MonitoringFile::mergeFiles; file " << tmpFile <<
" was not deleted.\n";
891 setFile(
const std::string&
fileName) {
894 if (
m_file != 0)
return true;
903 std::cerr <<
"MonitoringFile::printDirectories(): "
904 <<
"No input file is open\n";
910 getAllDirs(indirmap,
m_file,
"");
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";
923 std::cerr <<
"MonitoringFile::printStatistics(): "
924 <<
"No input file is open\n";
930 getAllDirs(indirmap,
m_file,
"");
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;
936 GatherStatistics stat_shift(idirName);
937 GatherStatistics stat_all(idirName);
939 loopOnHistogramsInMetadata(stat_shift, idir->second);
940 loopOnHistograms(stat_all, idir->second);
942 std::cout.setf(std::ios_base::left, std::ios_base::adjustfield);
944 std::cout << idirName <<
" ";
946 std::cout.setf(std::ios_base::right, std::ios_base::adjustfield);
947 std::cout <<
" shift: ";
949 std::cout << stat_shift.m_nHist1D <<
" ";
951 std::cout << stat_shift.m_nHist1DBins <<
" ";
953 std::cout << stat_shift.m_nHist2D <<
" ";
955 std::cout << stat_shift.m_nHist2DBins <<
" ";
957 std::cout << stat_shift.m_nGraph <<
" ";
959 std::cout << stat_shift.m_nGraphPoints <<
" ";
962 std::cout <<
" all: ";
964 std::cout << stat_all.m_nHist1D <<
" ";
966 std::cout << stat_all.m_nHist1DBins <<
" ";
968 std::cout << stat_all.m_nHist2D <<
" ";
970 std::cout << stat_all.m_nHist2DBins <<
" ";
972 std::cout << stat_all.m_nGraph <<
" ";
974 std::cout << stat_all.m_nGraphPoints <<
"\n";
982 copyHistograms(
const std::string&
outFileName,
const std::string& dirName) {
988 std::cerr <<
"MonitoringFile::copyHistograms(): "
989 <<
"No input file is open\n";
997 if (dirName !=
"all") {
1000 std::cerr <<
"MonitoringFile::copyHistograms(): "
1001 <<
"Directory \'" << dirName <<
"\' not found in input file\n";
1005 TDirectory* fromDir =
dynamic_cast<TDirectory*
>(dkey->ReadObj());
1007 DirMap_t::value_type dirmapVal(dirName, fromDir);
1008 indirmap.insert(dirmapVal);
1010 std::cout <<
"Building list of all TDirectories in file...\n" <<
std::flush;
1011 getAllDirs(indirmap,
m_file,
"");
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;
1025 if (!dirHasHistogramsInMetadata(idir->second)) {
1029 reducedmap.insert(*idir);
1035 std::cerr <<
"MonitoringFile::copyHistograms(): "
1036 <<
"Output file not opened\n";
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;
1045 TDirectory* toDir = createDir(outdirmap,
outfile.get(),
"", idirName);
1047 std::cerr <<
"MonitoringFile::copyHistograms(): "
1048 <<
"Directory \'" << idirName <<
"\' not created in output file\n";
1052 CopyHistogram copyFcn(toDir, idirName);
1054 loopOnHistogramsInMetadata(copyFcn, idir->second);
1067 const std::string&
hcfg,
const std::string& hcfg_lowStat,
const std::string& hcfg_medStat) {
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;
1078 std::cerr <<
"MonitoringFile::getHanResults(): "
1079 <<
"Cannot open input file \"" <<
input <<
"\"\n";
1083 std::vector<std::string> run_dirs;
1084 std::vector<std::string> lowStat_dirs;
1085 std::vector<std::string> medStat_dirs;
1087 TIter next_run(
infile->GetListOfKeys());
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);
1121 std::vector<std::string>::const_iterator dirs_end;
1122 std::vector<std::string>::const_iterator
dir;
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);
1132 fileList += han_output_run +
" " + tdir_run_name +
"\n";
1135 dirs_end = lowStat_dirs.end();
1136 for (
dir = lowStat_dirs.begin();
dir != dirs_end; ++
dir) {
1137 const std::string& tdir_minutes_path = *
dir;
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,
"_");
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);
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";
1152 dirs_end = medStat_dirs.end();
1153 for (
dir = medStat_dirs.begin();
dir != dirs_end; ++
dir) {
1154 const std::string& tdir_minutes_path = *
dir;
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,
"_");
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);
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";
1176 std::cerr <<
"MonitoringFile::printHanConfig(): "
1177 <<
"No input file is open\n";
1183 getAllDirs(indirmap,
m_file,
"");
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);
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);
1198 std::cout << idirName <<
"\n";
1199 std::cout << shortPath <<
", " <<
shortName <<
"\n";
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);
1245 return getIndentation(subPath, space);
1252 FindCommon(
const std::string&
name1,
const std::string& name2)
const {
1271 MonitoringFile::CopyHistogram::
1272 CopyHistogram(TDirectory*
target,
const std::string& dirName)
1274 , m_dirName(dirName)
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");
1284 MonitoringFile::CopyHistogram::
1287 m_metadata->SetDirectory(m_target);
1288 m_metadata->Write();
1296 hist->SetDirectory(m_target);
1318 MonitoringFile::CopyHistogram::
1319 fillMD(
const MetaData& md) {
1320 std::string
name(md.name);
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());
1332 MonitoringFile::CopyHistogram::
1333 executeMD(TH1*
hist,
const MetaData& md) {
1335 hist->SetDirectory(m_target);
1344 MonitoringFile::CopyHistogram::
1345 executeMD(TGraph* graph,
const MetaData& md) {
1354 bool MonitoringFile::CopyHistogram::executeMD(TEfficiency*
eff,
const MetaData& md) {
1361 MonitoringFile::GatherStatistics::
1362 GatherStatistics(
const std::string& dirName)
1363 : m_dirName(dirName)
1369 , m_nHist2DBins(0) {
1375 TH2* hist2d =
dynamic_cast<TH2*
>(
hist);
1379 m_nHist2DBins += (hist2d->GetNbinsX() * hist2d->GetNbinsY());
1383 m_nHist1DBins +=
hist->GetNbinsX();
1391 m_nGraphPoints += graph->GetMaxSize();
1398 TH1* h_total =
eff->GetCopyPassedHisto();
1399 TH2* h_total2D =
dynamic_cast<TH2*
>(h_total);
1401 if (h_total2D != 0) {
1402 m_nEfficiencyBins += (h_total2D->GetNbinsX() * h_total2D->GetNbinsY());
1405 m_nEfficiencyBins += h_total->GetNbinsX();
1410 MonitoringFile::GatherNames::
1417 m_names.push_back(std::string(
hist->GetName()));
1424 m_names.push_back(std::string(graph->GetName()));
1429 m_names.push_back(std::string(
eff->GetName()));
1441 m_fileCompressionLevel = 1;
1442 delete m_mergeMatchHistoRE;
1443 delete m_mergeMatchDirRE;
1444 m_mergeMatchHistoREString =
".*";
1445 m_mergeMatchDirREString =
".*";
1446 m_mergeMatchHistoRE =
new std::regex(m_mergeMatchHistoREString);
1447 m_mergeMatchDirRE =
new std::regex(m_mergeMatchDirREString);
1453 dirHasHistogramsInMetadata(TDirectory*
dir) {
1456 TKey* mdKey =
dir->FindKey(
"metadata");
1461 TTree* md =
dynamic_cast<TTree*
>(mdKey->ReadObj());
1474 std::cerr <<
"Exception: \"" <<
e.what() <<
"\" in directory \""
1488 loopOnHistograms(HistogramOperation&
fcn, TDirectory*
dir) {
1489 TIter
next(
dir->GetListOfKeys());
1492 while ((
key =
dynamic_cast<TKey*
>(
next())) != 0) {
1493 TObject*
obj =
key->ReadObj();
1497 if ((
h =
dynamic_cast<TH1*
>(
obj))) {
1499 }
else if ((
g =
dynamic_cast<TGraph*
>(
obj))) {
1501 }
else if ((
e =
dynamic_cast<TEfficiency*
>(
obj))) {
1510 loopOnHistogramsInMetadata(HistogramOperation&
fcn, TDirectory*
dir) {
1512 TKey* mdKey =
dir->FindKey(
"metadata");
1517 TTree* md =
dynamic_cast<TTree*
>(mdKey->ReadObj());
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");
1531 const std::string nameStr(
static_cast<char*
>(i_name.GetAddress()));
1533 i_key =
dir->FindKey(
static_cast<char*
>(i_name.GetAddress()));
1535 std::cerr <<
"MonitoringFile::loopOnHistogramsInMetadata(): "
1536 <<
"No \'" << nameStr <<
"\' object found\n";
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);
1546 fcn.executeMD(
h, md);
1548 TGraph*
g =
dynamic_cast<TGraph*
>(
obj);
1550 fcn.executeMD(
g, md);
1563 setListFromFile(std::vector<std::string>&
filelist,
const std::string& listFileName) {
1564 using namespace std;
1568 ifstream listfile(listFileName.c_str());
1570 cerr <<
"MonitoringFile::setListFromFile(): "
1571 <<
"cannot read from file: " << listFileName <<
"\n";
1578 while (getline(listfile,
line)) {
1579 istringstream linestream(
line);
1580 while (linestream.get(
c)) {
1587 linestream.putback(
c);
1590 cerr <<
"MonitoringFile::setListFromFile(): "
1591 <<
"badly formatted line: " <<
line <<
"\n";
1603 int MonitoringFile::mergeObjs(TObject* objTarget, TObject*
obj,
const std::string&
mergeType,
1607 std::string
name(
"mergeObjs");
1609 std::cerr <<
name <<
": empty target object pointer" << std::endl;
1613 std::cerr <<
name <<
": empty object pointer" << std::endl;
1619 ", class = " <<
obj->IsA()->GetName() << std::endl;
1621 TH1*
h = 0, * nextH = 0;
1622 TH2* h2 = 0, * nextH2 = 0;
1630 if ((
h =
dynamic_cast<TH1*
>(objTarget))) {
1633 nextH =
dynamic_cast<TH1*
>(
obj);
1635 std::cerr << objTarget->GetName() <<
" is a TH1, but " <<
obj->GetName() <<
" is not: skip merging" <<
1640 if ((h2 =
dynamic_cast<TH2*
>(objTarget)) && (nextH2 =
dynamic_cast<TH2*
>(nextH))) {
1641 merge_effAsPerCent(*h2, *nextH2);
1643 merge_effAsPerCentAlt(*
h, *nextH);
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") {
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);
1661 merge_RMS(*
h, *nextH);
1662 }
else if (
mergeType ==
"RMSpercentDeviation") {
1663 merge_RMSpercentDeviation(*
h, *nextH);
1665 merge_lowerLB(*
h, *nextH);
1667 merge_identical(*
h, *nextH);
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";
1678 }
else if ((
g =
dynamic_cast<TGraph*
>(objTarget))) {
1680 std::cerr <<
name <<
": TGraph " <<
obj->GetName() <<
" request mergeType = " <<
mergeType
1681 <<
" but only default merging implemented for TGraphs\n";
1683 TGraph* nextG =
dynamic_cast<TGraph*
>(
obj);
1688 }
else if ((
e =
dynamic_cast<TEfficiency*
>(objTarget))) {
1690 std::cerr <<
name <<
": TEfficiency " <<
obj->GetName() <<
" request mergeType = " <<
mergeType
1691 <<
" but only default merging implemented for TEfficiencies.\n";
1693 TEfficiency* nextE =
dynamic_cast<TEfficiency*
>(
obj);
1698 }
else if ((
t =
dynamic_cast<TTree*
>(objTarget))) {
1700 std::cout <<
"Merging Tree " <<
obj->GetName() << std::endl;
1703 std::cerr <<
name <<
": TTree " <<
obj->GetName() <<
" request mergeType = " <<
mergeType
1704 <<
" but only default merging implemented for TTrees\n";
1706 TTree* nextT =
dynamic_cast<TTree*
>(
obj);
1712 std::cerr <<
name <<
": object is not a histogram or graph, merging not implemented" << std::endl;
1717 int MonitoringFile::mergeLB_recursiveDirCopy(TDirectory* dir_top_out, TDirectory* dir_out, TDirectory*
cwd,
1718 std::vector<std::string>& v_dirsSub, debugLevel_t&
debugLevel) {
1721 std::string
name(
"mergeLB_recursiveDirCopy");
1723 std::cerr <<
name <<
": empty directory pointer cwd" << std::endl;
1727 std::cerr <<
name <<
": empty directory pointer dir_top_out" << std::endl;
1731 std::cerr <<
name <<
": empty directory pointer dir_out" << std::endl;
1735 TIter
next(
cwd->GetListOfKeys());
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());
1742 std::cerr <<
name <<
": could not retrieve directory " <<
key->GetName() <<
1743 " from " <<
cwd->GetPath() << std::endl;
1747 std::string p_top(dir_top_out->GetPath());
1749 if (p_top.size() <
p.size()) {
1750 p =
p.substr(p_top.size() + 1,
p.size() - p_top.size() - 1);
1756 for (
it = v_dirsSub.begin();
it != v_dirsSub.end(); ++
it) {
1757 if (*
it == (
p +
dir->GetName()))
break;
1759 if (
it == v_dirsSub.end()) {
1761 v_dirsSub.push_back(
p +
dir->GetName());
1764 TKey* test_key = dir_out->FindKey(
dir->GetName());
1765 TDirectory* dir_out_new(0);
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;
1772 dir_out_new = (TDirectory*)
gDirectory->mkdir(
dir->GetName());
1774 std::cerr <<
name <<
": could not create directory " <<
dir->GetName()
1775 <<
" in " <<
gDirectory->GetPath() << std::endl;
1779 DEBUG) std::cout <<
name <<
": " << dir_out->GetPath() <<
'/' <<
dir->GetName() <<
" exists already" <<
1782 dir_out_new = (TDirectory*) dir_out->Get(test_key->GetName());
1784 std::cerr <<
name <<
": could not retrieve directory " << test_key->GetName()
1785 <<
" from " << dir_out->GetPath() << std::endl;
1789 if (dir_out_new) mergeLB_recursiveDirCopy(dir_top_out, dir_out_new,
dir, v_dirsSub,
debugLevel);
1795 int MonitoringFile::mergeLB_createListOfHistos(TDirectory* dir_top, TDirectory*
cwd,
1796 std::vector<std::string>& v_histos, debugLevel_t&
debugLevel) {
1798 std::string
name(
"mergeLB_createListOfHistos");
1800 std::cerr <<
name <<
": empty directory pointer" << std::endl;
1804 TIter
next(
cwd->GetListOfKeys());
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")))) {
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);
1824 for (
it = v_histos.begin();
it != v_histos.end(); ++
it) {
1825 if (*
it == (
p +
key->GetName()))
break;
1828 if (
it == v_histos.end()) {
1829 std::string objName(
p +
key->GetName());
1830 v_histos.push_back(objName);
1840 int MonitoringFile::mergeLB_processLBinterval(std::vector<TDirectory*>& v_dirsStat, TDirectory* dir_run,
1845 std::string
name(
"mergeLB_processLBinterval");
1847 if (v_dirsStat.size() == 0)
return 0;
1850 std::cerr <<
name <<
": empty pointer dir_run" << std::endl;
1854 if (!v_dirsStat[0]) {
1855 std::cerr <<
name <<
": empty first directory pointer" << std::endl;
1872 TDirectory* dir_merged = dir_run;
1892 std::vector<TDirectory*>::const_iterator
i;
1896 std::vector<std::string> v_dirsSub;
1897 for (
i = v_dirsStat.begin();
i != v_dirsStat.end(); ++
i) {
1898 TDirectory* dirStat = *
i;
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);
1906 if (v_dirsSub.size() == 0) {
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());
1925 std::cerr <<
name <<
": could not retrieve directory " << dirFullName <<
1926 " from " << dirStat->GetPath() << std::endl;
1930 mergeLB_createListOfHistos(dirStat,
dir, v_histos,
debugLevel);
1933 if (v_histos.size() == 0) {
1938 TDirectory* dir_out = (TDirectory*) dir_merged->Get(dirFullName.c_str());
1940 std::cerr <<
name <<
": could not retrieve directory " << dirFullName <<
1941 " from " << dir_merged->GetPath() << std::endl;
1946 typedef std::map< std::string, MetaData > MetaDataMap_t;
1947 TTree* mdTree =
dynamic_cast<TTree*
>(dir_out->Get(
"metadata"));
1949 mdTree =
new TTree(
"metadata",
"Monitoring Metadata");
1951 mdTree->SetDirectory(0);
1952 OutputMetadata outputmd(mdTree);
1957 MetaDataMap_t mdMap;
1958 TDirectory* dir_in = (TDirectory*) v_dirsStat[0]->
Get(dirFullName.c_str());
1960 std::cerr <<
name <<
": could not retrieve directory " << dirFullName <<
1961 " from " << v_dirsStat[0]->GetPath() << std::endl;
1964 fillMetaDataMap(mdMap, dir_in);
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;
1971 TObject* objMerged(0);
1974 bool key_checked =
false;
1975 for (
i = v_dirsStat.begin();
i != v_dirsStat.end(); ++
i) {
1977 TDirectory* dir_current = (*i);
1978 std::unique_ptr<TObject> objThis((TObject*)dir_current->Get(histFullName.c_str()));
1980 if (!objThis.get()) {
1986 TKey* test_key = dir_out->FindKey(objThis->GetName());
1988 if (
debugLevel >=
DEBUG) std::cout <<
name <<
": " << dir_out->GetPath() <<
'/' << objThis->GetName()
1989 <<
" exists already, not written" << std::endl;
1997 objMerged = objThis->Clone();
2000 const MetaData* md(0);
2001 if (mdi != mdMap.end()) {
2002 md = &(mdi->second);
2009 fillMetaDataMap(mdMap, dir_current);
2010 mdi = mdMap.find(objThis->GetName());
2011 if (mdi != mdMap.end()) {
2012 md = &(mdi->second);
2017 std::cerr <<
name <<
": no metadata for " << histFullName << std::endl;
2018 std::cerr <<
name <<
": => using default merging" << std::endl;
2020 outputmd.fill(md->name, md->interval, md->chain, md->merge);
2026 TH1*
h =
dynamic_cast<TH1*
>(objMerged);
2027 if (
h &&
h->GetEntries() == 0 &&
h->GetSumOfWeights() == 0) {
2029 objMerged = objThis->Clone();
2042 DEBUG) std::cout <<
name <<
": wrote " << dir_out->GetPath() <<
'/' << objMerged->GetName() << std::endl;
2048 mdTree->SetDirectory(dir_out);
2049 mdTree->Write(0, kOverwrite);
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;
2062 for (std::vector<TDirectory*>::const_iterator dirit = v_dirsInterval.begin();
2063 dirit != v_dirsInterval.end();
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;
2073 << v_splits[0] <<
" "
2074 << v_splits[1] << std::endl;
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;
2084 for (std::vector<TDirectory*>::const_iterator dirit = v_dirLBs.begin();
2085 dirit != v_dirLBs.end();
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) {
2093 if (mapit ==
mapping.end())
continue;
2094 (*mapit).second.push_back(*dirit);
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*>();
2110 mapit !=
mapping.end(); ++mapit) {
2111 mergeLB_processLBinterval((*mapit).second, (*mapit).first,
debugLevel);
2117 int MonitoringFile::mergeLB_processRun(TDirectory* dir_run, debugLevel_t&
debugLevel) {
2120 std::string
name(
"mergeLB_processRun");
2122 std::cerr <<
name <<
": empty pointer to run directory" << std::endl;
2126 if (
debugLevel >=
DEBUG) std::cout <<
name <<
": processing dir " << dir_run->GetName() << std::endl;
2128 std::vector<TDirectory*> v_dirsLowStat, v_dirsMedStat, v_dirsHigStat,
2131 TIter
next(dir_run->GetListOfKeys());
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());
2138 std::cerr <<
name <<
": could not retrieve " <<
key->GetName() <<
" from " << dir_run->GetPath() << std::endl;
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);
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);
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);
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);
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);
2171 int MonitoringFile::mergeLBintervals(
const std::string& inFilename,
const std::string& inDebugLevel) {
2174 std::string
name(
"mergeLBintervals");
2177 if (inDebugLevel.empty()) {
2185 TFile*
f = (TFile::Open(inFilename.c_str(),
"UPDATE", inFilename.c_str(), m_fileCompressionLevel));
2187 TIter
next(
f->GetListOfKeys());
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());
2194 std::cerr <<
name <<
": could not retrieve " <<
key->GetName()
2195 <<
" from top level directory of " << inFilename << std::endl;
2198 std::string dirName(
dir->GetName());
2199 if ((dirName.size() > 3) && (dirName.substr(0, 4) ==
"run_")) {
2213 CheckHistogram(TFile*
f,
const char* HistoName) {
2214 std::unique_ptr<TObject>
obj(
f->Get(HistoName));
2221 int MonitoringFile::getDebugLevel() {
return m_debugLevel;}
2222 void MonitoringFile::setDebugLevel(
int level) {m_debugLevel =
level;}
2223 std::atomic<int> MonitoringFile::m_fileCompressionLevel = 1;
2224 std::atomic<int> MonitoringFile::m_debugLevel = 0;
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);