ATLAS Offline Software
OfflineHistogramProvider.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #ifndef AthenaMonitoringKernel_HistogramFiller_OfflineHistogramProvider_h
6 #define AthenaMonitoringKernel_HistogramFiller_OfflineHistogramProvider_h
7 
8 #include <memory>
9 
13 
14 #include "GaudiKernel/ContextSpecificPtr.h"
15 
16 #include "HistogramFactory.h"
17 
18 #include "TTree.h"
19 
20 // this mutex is used to protect access to the metadata trees
21 namespace {
22  static std::mutex s_metadataMutex;
23 }
24 
25 namespace Monitored {
30  public:
39  std::shared_ptr<HistogramFactory> factory,
40  const HistogramDef& histDef)
42  , m_gmTool(gmTool)
43  , m_factory(std::move(factory))
44  , m_histDef(new HistogramDef(histDef))
45  , m_objcache({0, 0, nullptr})
46  {}
47 
48  // store metadata trees on object destruction
49  virtual ~OfflineHistogramProvider() override {
50  try {
51  storeMetadata();
52  }
53  catch (const GaudiException&) {
54  // storeMetadata can throw due to dereferencing a Gaudi handle
55  std::abort();
56  }
57  }
58 
68  TNamed* histogram() override {
69  const unsigned runNumber = m_gmTool->runNumber();
70  const unsigned lumiBlock = m_gmTool->lumiBlock();
71 
72  // do we have the object already?
73  std::scoped_lock lock(m_cacheMutex);
74  objcache& objcacheref = m_objcache;
75  if (objcacheref.lumiBlock == lumiBlock
76  && objcacheref.runNumber == runNumber
77  && objcacheref.object) {
78  return objcacheref.object;
79  }
80 
81  std::string lbString;
84  lbString = "";
85  } else if ( period == HistogramDef::RunPeriod::LowStat ) {
86  const unsigned lbBase = lumiBlock-(((int64_t)lumiBlock-1)%20);
87  lbString = "/lowStat_LB"+std::to_string(lbBase)+"-"+std::to_string(lbBase+19);
88  } else {
89  lbString = "/lb_"+std::to_string(lumiBlock);
90  }
91  m_histDef->tld = "/run_"+std::to_string(runNumber)+lbString+"/";
92 
93  objcacheref.lumiBlock = lumiBlock;
94  objcacheref.runNumber = runNumber;
95  objcacheref.object = m_factory->create(*m_histDef);
96  const auto fullName = m_factory->getFullName(*m_histDef);
97  if (std::find(m_storedPaths.begin(), m_storedPaths.end(), fullName) == m_storedPaths.end()) {
98  m_storedPaths.push_back(std::move(fullName));
99  }
100  return objcacheref.object;
101  }
102 
103  private:
105  std::shared_ptr<HistogramFactory> m_factory;
106  std::shared_ptr<HistogramDef> m_histDef;
107 
108  struct objcache {
109  unsigned int runNumber;
110  unsigned int lumiBlock;
111  TNamed* object;
112  };
113  mutable Gaudi::Hive::ContextSpecificData<objcache> m_objcache ATLAS_THREAD_SAFE;
115 
116  std::vector<std::string> m_storedPaths;
117 
124  void storeMetadata() const {
125  std::scoped_lock<std::mutex> metadataLock(s_metadataMutex);
126  for (const auto &path : m_storedPaths) {
127  //std::cout << "Path " << path << std::endl;
128  size_t pos = path.find_last_of('/');
129  auto splitPath = std::make_pair(path.substr(0, pos), path.substr(pos + 1));
130  std::string treePath = splitPath.first + "/metadata";
131  auto &histSvc = m_gmTool->histogramService();
132  std::string interval;
133  char triggerData[] = "<none>";
134  const std::string mergeDataStr = m_histDef->merge == "" ? "<default>" : m_histDef->merge;
135  std::vector<char> mergeData{mergeDataStr.begin(), mergeDataStr.end()};
136  mergeData.push_back('\0');
137 
140  interval = "run";
142  interval = "lowStat";
143  } else {
144  interval = "lumiBlock";
145  }
146  if (!histSvc->existsTree(treePath)) {
147  auto tree = std::make_unique<TTree>("metadata", "Monitoring Metadata");
148 
149  tree->Branch("Name", &(splitPath.second[0]), "Name/C");
150  tree->Branch("Interval", &(interval[0]), "Interval/C");
151  tree->Branch("TriggerChain", triggerData, "TriggerChain/C");
152  tree->Branch("MergeMethod", mergeData.data(), "MergeMethod/C");
153  tree->Fill();
154 
155  if (!histSvc->regTree(treePath, std::move(tree))) {
156  MsgStream log(Athena::getMessageSvc(), "OfflineHistogramProvider");
157  log << MSG::ERROR
158  << "Failed to register DQ metadata TTree " << treePath << endmsg;
159  }
160  } else {
161  TTree *tree{nullptr};
162  if (histSvc->getTree(treePath, tree).isSuccess()) {
163  tree->SetBranchAddress("Name", &(splitPath.second[0]));
164  tree->SetBranchAddress("Interval", &(interval[0]));
165  tree->SetBranchAddress("TriggerChain", triggerData);
166  tree->SetBranchAddress("MergeMethod", mergeData.data());
167  tree->Fill();
168  } else {
169  MsgStream log(Athena::getMessageSvc(), "OfflineHistogramProvider");
170  log << MSG::ERROR
171  << "Failed to retrieve DQ metadata TTree " << treePath << " which is reported to exist" << endmsg;
172  }
173  }
174  }
175  }
176  };
177 }
178 
179 #endif /* AthenaMonitoringKernel_HistogramFiller_OfflineHistogramProvider_h */
python.AtlRunQueryAMI.period
period
Definition: AtlRunQueryAMI.py:224
IHistogramProvider.h
Monitored::OfflineHistogramProvider::m_histDef
std::shared_ptr< HistogramDef > m_histDef
Definition: OfflineHistogramProvider.h:106
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:128
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
Monitored::IHistogramProvider
Interface of the source of ROOT objects for HistogramFillers.
Definition: IHistogramProvider.h:14
Monitored::OfflineHistogramProvider::m_factory
std::shared_ptr< HistogramFactory > m_factory
Definition: OfflineHistogramProvider.h:105
BeamSpot::mutex
std::mutex mutex
Definition: InDetBeamSpotVertex.cxx:18
HistogramDef.h
Monitored::HistogramDef::RunPeriod::Run
@ Run
rebook histogram after each run
WriteCellNoiseToCool.fullName
fullName
Definition: WriteCellNoiseToCool.py:461
tree
TChain * tree
Definition: tile_monitor.h:30
CSV_InDetExporter.new
new
Definition: CSV_InDetExporter.py:145
GenericMonitoringTool::lumiBlock
virtual uint32_t lumiBlock()
Definition: GenericMonitoringTool.cxx:286
Monitored::OfflineHistogramProvider::objcache::object
TNamed * object
Definition: OfflineHistogramProvider.h:111
Monitored::OfflineHistogramProvider::objcache::runNumber
unsigned int runNumber
Definition: OfflineHistogramProvider.h:109
python.RatesEmulationExample.lock
lock
Definition: RatesEmulationExample.py:148
Monitored::HistogramDef
the internal class used to keep parsed Filler properties
Definition: HistogramDef.h:15
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
Monitored::OfflineHistogramProvider::objcache::lumiBlock
unsigned int lumiBlock
Definition: OfflineHistogramProvider.h:110
Monitored::HistogramDef::RunPeriod
RunPeriod
Definition: HistogramDef.h:33
GenericMonitoringTool.h
Monitored
Generic monitoring tool for athena components.
Definition: GenericMonitoringTool.h:30
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
getLatestRuns.interval
interval
Definition: getLatestRuns.py:24
Monitored::OfflineHistogramProvider::histogram
TNamed * histogram() override
Getter of ROOT object.
Definition: OfflineHistogramProvider.h:68
Monitored::OfflineHistogramProvider::m_storedPaths
std::vector< std::string > m_storedPaths
Definition: OfflineHistogramProvider.h:116
MuonSegmentReaderConfig.histSvc
histSvc
Definition: MuonSegmentReaderConfig.py:96
Monitored::OfflineHistogramProvider::m_gmTool
GenericMonitoringTool *const m_gmTool
Definition: OfflineHistogramProvider.h:104
Monitored::OfflineHistogramProvider::m_cacheMutex
std::mutex m_cacheMutex
Definition: OfflineHistogramProvider.h:114
GenericMonitoringTool::runNumber
virtual uint32_t runNumber()
Definition: GenericMonitoringTool.cxx:282
GenericMonitoringTool
Definition: GenericMonitoringTool.py:1
Monitored::OfflineHistogramProvider::objcache
Definition: OfflineHistogramProvider.h:108
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
Monitored::OfflineHistogramProvider::storeMetadata
void storeMetadata() const
Store metadata trees.
Definition: OfflineHistogramProvider.h:124
GenericMonitoringTool::histogramService
virtual const ServiceHandle< ITHistSvc > & histogramService() const
Definition: GenericMonitoringTool.h:72
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:16
Monitored::OfflineHistogramProvider
Implementation of IHistogramProvider for offline histograms.
Definition: OfflineHistogramProvider.h:29
DeMoAtlasDataLoss.runNumber
string runNumber
Definition: DeMoAtlasDataLoss.py:64
HistogramFactory.h
Monitored::OfflineHistogramProvider::OfflineHistogramProvider
OfflineHistogramProvider(GenericMonitoringTool *const gmTool, std::shared_ptr< HistogramFactory > factory, const HistogramDef &histDef)
Constructor.
Definition: OfflineHistogramProvider.h:38
Monitored::OfflineHistogramProvider::~OfflineHistogramProvider
virtual ~OfflineHistogramProvider() override
Definition: OfflineHistogramProvider.h:49
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
Monitored::HistogramDef::RunPeriod::LowStat
@ LowStat
rebook histogram after every 20 lumiblocks
xAOD::lumiBlock
setTeId lumiBlock
Definition: L2StandAloneMuon_v1.cxx:328
Monitored::OfflineHistogramProvider::ATLAS_THREAD_SAFE
Gaudi::Hive::ContextSpecificData< objcache > m_objcache ATLAS_THREAD_SAFE
Definition: OfflineHistogramProvider.h:113