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