57 {
58
59
60
61
62
63HanConfig::
64HanConfig()
65 : m_config(0)
66 , m_dqRoot()
67 , m_top_level(0)
68 , m_metadata(0)
69{
70}
71
72
73HanConfig::
74~HanConfig()
75{
76 delete m_config;
77
78 delete m_top_level;
79 if (m_metadata) m_metadata->Delete();
80 delete m_metadata;
81}
82
83namespace {
84 bool TestMiniNodeIsRegex(
const MiniConfigTreeNode*
node) {
85 std::string regexflag(
node->GetAttribute(
"regex"));
86 boost::algorithm::to_lower(regexflag);
87 if (regexflag == "1" || regexflag == "true" || regexflag == "yes") {
88 return true;
89 }
90 return false;
91 }
92}
93
94void
95HanConfig::
96AssembleAndSave( const std::string & infileName, const std::string & outfileName, const std::string & connectionString, long runNumber, bool bulk)
97{
98 std::unique_ptr< TFile >
outfile( TFile::Open( outfileName.c_str(),
99 "RECREATE" ) );
101
102
103 MiniConfig refconfig;
104 refconfig.AddKeyword("reference");
105 refconfig.ReadFile(infileName);
106 TMap refsourcedata;
107 refsourcedata.SetOwnerKeyValue();
109 refconfig.SendVisitor( refvisitor );
110
111 DatabaseConfig databaseConfig(connectionString, runNumber);
112 RefWriter refwriter(databaseConfig, bulk);
113 refconfig.SendWriter( refwriter );
114 databaseConfig.Disconnect();
115
116
117 MiniConfig thrconfig;
118 thrconfig.AddKeyword("thresholds");
119 thrconfig.AddAttributeKeyword("limits");
120 thrconfig.ReadFile(infileName);
121
122
123 MiniConfig algconfig;
124 algconfig.AddKeyword("algorithm");
125 algconfig.ReadFile(infileName);
126
127
128 MiniConfig regconfig;
129 regconfig.AddKeyword("output");
130 regconfig.ReadFile(infileName);
131
132
133 MiniConfig histconfig;
134 histconfig.AddKeyword("dir");
135 histconfig.AddAttributeKeyword("hist");
136 histconfig.SetAttribKeywordPropagateDown(false);
137 histconfig.ReadFile(infileName);
138
139
140 MiniConfig compalgconfig;
141 compalgconfig.AddKeyword("compositealgorithm");
142 compalgconfig.ReadFile(infileName);
143 CompAlgVisitor compalgvisitor(
outfile.get(), compalgconfig);
144 compalgconfig.SendVisitor(compalgvisitor);
145
146 MiniConfig metadataconfig;
147 metadataconfig.AddKeyword("metadata");
148 metadataconfig.ReadFile(infileName);
149 MetadataVisitor metadatavisitor(
outfile.get(), metadataconfig);
150 metadataconfig.SendVisitor(metadatavisitor);
151
152
154 std::unique_ptr< HanConfigGroup >
root(
new HanConfigGroup() );
155
156 RegionVisitor regvisitor(
root.get(), algconfig, thrconfig, refconfig,
directories );
157 regconfig.SendVisitor( regvisitor );
158
159 AssessmentVisitor histvisitor(
root.get(), algconfig, thrconfig, refconfig,
outfile.get(),
161 histconfig.SendVisitor( histvisitor );
162
163 outfile->WriteTObject(&refsourcedata,
"refsourcedata");
168}
169
170void
171HanConfig::
172BuildMonitors( std::string configName, HanInputRootFile& input, HanOutput& output )
173{
174 bool isInitialized =
Initialize( configName );
175 if( !isInitialized ) {
176 return;
177 }
178
179 m_dqRoot = BuildMonitorsNewRoot( std::move(configName), input, output );
180
182}
183
184boost::shared_ptr<dqm_core::Region>
185HanConfig::
186BuildMonitorsNewRoot( std::string configName, HanInputRootFile& input, dqm_core::Output& output )
187{
188 bool isInitialized =
Initialize( configName );
189 if( !isInitialized ) {
190 return boost::shared_ptr<dqm_core::Region>();
191 }
192
193 TDirectory* topdir =
const_cast<TDirectory*
>(
input.getBasedir());
194 TPython::Bind(m_config, "config");
195 TPython::Bind(m_top_level, "top_level");
196 TPython::Bind(topdir, "path");
197 TPython::Exec("from DataQualityInterfaces.han import FixRegion, logLevel");
198 const char* debugflag = std::getenv("HANDEBUG");
199 if (!debugflag) {
200 TPython::Exec("logLevel('INFO')");
201 } else {
202 TPython::Exec("logLevel('DEBUG')");
203 }
204
205#if ROOT_VERSION_CODE >= ROOT_VERSION(6,33,01)
207 TPython::Exec (
"_anyresult = ROOT.std.make_any['dqi::HanConfigGroup'](FixRegion(config, top_level, path))", &
result);
209#else
210 HanConfigGroup* new_top_level = TPython::Eval("FixRegion(config, top_level, path)");
211#endif
212 delete m_top_level;
213 m_top_level = new_top_level;
214
215 std::string
algName( m_top_level->GetAlgName() );
216 std::string algLibName( m_top_level->GetAlgLibName() );
217 if( algLibName != "" ) {
218 try {
219 dqm_core::LibraryManager::instance().loadLibrary( algLibName );
220 }
221 catch ( dqm_core::Exception& ex ) {
222
223 }
224 }
225 dqm_core::RegionConfig regc( algName, 1.0 );
226 boost::shared_ptr<dqm_core::Region>
retval(dqm_core::Region::createRootRegion(
"top_level", input, output, regc ));
227
228 ConfigVisitor confvisitor( m_config, &output );
229 m_top_level->Accept( confvisitor, retval );
231}
232
233void
234HanConfig::
235BuildConfigOutput( std::string configName, TFile* inputFile, const std::string & path,
236 HanOutput::DQOutputMap_t* outputMap, TSeqCollection* outputList )
237{
238 bool isInitialized =
Initialize( configName );
239 if( !isInitialized ) {
240 return;
241 }
242
243 if( inputFile == 0 ) {
244 return;
245 }
246
247 TDirectory* basedir(0);
248 if( path != "" ) {
249 std::string pathForSearch =
path +
"/dummyName";
250 basedir = ChangeInputDir( inputFile, std::move(pathForSearch) );
251 }
252
253 if( basedir == 0 )
255
256 TIter mdIter(m_metadata);
257 TSeqCollection* mdList =
newTList(
"HanMetadata_");
258 HanConfigMetadata* md(0);
259 while ((md = dynamic_cast<HanConfigMetadata*>(mdIter()))) {
260 mdList->Add( md->GetList(basedir,*outputMap) );
261 }
262 TSeqCollection* top_level_list = m_top_level->GetList(basedir,*outputMap);
263 top_level_list->Add( mdList );
264 outputList->Add( top_level_list );
265}
266
267
268TObject*
269HanConfig::
270GetReference( std::string& groupName, std::string& name )
271{
272
273
274
275
276
277
278
279
280
281 std::unique_ptr<const HanConfigAssessor>
a(GetAssessor( groupName, name ));
282 if (!
a.get())
return 0;
283 std::string refName(
a->GetAlgRefName() );
284 if( refName != "" ) {
286 if( key != 0 ) {
287
288 TObject*
ref =
key->ReadObj();
291 }
292 }
293
294 return 0;
295}
296
297std::string
298SplitReference(std::string refPath, const std::string& refName )
299{
300
301 static std::map<std::string, std::string> mappingCache;
302
303
304 std::vector<std::string> refFileDirList;
305 boost::split(refFileDirList, refPath, boost::is_any_of(","));
306
307
308 std::vector<std::string> refFileList;
309 for (const auto& dir : refFileDirList ) {
310 refFileList.push_back(boost::algorithm::trim_copy(dir+refName));
311 }
312
313
314 std::string tfilestring = boost::algorithm::join(refFileList, "|");
315
316 const auto& cachehit = mappingCache.find(tfilestring);
317 if (cachehit != mappingCache.end()) {
318 return cachehit->second;
319 }
320
321 if (const auto* f = TFile::Open(tfilestring.c_str())) {
322 mappingCache[tfilestring] =
f->GetName();
323 } else {
324 std::cerr << "Unable to open any reference files in " << tfilestring << ", reference will not be included" << std::endl;
325 mappingCache[tfilestring] = "";
326 }
327 return mappingCache[tfilestring];
328}
329
330const HanConfigAssessor*
331HanConfig::
332GetAssessor( std::string& groupName, std::string& name ) const
333{
334 if( m_top_level == 0 ) {
335 return 0;
336 }
337
338 HanConfigGroup*
parent = m_top_level->GetNode(groupName);
339 if( parent == 0 ) {
341 }
342
343 const HanConfigAssessor&
a =
parent->GetAssessor(name);
344
345 return new HanConfigAssessor(
a);
346}
347
348void
349HanConfig::
350GetRegexList(std::set<std::string>& regexlist)
351{
352 RegexVisitor
rv(regexlist);
353 m_top_level->Accept(rv, boost::shared_ptr<dqm_core::Region>());
354}
355
356
357
358
359
360HanConfig::RefVisitor::
361RefVisitor( TFile* outfile_, HanConfig::DirMap_t& directories_, TMap* refsourcedata_ )
362 : m_outfile(outfile_)
363 , m_directories(directories_)
364 , m_refsourcedata(refsourcedata_)
365{
366}
367
368
369void
370HanConfig::RefVisitor::
371Visit(
const MiniConfigTreeNode*
node )
372{
374 std::string
name =
node->GetAttribute(
"name");
376 if( fileName != "" && name != "" && name != "same_name" ) {
377 fileName = SplitReference(
node->GetAttribute(
"location"), fileName);
378 std::string refInfo =
node->GetAttribute(
"info");
379 if (refInfo == "") {
380 std::cerr <<
"INFO: Reference " <<
name <<
" is defined without an \"info\" attribute. Consider adding one"
381 << std::endl;
382 }
385 if( key == 0 ) {
386 std::cerr <<
"WARNING: HanConfig::RefVisitor::Visit(): Reference not found: \"" <<
name <<
"\"\n";
387 return;
388 }
389
390
391
392 m_outfile->cd();
394
396
397
399 obj->Write(newHistoName.c_str());
401 TObjString* fnameostr =
new TObjString(
fileName.c_str());
402 m_refsourcedata->Add(new TObjString(newHistoName.c_str()),
403 fnameostr);
404 if (! m_refsourcedata->FindObject(
fileName.c_str())) {
405 m_refsourcedata->Add(fnameostr->Clone(), refInfo != "" ? new TObjString(refInfo.c_str())
406 : new TObjString("Reference"));
407 }
408 }
409}
410
411HanConfig::RefWriter::
412RefWriter( DatabaseConfig& databaseConfig_, const bool bulk)
413 : m_databaseConfig(databaseConfig_),
414 m_bulk(bulk)
415{
416}
417
418
419void
420HanConfig::RefWriter::
421Write( MiniConfigTreeNode*
node )
422{
424
425 if(database != "") {
426 database += (m_bulk ?
"-physics-UPD4" :
"-express-UPD1");
427 nlohmann::json jsonPayload = m_databaseConfig.GetPayload(database);
429
430 if(jsonPayload.find(
reference) != jsonPayload.end()) {
431 nlohmann::json referenceJson = jsonPayload[std::move(
reference)];
432 for (nlohmann::json::iterator it = referenceJson.begin(); it != referenceJson.end(); ++it) {
433 node->SetAttribute(
it.key(),
it.value(),
false);
434 }
435 } else {
436 std::cerr <<
"Unable to find reference definition in database: " <<
reference <<
'\n';
437 }
438 }
439}
440
441HanConfig::AssessmentVisitorBase::
442AssessmentVisitorBase( HanConfigGroup* root_, const MiniConfig& algConfig_,
443 const MiniConfig& thrConfig_, const MiniConfig& refConfig_,
444 TFile* outfile_, HanConfig::DirMap_t& directories_,
445 TMap* refsourcedata_ )
446 : m_root(root_)
447 , m_algConfig(algConfig_)
448 , m_thrConfig(thrConfig_)
449 , m_refConfig(refConfig_)
450 , m_outfile(outfile_)
451 , m_directories(directories_)
452 , m_refsourcedata(refsourcedata_)
453{
454}
455
456std::shared_ptr<TFile>
457HanConfig::AssessmentVisitorBase::
458GetROOTFile( std::string& fname )
459{
460 auto it = m_filecache.find(fname);
461 if (it !=
end(m_filecache)) {
463 } else {
464 if (m_badPaths.find(fname) != m_badPaths.end()) {
465 return std::shared_ptr<TFile>(nullptr);
466 }
467 std::shared_ptr<TFile> thisptr(TFile::Open(
fname.c_str()));
468 if (thisptr.get()) {
469 return ( m_filecache[fname] = std::move(thisptr) );
470 } else {
471 m_badPaths.insert(fname);
472 return thisptr;
473 }
474 }
475}
476
477void
478HanConfig::AssessmentVisitorBase::
479PopulateKeyCache(
const std::string& fname, std::shared_ptr<TFile> &
file) {
482}
483
484void
485HanConfig::AssessmentVisitorBase::
486EnsureKeyCache(std::string& fname) {
487 DisableMustClean dmc;
488 auto file = GetROOTFile(fname);
490 if (m_keycache.find(fname) != m_keycache.end()) {
491 return;
492 } else {
493 m_keycache[
fname].reserve(100000);
494 PopulateKeyCache(fname,
file);
495 }
496 }
497}
498
499float AttribToFloat(
const MiniConfigTreeNode*
node,
const std::string& attrib,
500 const std::string& warningString, bool local=false)
501{
502 std::istringstream valstream;
503 if (local) {
504 valstream.str(
node->GetAttributeLocal(attrib));
505 } else {
506 valstream.str(
node->GetAttribute(attrib));
507 }
510 if (! valstream) {
511 std::cerr << warningString << std::endl;
512 return 0;
513 } else {
515 }
516}
517
518void
519HanConfig::AssessmentVisitorBase::
520GetAlgorithmConfiguration( HanConfigAssessor* dqpar, const std::string& algID,
521 const std::string& assessorName )
522{
523
524 std::set<std::string> algAtt;
525 m_algConfig.GetAttributeNames( algID, algAtt );
526 std::set<std::string>::const_iterator algAttEnd = algAtt.end();
527 for( std::set<std::string>::const_iterator i = algAtt.begin(); i != algAttEnd; ++i ) {
528 std::string trail("");
529 std::string::size_type
pos = (*i).find(
'|');
530 if (pos != std::string::npos) {
531 trail = (*i).substr(pos + 1, std::string::npos);
532 }
533 if( *i == "name" ) {
534
535 std::string
algName( m_algConfig.GetStringAttribute(algID,
"name") );
536 dqpar->SetAlgName( std::move(algName) );
537 }
538 else if( *i == "libname" ) {
539 std::string algLibName( m_algConfig.GetStringAttribute(algID,"libname") );
540 dqpar->SetAlgLibName( std::move(algLibName) );
541 }
542 else if( *i == "thresholds" || trail == "thresholds" ) {
543 std::string thrID( m_algConfig.GetStringAttribute(algID,*i) );
544 std::set<std::string> thrAtt;
545 m_thrConfig.GetAttributeNames( thrID, thrAtt );
546 std::set<std::string>::const_iterator thrAttEnd = thrAtt.end();
547 for( std::set<std::string>::const_iterator t = thrAtt.begin(); t != thrAttEnd; ++t ) {
548 std::string thrAttName = *
t;
549 std::string thrAttVal = m_thrConfig.GetStringAttribute( thrID, thrAttName );
550 std::string limName = thrAttVal + std::string("/") + thrAttName;
551 HanConfigAlgLimit algLim;
552 if (pos != std::string::npos) {
553 algLim.SetName( (*i).substr(0, pos) + std::string("|") + *t );
554 } else {
555 algLim.SetName( *t );
556 }
557 algLim.SetGreen( m_thrConfig.GetFloatAttribute(limName,"warning") );
558 algLim.SetRed( m_thrConfig.GetFloatAttribute(std::move(limName),"error") );
559 dqpar->AddAlgLimit( algLim );
560 }
561 }
562 else if( *i == "reference" ) {
563
564
565
566 std::string tmpRefID=m_algConfig.GetStringAttribute(algID,"reference");
567
569
571 std::stringstream newRefString;
572
573 for(
size_t t=0;
t<condPairs.size();
t++){
574 bool refsuccess(false);
575 std::string refID=condPairs.at(t).second;
576 std::string cond=condPairs.at(t).first;
577 std::vector<std::string> refIDVec;
578
579 std::vector<std::vector<std::pair<std::string, std::shared_ptr<TObject>>>>
objects;
580 std::string newRefId("");
581 bool isMultiRef(false);
582 std::vector<std::string> sourceMatches;
583 if (refID[0] == '[') {
584 std::string cleanedRefID = refID;
585 boost::algorithm::trim_if(cleanedRefID, boost::is_any_of("[] "));
586 isMultiRef = true;
587 boost::split(refIDVec, cleanedRefID, boost::is_any_of(","));
588
589
590 } else {
591 refIDVec.push_back(refID);
592 }
593
594
595
596 std::string algRefName( m_refConfig.GetStringAttribute(refID,"name") );
597 std::string algRefInfo( m_refConfig.GetStringAttribute(refID,"info") );
598 std::string algRefFile( m_refConfig.GetStringAttribute(refID,"file") );
599 if (algRefName != "same_name" && !isMultiRef) {
601
602 if(newRefId.empty()){
603 std::string algRefPath( m_refConfig.GetStringAttribute(refID,"path") );
604 std::cerr<<"Warning New reference id is empty for refId=\""
605 <<refID<<"\", cond=\""<<cond<<"\", assessorName=\""
606 <<assessorName<<"\", algRefName=\""
607 <<algRefName<<"\""<<std::endl;
608 std::cerr << "AlgRefPath=" << algRefPath << " AlgRefInfo=" << algRefInfo << std::endl;
609 } else {
610 refsuccess = true;
611 }
612 } else {
613
614 objects.resize(refIDVec.size());
615 std::string absAlgRefName, algRefPath, algRefInfo;
616 for (size_t iRefID = 0; iRefID < refIDVec.size(); ++iRefID) {
617 const auto& thisRefID = refIDVec[iRefID];
618 algRefName = m_refConfig.GetStringAttribute(thisRefID,"name");
619 algRefPath = m_refConfig.GetStringAttribute(thisRefID,"path");
620 algRefInfo = m_refConfig.GetStringAttribute(thisRefID,"info");
621 algRefFile = m_refConfig.GetStringAttribute(thisRefID,"file");
622 if (algRefInfo == "") {
623 std::cerr << "INFO: Reference " << thisRefID << " is defined without an \"info\" attribute. Consider adding one"
624 << std::endl;
625 }
626 absAlgRefName = "";
627 if( algRefPath != "" ) {
628 absAlgRefName += algRefPath;
629 absAlgRefName += "/";
630 }
631 if( algRefName == "same_name" ) {
632 algRefName = assessorName;
633 absAlgRefName += algRefName;
634 algRefFile = SplitReference( m_refConfig.GetStringAttribute(thisRefID,"location"), algRefFile);
635
636 if( algRefFile != "" ) {
637 std::shared_ptr<TFile>
infile = GetROOTFile(algRefFile);
639 std::cerr << "HanConfig::AssessmentVistorBase::GetAlgorithmConfiguration: Reference file " << algRefFile << " not found" << std::endl;
640 continue;
641 }
642 std::vector<std::string> localMatches;
643 if (
dqpar->GetIsRegex()) {
644 if (! sourceMatches.empty()) {
645 std::cerr << "same_name appears twice in a reference request???" << std::endl;
646 } else {
647
648 std::string regexPattern = boost::regex_replace(absAlgRefName, boost::regex("\\(\\?P=([^)]*)\\)"), "\\\\k<\\1>", boost::format_all);
649 boost::regex
re(boost::replace_all_copy(regexPattern,
"(?P",
"(?"));
650 EnsureKeyCache(algRefFile);
651 for (const auto& iKey: m_keycache[algRefFile]) {
652 if (boost::regex_match(iKey,
re)) {
653 sourceMatches.push_back(iKey);
655 m_outfile->cd();
656 objects[iRefID].emplace_back(iKey,
key->ReadObj());
657 }
658 }
659 }
660 } else {
662 if( key == 0 ) {
663
664 continue;
665 }
666 m_outfile->cd();
667 std::shared_ptr<TObject>
q(
key->ReadObj());
668 objects[iRefID].emplace_back(absAlgRefName, q);
669 }
670 }
671 } else {
672 absAlgRefName += algRefName;
673 algRefFile = SplitReference( m_refConfig.GetStringAttribute(thisRefID,"location"), algRefFile);
674
675 if( algRefFile != "" ) {
676 std::shared_ptr<TFile>
infile = GetROOTFile(algRefFile);
678 std::cerr << "HanConfig::AssessmentVistorBase::GetAlgorithmConfiguration: Reference file " << algRefFile << " not found" << std::endl;
679 continue;
680 }
681
683 if( key == 0 ) {
684
685 std::cerr << "Couldn't find reference " << absAlgRefName << std::endl;
686 continue;
687 }
688 m_outfile->cd();
689 std::shared_ptr<TObject>
q(
key->ReadObj());
690 TNamed* qn =
dynamic_cast<TNamed*
>(
q.get());
691 if (isMultiRef && qn) {
692 std::string multirefname = thisRefID;
693 if (algRefInfo != "") {
694 multirefname = algRefInfo;
695 } else if (algRefFile != "") {
696 multirefname = algRefFile;
697 }
698 qn->SetName(multirefname.c_str());
699 }
700 objects[iRefID].emplace_back(absAlgRefName, q);
701 } else {
702 std::cerr << "No file specified for " << absAlgRefName << " ?" << std::endl;
703 }
704 }
705 }
706
707 std::shared_ptr<TObject> toWriteOut;
708 std::string algRefUniqueName;
709 std::string algRefSourceInfo = (algRefInfo != "" ? algRefInfo.c_str() : "Reference");
710
711 if (!isMultiRef) {
712
713 if (
dqpar->GetIsRegex() && !objects[0].empty()) {
714 refsuccess = true;
715 TMap* tmapobj = new TMap();
716 tmapobj->SetOwnerKeyValue();
717 for (const auto& thisPair: objects[0]) {
718 std::unique_ptr<TObject> cobj(thisPair.second->Clone());
719 TNamed* hobj = dynamic_cast<TNamed*>(cobj.get());
720 if (hobj) {
721 hobj->SetName(refID.c_str());
722 }
723 algRefUniqueName = algRefFile+":/"+thisPair.first;
725 if(newRefId.empty()){
728 m_refsourcedata->Add(new TObjString(newRefId.c_str()),
729 new TObjString(algRefFile.c_str()));
730 cobj->Write(newRefId.c_str(), 1);
731 }
732 m_outfile->cd();
733 std::string maprefstring(thisPair.first);
734 if (algRefPath != "") {
735 boost::replace_first(maprefstring, algRefPath + "/", "");
736 }
737 tmapobj->Add(new TObjString(maprefstring.c_str()),
738 new TObjString(newRefId.c_str()));
739 }
740 toWriteOut.reset(tmapobj);
741 algRefUniqueName = algRefFile+
"_regex:/"+
dqpar->GetUniqueName();
742 }
743 else {
744 algRefUniqueName = algRefFile+":/"+absAlgRefName;
745 if (! objects[0].
empty()) {
746 refsuccess = true;
747 toWriteOut =
objects[0][0].second;
748 }
749 }
750 } else {
751 algRefUniqueName=cond+"_multiple:/"+absAlgRefName;
752 algRefSourceInfo="Multiple references";
753
754 if (
dqpar->GetIsRegex()) {
755
756 } else {
757 TObjArray* toarray = new TObjArray();
758 toarray->SetOwner(true);
759 for (
size_t iRef = 0; iRef <
objects.size(); ++iRef) {
760
761 if (! objects[iRef].
empty()) {
762 toarray->Add(objects[iRef][0].
second->Clone());
763 }
764 }
765 toWriteOut.reset(toarray);
766 refsuccess = true;
767 }
768 }
769
770 if (refsuccess && toWriteOut) {
771
773 if(newRefId.empty()){
776 if (! isMultiRef) {
777
778 m_refsourcedata->Add(new TObjString(newRefId.c_str()),
779 new TObjString(algRefFile.c_str()));
780
781 if (! m_refsourcedata->FindObject(algRefFile.c_str())) {
782 m_refsourcedata->Add(new TObjString(algRefFile.c_str()),
783 new TObjString(algRefSourceInfo.c_str()));
784 }
785 } else {
786
787 m_refsourcedata->Add(new TObjString(newRefId.c_str()),
788 new TObjString(algRefSourceInfo.c_str()));
789 }
790 }
791 m_outfile->cd();
792 toWriteOut->Write(newRefId.c_str(), 1);
793 }
794 }
795
796 if (!newRefId.empty()) {
797 if(!cond.empty()){
798 newRefString<<cond<<":"<<newRefId<<";";
799 }else{
800 newRefString<<newRefId;
801 }
802 }
803 }
804 dqpar->SetAlgRefName((newRefString.str()));
805
806 }else {
807 std::string
stringValue = m_algConfig.GetStringAttribute( algID, *i );
808 float numberValue;
809 std::istringstream
parser( stringValue );
811 if ( ! parser ) {
812 HanConfigParMap algPar;
813 algPar.SetName( *i );
814 algPar.SetValue( stringValue );
815 dqpar->AddAlgStrPar( algPar );
816 } else {
817 HanConfigAlgPar algPar;
818 algPar.SetName( *i );
819 algPar.SetValue( numberValue );
820 dqpar->AddAlgPar( algPar );
821 }
822 }
823 }
824}
825
826
827HanConfig::RegionVisitor::
828RegionVisitor( HanConfigGroup* root_, const MiniConfig& algConfig_,
829 const MiniConfig& thrConfig_, const MiniConfig& refConfig_,
830 HanConfig::DirMap_t& directories_ )
831 : AssessmentVisitorBase( root_, algConfig_, thrConfig_, refConfig_, 0, directories_, nullptr )
832{
833}
834
835
836void
837HanConfig::RegionVisitor::
838Visit(
const MiniConfigTreeNode*
node )
839{
840 const MiniConfigTreeNode*
parent =
node->GetParent();
841 if( parent == 0 )
842 return;
843
844 const MiniConfigTreeNode* grandparent =
parent->GetParent();
845 auto alloc = std::make_unique<HanConfigGroup>();
846 HanConfigGroup*
reg = (grandparent==0) ? m_root : alloc.
get();
847
848
849
850 reg->SetName(
node->GetName() );
851 reg->SetPathName(
node->GetPathName() );
852
853 std::string algID(
node->GetAttribute(
"algorithm") );
854 if( algID != "" ) {
855 GetAlgorithmConfiguration( reg, algID );
856 } else {
857 std::cerr << "Warning: no summary algorithm specified for " << node->GetPathName() << std::endl
858 << "This is probably not what you want" << std::endl;
859 }
860
861 if (
node->GetAttributeLocal(
"weight") !=
"") {
862 std::ostringstream err;
863 err << "Weight is not a floating point attribute for " << node->GetPathName() << "; setting to 0";
864 reg->SetWeight(AttribToFloat(node, "weight", err.str(), true));
865 }
866
867 if( grandparent != 0 ) {
868 std::string path( parent->GetPathName() );
869 HanConfigGroup* parentReg = m_root->GetNode( path );
870 parentReg = (parentReg==0) ? m_root : parentReg;
871 if( parentReg != 0 ) {
872 parentReg->AddGroup( *reg );
873 }
874 }
875}
876
877HanConfig::RegexVisitor::
878RegexVisitor( std::set<std::string>& regexes_ )
879 : m_regexes(regexes_)
880{
881}
882
883boost::shared_ptr<dqm_core::Node>
884HanConfig::RegexVisitor::
885Visit(
const HanConfigAssessor*
node, boost::shared_ptr<dqm_core::Region> )
886{
887
888 if (
dynamic_cast<const HanConfigGroup*
>(
node) != NULL) {
889 return boost::shared_ptr<dqm_core::Parameter>();
890 }
891 if (
node->GetIsRegex()) {
892 m_regexes.insert(
node->GetName());
893 }
894 return boost::shared_ptr<dqm_core::Parameter>();
895}
896
897HanConfig::AssessmentVisitor::
898AssessmentVisitor( HanConfigGroup* root_, const MiniConfig& algConfig_,
899 const MiniConfig& thrConfig_, const MiniConfig& refConfig_,
900 TFile* outfile_, HanConfig::DirMap_t& directories_,
901 TMap* refsourcedata_ )
902 : AssessmentVisitorBase( root_, algConfig_, thrConfig_, refConfig_, outfile_, directories_, refsourcedata_ )
903{
904}
905
906void
907HanConfig::AssessmentVisitor::
908Visit(
const MiniConfigTreeNode*
node )
909{
910 std::set<std::string> histAtt;
911 node->GetAttributeNames( histAtt );
912 std::set<std::string> defined;
913 std::string regID("");
914 std::string algID("");
915 std::set<std::string>::const_iterator histAttEnd = histAtt.end();
916 for( std::set<std::string>::const_iterator
h = histAtt.begin();
h != histAttEnd; ++
h ) {
917 const MiniConfigTreeNode* histNode =
node->GetDaughter( *
h );
918 if( histNode == 0 )
919 continue;
920
921 algID = histNode->GetAttribute("algorithm");
922 regID = histNode->GetAttribute("output");
923
924 if( algID == "" ) {
925 std::cerr << "No \"algorithm\" defined for " << histNode->GetPathName() << "\n";
926 continue;
927 }
928
929 if( regID == "" )
930 regID = "top_level";
931
932 std::string strNodeName(histNode->GetName());
933 std::string strHistName, strFullHistName;
934 std::string::size_type atsign = strNodeName.find('@');
935 if (atsign == std::string::npos) {
936 strHistName = std::move(strNodeName);
937 strFullHistName = histNode->GetPathName();
938 } else {
939 strHistName = strNodeName.substr(0, atsign);
940 strFullHistName = histNode->GetPathName();
941 strFullHistName.resize(strFullHistName.find('@'));
942 }
943
944 if( strHistName == "all_in_dir" )
945 continue;
946
947 if( defined.find(histNode->GetPathName()) != defined.end() )
948 continue;
949
950 HanConfigAssessor
dqpar;
951 dqpar.SetName( histNode->GetPathName() );
952
953 dqpar.SetIsRegex(TestMiniNodeIsRegex(histNode));
954
955 if (histNode->GetAttribute("weight") != "") {
956 std::ostringstream
err;
957 err <<
"Weight attribute not a floating point type for " << histNode->GetPathName() <<
"; setting to zero";
958 dqpar.SetWeight(AttribToFloat(histNode,
"weight",
960 }
961
962 GetAlgorithmConfiguration( &dqpar, algID, strFullHistName );
963
964 std::set<std::string> histAtt2;
965 histNode->GetAttributeNames( histAtt2 );
966 std::set<std::string>::const_iterator histAttEnd2 = histAtt2.end();
967 for( std::set<std::string>::const_iterator h2 = histAtt2.begin(); h2 != histAttEnd2; ++h2 ) {
968 if (
node->GetDaughter( *h2 )
969 || *h2 == "algorithm" || *h2 == "output" || *h2 == "reference"
970 || *h2 == "weight" || *h2 == "regex") {
971 continue;
972 }
973 HanConfigParMap parMap;
974 parMap.SetName(*h2); parMap.SetValue(histNode->GetAttribute(*h2));
975 dqpar.AddAnnotation(parMap);
976 }
977
978
979 HanConfigParMap parMap;
980 parMap.SetName("inputname"); parMap.SetValue( strFullHistName );
981 dqpar.AddAnnotation(parMap);
982
983 HanConfigGroup* dqreg = m_root->GetNode( regID );
984 dqreg = (dqreg==0) ? m_root : dqreg;
985 if( dqreg != 0 ) {
986 dqreg->AddAssessor( dqpar );
987 }
988 defined.insert( std::move(strFullHistName) );
989 }
990
991 for( std::set<std::string>::const_iterator
h = histAtt.begin();
h != histAttEnd; ++
h ) {
992 const MiniConfigTreeNode* histNode =
node->GetDaughter( *
h );
993 if( histNode == 0 )
994 continue;
995
996 algID = histNode->GetAttribute("algorithm");
997 regID = histNode->GetAttribute("output");
998
999 if( algID == "" ) {
1000 std::cerr << "No \"algorithm\" defined for " << histNode->GetPathName() << "\n";
1001 continue;
1002 }
1003
1004 if( regID == "" )
1005 regID = "top_level";
1006
1007 std::string strNodeName(histNode->GetName());
1008 std::string strHistName, strFullHistName, extension;
1009 std::string::size_type atsign = strNodeName.find('@');
1010 if (atsign == std::string::npos) {
1011 strHistName = std::move(strNodeName);
1012 strFullHistName = histNode->GetPathName();
1013 extension = "";
1014 } else {
1015 strHistName = strNodeName.substr(0, atsign);
1016 extension = strNodeName.substr(atsign, std::string::npos);
1017 strFullHistName = histNode->GetPathName();
1018 strFullHistName.resize(strFullHistName.find('@'));
1019 }
1020
1021 if( strHistName == "all_in_dir" ) {
1022
1023 std::string regexflag(histNode->GetAttribute("regex"));
1024 if (histNode->GetAttribute("regex") != "") {
1025 std::cerr << "WARNING: all_in_dir and regex are incompatible; ignoring regex flag for " << histNode->GetPathName()
1026 << "/all_in_dir" << std::endl;
1027 }
1028
1029 std::string refID( histNode->GetAttribute("reference") );
1030 if( refID == "" ) {
1031 std::cerr << "WARNING: No \"reference\" defined for " << histNode->GetPathName() << "\n";
1032 continue;
1033 }
1034 std::string
refFile( m_refConfig.GetStringAttribute(refID,
"file") );
1035 if( refFile == "" ) {
1036 std::cerr << "WARNING: No \"file\" defined for " << histNode->GetPathName() << "\n";
1037 continue;
1038 }
1039
1040 std::string
refPath( m_refConfig.GetStringAttribute(refID,
"path") );
1041
1042 std::string objPath("");
1043 std::string absObjPath("");
1044
1045 refFile = SplitReference( m_refConfig.GetStringAttribute(std::move(refID),
"location"), refFile);
1046 std::shared_ptr<TFile>
infile( GetROOTFile(refFile) );
1047 TDirectory* basedir(0);
1050
1051 if( refPath != "" ) {
1052
1054 absObjPath += "/";
1055 std::string refPathForSearch =
refPath;
1056 refPathForSearch += "/dummyName";
1057 basedir = ChangeInputDir(
infile.get(), refPathForSearch );
1058 if( basedir == 0 ) {
1059 std::cerr <<
"INFO: Cannot find path \"" <<
refPath <<
"\" in reference file\n";
1060 continue;
1061 }
1062 }
1063
1064 if( basedir == 0 )
1066
1067 std::string allPathName( histNode->GetPathName() );
1068 std::string::size_type
i = allPathName.find_last_of(
'/');
1069 if( i != std::string::npos ) {
1070 objPath = std::string( allPathName, 0, i );
1071 objPath += "/";
1072 absObjPath += std::string( allPathName, 0, i );
1073 absObjPath += "/";
1074 }
1075
1076 dir = ChangeInputDir( basedir, histNode->GetPathName() );
1077 if( dir == 0 ) {
1078 std::cerr << "INFO: Cannot find path \"" << absObjPath << "\" in reference file\n";
1079 continue;
1080 }
1081
1082 TIter
next(
dir->GetListOfKeys() );
1083 std::string objName;
1084 std::string absObjName;
1085
1086
1087 std::set<std::string> localdefined;
1088 while( (key =
dynamic_cast<TKey*
>(
next())) != 0 ) {
1089 TObject* tmpobj =
key->ReadObj();
1090 TH1* tmph = dynamic_cast<TH1*>(tmpobj);
1091 TGraph* tmpg = dynamic_cast<TGraph*>(tmpobj);
1092 TEfficiency* tmpe = dynamic_cast<TEfficiency*>(tmpobj);
1093 if( tmph == 0 && tmpg == 0 && tmpe == 0 )
1094 continue;
1095
1096 objName = objPath;
1097 objName += std::string( tmpobj->GetName() );
1098 absObjName = absObjPath;
1099 absObjName += std::string( tmpobj->GetName() );
1100 delete tmpobj;
1101
1102 if( defined.find(objName) != defined.end() ||
1103 localdefined.find(objName) != localdefined.end() )
1104 continue;
1105
1107 if( test == 0 )
1108 continue;
1109
1110 HanConfigAssessor
dqpar;
1111 dqpar.SetName( objName + extension );
1112 GetAlgorithmConfiguration( &dqpar, algID, objName );
1113
1114 if (histNode->GetAttribute("weight") != "") {
1115 std::ostringstream
err;
1116 err <<
"Weight attribute not a floating point type for " << objName <<
"; setting to zero";
1117 dqpar.SetWeight(AttribToFloat(histNode,
"weight",
1119 }
1120
1121 std::set<std::string> histAtt2;
1122 histNode->GetAttributeNames( histAtt2 );
1123 std::set<std::string>::const_iterator histAttEnd2 = histAtt2.end();
1124 for( std::set<std::string>::const_iterator h2 = histAtt2.begin(); h2 != histAttEnd2; ++h2 ) {
1125 if (
node->GetDaughter( *h2 )
1126 || *h2 == "algorithm" || *h2 == "output" || *h2 == "reference"
1127 || *h2 == "weight" || *h2 == "regex") {
1128 continue;
1129 }
1130 HanConfigParMap parMap;
1131 parMap.SetName(*h2); parMap.SetValue(histNode->GetAttribute(*h2));
1132 dqpar.AddAnnotation(parMap);
1133 }
1134
1135
1136 HanConfigParMap parMap;
1137 parMap.SetName("inputname"); parMap.SetValue( objName );
1138 dqpar.AddAnnotation(parMap);
1139
1140 HanConfigGroup* dqreg = m_root->GetNode( regID );
1141 dqreg = (dqreg==0) ? m_root : dqreg;
1142 if( dqreg != 0 ) {
1143 dqreg->AddAssessor( dqpar );
1144 }
1145 localdefined.insert( objName );
1146 }
1147
1148 continue;
1149 }
1150 }
1151}
1152
1153
1154HanConfig::ConfigVisitor::
1155ConfigVisitor( TFile* file_, dqm_core::Output* output_ )
1156 : m_file(file_),
1157 m_output(output_)
1158{
1159}
1160
1161
1162boost::shared_ptr<dqm_core::Node>
1163HanConfig::ConfigVisitor::
1164Visit(
const HanConfigAssessor*
node, boost::shared_ptr<dqm_core::Region> dqParent )
1165{
1166 const HanConfigGroup* gnode =
dynamic_cast<const HanConfigGroup*
>(
node );
1168 std::string algLibName(
node->GetAlgLibName() );
1169 if( algLibName != "" ) {
1170 try {
1171 dqm_core::LibraryManager::instance().loadLibrary( algLibName );
1172 }
1173 catch ( dqm_core::Exception& ex ) {
1174
1175 }
1176 }
1177
1178 if( gnode != 0 ) {
1179 dqm_core::RegionConfig regc( algName,
node->GetWeight() );
1180 std::string regName( gnode->GetPathName() );
1181 boost::shared_ptr<dqm_core::Region>
reg(dqParent->addRegion( regName, regc ));
1182 m_output->addListener(regName, dqParent.get());
1184 }
1185
1186 std::string inputData(
node->GetHistPath() );
1187 HanAlgorithmConfig* algConfig =
new HanAlgorithmConfig( *
node, m_file );
1188 dqm_core::ParameterConfig parc( inputData, algName,
node->GetWeight(),
1189 std::shared_ptr<HanAlgorithmConfig>(algConfig),
node->GetIsRegex() );
1190 boost::shared_ptr<dqm_core::Node>
par(dqParent->addParameter(
node->GetName(), parc ));
1191 m_output->addListener(
node->GetName(), dqParent.get());
1193}
1194
1195
1196HanConfig::CompAlgVisitor::
1197CompAlgVisitor(TFile* outfile_, const MiniConfig& compAlgConfig_)
1198 : m_outfile(outfile_)
1199 , m_compAlgConfig(compAlgConfig_)
1200{
1201}
1202
1203
1204void
1205HanConfig::CompAlgVisitor::
1206Visit(
const MiniConfigTreeNode*
node )
1207{
1208 m_outfile->cd();
1209 std::map<std::string,MiniConfigTreeNode*> daughters =
node->GetDaughters();
1210 std::map<std::string,MiniConfigTreeNode*>::const_iterator nodeiterEnd = daughters.end();
1211 for( std::map<std::string,MiniConfigTreeNode*>::const_iterator iter = daughters.begin(); iter != nodeiterEnd; ++iter ) {
1212 std::string compAlgID =
iter->second->GetName();
1213 std::string compAlgKey =
iter->first;
1214
1215 HanConfigCompAlg* compAlg = new HanConfigCompAlg();
1216 std::set<std::string> compAlgAtt;
1217 m_compAlgConfig.GetAttributeNames(compAlgID, compAlgAtt);
1218 std::set<std::string>::const_iterator compAlgAttEnd = compAlgAtt.end();
1219
1220 compAlg->SetName(compAlgID);
1221 for( std::set<std::string>::const_iterator i = compAlgAtt.begin(); i != compAlgAttEnd; ++i ) {
1222 if( *i == "subalgs" ) {
1223 std::string subAlgs( m_compAlgConfig.GetStringAttribute(compAlgID,"subalgs") );
1224 std::string::size_type
pos = subAlgs.find(
',');
1225 for(int size=subAlgs.size(), sizeOld=-8;
1226 size != sizeOld;
1227 subAlgs.erase(0, pos+1), pos = subAlgs.find(','),sizeOld=size, size=subAlgs.size()) {
1228
1229 compAlg->AddAlg( subAlgs.substr(0,pos));
1230 }
1231 }
1232 else if( *i == "libnames" ) {
1233 std::string
libs( m_compAlgConfig.GetStringAttribute(compAlgID,
"libnames") );
1234 std::string::size_type
pos =
libs.find(
',');
1235 for(
int size=
libs.size(), sizeOld=-8;
1236 size != sizeOld;
1237 libs.erase(0, pos+1), pos =
libs.find(
','),sizeOld=size, size=
libs.size()) {
1238
1239 compAlg->AddLib(
libs.substr(0,pos));
1240 }
1241 }
1242 }
1243 compAlg->Write();
1244 }
1245}
1246
1247HanConfig::MetadataVisitor::
1248MetadataVisitor(TFile* outfile_, const MiniConfig& metadataConfig_)
1249 : m_outfile(outfile_)
1250 , m_metadataConfig(metadataConfig_)
1251{
1252}
1253
1254
1255void
1256HanConfig::MetadataVisitor::
1257Visit(
const MiniConfigTreeNode*
node )
1258{
1259
1260 if (m_outfile->Get("HanMetadata")) {
1261 m_outfile->cd("HanMetadata");
1262 } else {
1263
1264 TDirectory* mdir = m_outfile->mkdir("HanMetadata");
1265 if (mdir) {
1266 mdir->cd();
1267 } else {
1268
1269 m_outfile->cd();
1270 }
1271 }
1272
1273 std::map<std::string,MiniConfigTreeNode*> daughters =
node->GetDaughters();
1274 std::map<std::string,MiniConfigTreeNode*>::const_iterator nodeiterEnd = daughters.end();
1275 for( std::map<std::string,MiniConfigTreeNode*>::const_iterator iter = daughters.begin(); iter != nodeiterEnd; ++iter ) {
1276 std::string metadataID =
iter->second->GetName();
1277
1278 std::set<std::string> metadataAtt;
1279 m_metadataConfig.GetAttributeNames(metadataID, metadataAtt);
1280 HanConfigMetadata*
metadata =
new HanConfigMetadata();
1282 for (std::set<std::string>::const_iterator i = metadataAtt.begin(); i != metadataAtt.end(); ++i ) {
1283 HanConfigParMap parMap;
1284 parMap.SetName(*i); parMap.SetValue(m_metadataConfig.GetStringAttribute(metadataID, *i));
1286 }
1289 }
1290}
1291
1292
1293bool
1294HanConfig::
1295Initialize( const std::string& configName )
1296{
1297 if( m_config == 0 || m_top_level == 0 ) {
1298
1299 delete m_config;
1300 delete m_top_level;
1301 if (m_metadata) {
1302 m_metadata->Delete();
1303 }
1304 delete m_metadata; m_metadata=
newTList(
"HanMetadata");
1305
1306 m_config = TFile::Open( configName.c_str(), "READ" );
1307 if( m_config == 0 ) {
1308 std::cerr << "HanConfig::Initialize() cannot open file \"" << configName << "\"\n";
1309 return false;
1310 }
1311
1312 TMap* refsourcedata = dynamic_cast<TMap*>(m_config->Get("refsourcedata"));
1313 if (refsourcedata) {
1314 ConditionsSingleton::getInstance().setRefSourceMapping(refsourcedata);
1315 } else {
1316 std::cerr << "Can't retrieve reference source info" << std::endl;
1317 }
1318
1319 TIter nextKey( m_config->GetListOfKeys() );
1320 TKey* compAlgKey(0);
1321 while( (compAlgKey = dynamic_cast<TKey*>( nextKey() )) != 0 ) {
1322 TObject*
obj = compAlgKey->ReadObj();
1323 HanConfigCompAlg* compAlg =
dynamic_cast<HanConfigCompAlg*
>(
obj );
1324 if( compAlg != 0 ) {
1325
1326 new CompositeAlgorithm( *compAlg );
1327 }
1329 }
1330
1332
1333 m_metadata =
newTList(
"HanMetadata");
1334 key = m_config->FindKey(
"HanMetadata");
1335 if ( key ) {
1336 TDirectory* mdDir =
dynamic_cast<TDirectory*
>(
key->ReadObj());
1337 if (mdDir) {
1338 TIter mdIter(mdDir->GetListOfKeys());
1339 TKey* mdKey(0);
1340 while ((mdKey = dynamic_cast<TKey*>(mdIter()))) {
1341 HanConfigMetadata* md = dynamic_cast<HanConfigMetadata*>(mdKey->ReadObj());
1342 if (md) {
1343 m_metadata->Add(md);
1344 }
1345 }
1346 }
1347 delete mdDir;
1348 }
1349
1350 key = m_config->FindKey(
"top_level");
1351 if( key == 0 ) {
1352 std::cerr << "HanConfig::Initialize() cannot find configuration in file \"" << configName << "\"\n";
1353 return false;
1354 }
1355
1356 m_top_level =
dynamic_cast<HanConfigGroup*
>(
key->ReadObj() );
1357 if( m_top_level == 0 ) {
1358 std::cerr << "HanConfig::Initialize() cannot find configuration in file \"" << configName << "\"\n";
1359 return false;
1360 }
1361 }
1362
1363 return true;
1364}
1365
1366
1367
1368
1369
1370
1371
1372TDirectory*
1373HanConfig::
1374ChangeInputDir( TDirectory* dir, const std::string& path )
1375{
1376 if( dir == 0 )
1377 return 0;
1378
1380
1381 std::string::size_type
i =
path.find_first_of(
'/');
1382 if( i != std::string::npos ) {
1383 std::string dName( path, 0, i );
1384 std::string pName( path, i+1, std::string::npos );
1385 if( dName != "" ) {
1386 TDirectory* subDir(0);
1387 key =
dir->FindKey( dName.c_str() );
1388 if( key != 0 ) {
1389 subDir =
dynamic_cast<TDirectory*
>(
key->ReadObj() );
1390 }
1391 else {
1392 return 0;
1393 }
1394 TDirectory*
retval = ChangeInputDir( subDir, pName );
1396 }
1397 return ChangeInputDir( dir, pName );
1398 }
1399
1401}
1402
1403
1404TDirectory*
1405HanConfig::
1406ChangeOutputDir( TFile*
file,
const std::string& path, DirMap_t&
directories )
1407{
1409 return 0;
1410
1411 std::string::size_type
i =
path.find_last_of(
'/');
1412 if( i != std::string::npos ) {
1413 std::string subPath( path, 0, i );
1414 DirMap_t::const_iterator j =
directories.find( subPath );
1416 TDirectory*
dir = j->second;
1418 }
1419 else {
1422 std::string::size_type
k = subPath.find_last_of(
'/');
1423 dirName = (
k != std::string::npos) ? std::string( subPath, k+1, std::string::npos ) : subPath;
1424 TDirectory*
dir =
nullptr;
1425 if (!parDir->FindKey(
dirName.c_str())) {
1427 }
1428 else{
1429 std::cout <<
"Failed to make directory " <<
dirName.c_str() << std::endl;
1430 }
1431 DirMap_t::value_type dirVal( subPath, dir );
1434 }
1435 }
1436
1438}
1439
1440}
const boost::regex ref(r_ef)
const boost::regex re(r_e)
std::vector< size_t > vec
static const Attributes_t empty
Header file for AthHistogramAlgorithm.
static ConditionsSingleton & getInstance()
void setNewReferenceName(const std::string &, const std::string &)
std::string getNewRefHistoName()
std::vector< std::pair< std::string, std::string > > getConditionReferencePairs(std::string inp) const
std::string getNewReferenceName(const std::string &, bool quiet=false) const
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
std::vector< std::string > directories
path
python interpreter configuration --------------------------------------—
void dolsr(const TDirectory *dir, std::vector< std::string > &hists, const TDirectory *topdir=nullptr)
TKey * getObjKey(TDirectory *dir, const std::string &path)
TSeqCollection * newTList(const char *name, TObject *obj=0)
const std::string & algName(ID id)
Converts a JetAlgorithmType::ID into a string.