ATLAS Offline Software
TrigMonTHistSvc.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "TrigMonTHistSvc.h"
6 
7 #include "GaudiKernel/ISvcLocator.h"
8 
11 
12 #include "hltinterface/IInfoRegister.h"
13 
14 #include "TError.h"
15 #include "TGraph.h"
16 #include "TH1.h"
17 #include "TH2.h"
18 #include "TH3.h"
19 #include "TObject.h"
20 #include "TROOT.h"
21 #include "TTree.h"
22 
23 TrigMonTHistSvc::TrigMonTHistSvc(const std::string& name, ISvcLocator* svc) : base_class(name, svc)
24 {}
25 
27 {
28  // Protect against multiple instances of TROOT
29  if (0 == gROOT) {
30  static TROOT root("root", "ROOT I/O");
31  }
32  else {
33  ATH_MSG_VERBOSE("ROOT already initialized, debug = " << gDebug);
34  }
35  gErrorIgnoreLevel = kBreak; // ignore warnings see TError.h in ROOT base src
36 
37  // compile regexes
38  m_excludeTypeRegex = boost::regex(m_excludeType.value());
39  m_includeTypeRegex = boost::regex(m_includeType.value());
40  m_excludeNameRegex = boost::regex(m_excludeName.value());
41  m_includeNameRegex = boost::regex(m_includeName.value());
42 
43  // Retrieve and set OH mutex
44  ATH_MSG_INFO("Enabling use of OH histogram mutex");
46  hltinterface::IInfoRegister::instance()->getPublicationMutex());
47 
48  return StatusCode::SUCCESS;
49 }
50 
52 {
53  // Clear list of histograms (actual TH is not owned by us)
54  m_hists.clear();
55 
56  return StatusCode::SUCCESS;
57 }
58 
60 {
61  // Reset OH mutex
62  ATH_MSG_DEBUG("Resetting OH histogram mutex");
64 
65  return StatusCode::SUCCESS;
66 }
67 
68 template <typename T>
69 StatusCode TrigMonTHistSvc::regHist_i(std::unique_ptr<T> hist_unique, const std::string& id,
70  bool shared, THistID*& phid)
71 {
72  std::scoped_lock lock(m_svcMut);
73 
74  // We need to pass ownership to the hist registry now
75  phid = nullptr;
76  if (not isObjectAllowed(id, hist_unique.get())) {
77  return StatusCode::FAILURE;
78  }
79 
80  if (hist_unique->Class()->InheritsFrom(TH1::Class())) {
81  T* hist = hist_unique.release();
82  if (hltinterface::IInfoRegister::instance()->registerTObject(name(), id, hist)) {
83  auto [iter,inserted] = m_hists.try_emplace(id, id, hist);
84  if (not inserted) {
85  ATH_MSG_ERROR("Histogram with name " << id << " already registered");
86  return StatusCode::FAILURE;
87  }
88  if (shared) iter->second.mutex = new std::mutex;
89  phid = &iter->second;
90  ATH_MSG_DEBUG((shared ? "Shared histogram " : "Histogram ")
91  << hist->GetName() << " registered under " << id << " " << name());
92  }
93  else {
94  ATH_MSG_ERROR("Registration of " << hist->ClassName() << " with IInfoRegister failed");
95  delete hist;
96  return StatusCode::FAILURE;
97  }
98  }
99  else {
100  ATH_MSG_ERROR("Cannot register " << hist_unique->ClassName()
101  << " because it does not inherit from TH1");
102  return StatusCode::FAILURE;
103  }
104  return StatusCode::SUCCESS;
105 }
106 
107 template <typename T>
108 LockedHandle<T> TrigMonTHistSvc::regShared_i(const std::string& id, std::unique_ptr<T> hist)
109 {
110  std::scoped_lock lock(m_svcMut);
111 
112  LockedHandle<T> lh(nullptr, nullptr);
113  const auto& h = m_hists.find(id);
114 
115  // No histogram under that id yet
116  if (h == m_hists.end()) {
117  T* phist = hist.get();
118  THistID* phid = nullptr;
119  if (regHist_i(std::move(hist), id, true, phid).isSuccess()) {
120  lh.set(phist, phid->mutex);
121  }
122  }
123  // Histogram already registered under that id
124  else {
125  if (h->second.mutex == nullptr) {
126  ATH_MSG_ERROR("regShared: previously registered histogram \"" << id
127  << "\" was not marked shared");
128  }
129  T* phist = dynamic_cast<T*>(h->second.obj);
130  if (phist == nullptr) {
131  ATH_MSG_ERROR("regShared: unable to dcast retrieved shared hist \""
132  << id << "\" of type " << h->second.obj->IsA()->GetName()
133  << " to requested type " << System::typeinfoName(typeid(T)));
134  }
135  else {
136  lh.set(phist, h->second.mutex);
137  //hist is automatically deleted at end of method
138  }
139  }
140  return lh;
141 }
142 
143 template <typename T>
144 T* TrigMonTHistSvc::getHist_i(const std::string& id, const size_t& /*ind*/, bool quiet) const
145 {
146  std::scoped_lock lock(m_svcMut);
147 
148  const auto& h = m_hists.find(id);
149  if (h == m_hists.end()) {
150  if (!quiet) ATH_MSG_ERROR("could not locate Hist with id \"" << id << "\"");
151  return nullptr;
152  }
153 
154  T* phist = dynamic_cast<T*>(h->second.obj);
155  if (phist == nullptr) {
156  ATH_MSG_ERROR("getHist: unable to dcast retrieved shared hist \""
157  << id << "\" of type " << h->second.obj->IsA()->GetName() << " to requested type "
158  << System::typeinfoName(typeid(T)));
159  return nullptr;
160  }
161  return phist;
162 }
163 
164 StatusCode TrigMonTHistSvc::getTHists_i(const std::string& dir, TList& tl) const
165 {
166  std::scoped_lock lock(m_svcMut);
167  for (const auto& [id, h] : m_hists) {
168  if (id.find(dir) == 0) { // histogram booking path starts from the dir
169  tl.Add(h.obj);
170  }
171  }
172  return StatusCode::SUCCESS;
173 }
174 
175 template <typename T>
176 LockedHandle<T> TrigMonTHistSvc::getShared_i(const std::string& id) const
177 {
178  std::scoped_lock lock(m_svcMut);
179  const auto& h = m_hists.find(id);
180  if (h != m_hists.end()) {
181  if (h->second.mutex == nullptr) {
182  ATH_MSG_ERROR("getShared: found Hist with id \"" << id
183  << "\", but it's not marked as shared");
184  return {};
185  }
186  T* phist = dynamic_cast<T*>(h->second.obj);
187  if (phist == nullptr) {
188  ATH_MSG_ERROR("getShared: unable to dcast retrieved shared hist \""
189  << id << "\" of type " << h->second.obj->IsA()->GetName()
190  << " to requested type " << System::typeinfoName(typeid(T)));
191  return {};
192  }
193  return LockedHandle<T>(phist, h->second.mutex);
194  }
195  ATH_MSG_ERROR("getShared: cannot find histogram with id \"" << id << "\"");
196  return {};
197 }
198 
200 {
201  std::scoped_lock lock(m_svcMut);
202  // Find the relevant histogram and deregister it
203  for (const auto& [name, histid] : m_hists) {
204  if (histid.obj == optr) {
205  ATH_MSG_DEBUG("Found histogram " << optr << " booked under " << name
206  << " and will deregister it");
207  return deReg(name);
208  }
209  }
210  return StatusCode::FAILURE;
211 }
212 
213 StatusCode TrigMonTHistSvc::deReg(const std::string& id)
214 {
215  // This lock should not be needed but the MonSvc implementation in the
216  // HLTMMPPU is not thread-safe (maybe related to ATR-28222).
217  std::scoped_lock lock(m_svcMut);
218  hltinterface::IInfoRegister::instance()->releaseTObject(name(), id);
219  ATH_MSG_DEBUG("Deregistration of " << id << " done");
220  return StatusCode::SUCCESS;
221 }
222 
223 std::vector<std::string> TrigMonTHistSvc::getHists() const
224 {
225  std::scoped_lock lock(m_svcMut);
226  std::vector<std::string> l;
227  l.reserve(m_hists.size());
228  for (const auto& h : m_hists) l.push_back(h.first);
229  return l;
230 }
231 
232 bool TrigMonTHistSvc::isObjectAllowed(const std::string& path, const TObject* o) const
233 {
234  boost::cmatch what;
235 
236  if (not boost::regex_match(o->ClassName(), what, m_includeTypeRegex)) {
237  ATH_MSG_WARNING("Object " << path << " of type " << o->ClassName()
238  << " does NOT match IncludeType \"" << m_includeType << "\"");
239  return false;
240  }
241 
242  if (boost::regex_match(o->ClassName(), what, m_excludeTypeRegex)) {
243  ATH_MSG_WARNING("Object " << path << " of type " << o->ClassName() << " matches ExcludeType \""
244  << m_excludeType << "\"");
245  return false;
246  }
247 
248  if (not boost::regex_match(path.c_str(), what, m_includeNameRegex)) {
249  ATH_MSG_WARNING("Object " << path << " does NOT match IncludeName \"" << m_includeName << "\"");
250  return false;
251  }
252 
253  if (boost::regex_match(path.c_str(), what, m_excludeNameRegex)) {
254  ATH_MSG_WARNING("Object " << path << " matches ExcludeName \"" << m_excludeName << "\"");
255  return false;
256  }
257 
258  return true;
259 }
260 
261 bool TrigMonTHistSvc::existsHist(const std::string& name) const
262 {
263  return (getHist_i<TH1>(name, 0, true) != nullptr);
264 }
265 
266 /**************************************************************************************
267  * Typed interface methods
268  * All these are just forwarding to the templated xyz_i methods
269  **************************************************************************************/
270 StatusCode TrigMonTHistSvc::regHist(const std::string& id)
271 {
272  std::unique_ptr<TH1> hist = nullptr;
273  THistID* hid = nullptr;
274  return regHist_i(std::move(hist), id, false, hid);
275 }
276 
277 StatusCode TrigMonTHistSvc::regHist(const std::string& id, std::unique_ptr<TH1> hist)
278 {
279  THistID* hid = nullptr;
280  return regHist_i(std::move(hist), id, false, hid);
281 }
282 
283 StatusCode TrigMonTHistSvc::regHist(const std::string& id, TH1* hist_ptr)
284 {
285  THistID* hid = nullptr;
286  std::unique_ptr<TH1> hist(hist_ptr);
287  return regHist_i(std::move(hist), id, false, hid);
288 }
289 
290 /**************************************************************************************/
291 
292 StatusCode TrigMonTHistSvc::getHist(const std::string& id, TH1*& hist, size_t ind) const
293 {
294  hist = getHist_i<TH1>(id, ind);
295  return (hist != nullptr ? StatusCode::SUCCESS : StatusCode::FAILURE);
296 }
297 
298 StatusCode TrigMonTHistSvc::getHist(const std::string& id, TH2*& hist, size_t ind) const
299 {
300  hist = getHist_i<TH2>(id, ind);
301  return (hist != nullptr ? StatusCode::SUCCESS : StatusCode::FAILURE);
302 }
303 
304 StatusCode TrigMonTHistSvc::getHist(const std::string& id, TH3*& hist, size_t ind) const
305 {
306  hist = getHist_i<TH3>(id, ind);
307  return (hist != nullptr ? StatusCode::SUCCESS : StatusCode::FAILURE);
308 }
309 
310 /**************************************************************************************/
311 
312 StatusCode TrigMonTHistSvc::getTHists(TDirectory* td, TList& tl, bool recurse) const
313 {
314  if (recurse) ATH_MSG_DEBUG("Recursive flag is not supported in this implementation");
315  return getTHists_i(std::string(td->GetPath()), tl);
316 }
317 
318 StatusCode TrigMonTHistSvc::getTHists(const std::string& dir, TList& tl, bool recurse) const
319 {
320  if (recurse) ATH_MSG_DEBUG("Recursive flag is not supported in this implementation");
321  return getTHists_i(dir, tl);
322 }
323 
324 StatusCode TrigMonTHistSvc::getTHists(TDirectory* td, TList& tl, bool recurse, bool reg)
325 {
326  if (recurse || reg)
327  ATH_MSG_DEBUG("Recursive flag and automatic registration flag is not "
328  "supported in this implementation");
329  return getTHists_i(std::string(td->GetPath()), tl);
330 }
331 
332 StatusCode TrigMonTHistSvc::getTHists(const std::string& dir, TList& tl, bool recurse, bool reg)
333 {
334  if (recurse || reg)
335  ATH_MSG_DEBUG("Recursive flag and automatic registration flag is not "
336  "supported in this implementation");
337  return getTHists_i(dir, tl);
338 }
339 
340 /**************************************************************************************/
341 
342 StatusCode TrigMonTHistSvc::regShared(const std::string& id, std::unique_ptr<TH1> hist,
343  LockedHandle<TH1>& lh)
344 {
345  lh = regShared_i<TH1>(id, std::move(hist));
346  return (lh ? StatusCode::SUCCESS : StatusCode::FAILURE);
347 }
348 
349 StatusCode TrigMonTHistSvc::regShared(const std::string& id, std::unique_ptr<TH2> hist,
350  LockedHandle<TH2>& lh)
351 {
352  lh = regShared_i<TH2>(id, std::move(hist));
353  return (lh ? StatusCode::SUCCESS : StatusCode::FAILURE);
354 }
355 
356 StatusCode TrigMonTHistSvc::regShared(const std::string& id, std::unique_ptr<TH3> hist,
357  LockedHandle<TH3>& lh)
358 {
359  lh = regShared_i<TH3>(id, std::move(hist));
360  return (lh ? StatusCode::SUCCESS : StatusCode::FAILURE);
361 }
362 
363 /**************************************************************************************/
364 
365 StatusCode TrigMonTHistSvc::getShared(const std::string& id, LockedHandle<TH1>& lh) const
366 {
367  lh = getShared_i<TH1>(id);
368  return (lh ? StatusCode::SUCCESS : StatusCode::FAILURE);
369 }
370 
371 StatusCode TrigMonTHistSvc::getShared(const std::string& id, LockedHandle<TH2>& lh) const
372 {
373  lh = getShared_i<TH2>(id);
374  return (lh ? StatusCode::SUCCESS : StatusCode::FAILURE);
375 }
376 
377 StatusCode TrigMonTHistSvc::getShared(const std::string& id, LockedHandle<TH3>& lh) const
378 {
379  lh = getShared_i<TH3>(id);
380  return (lh ? StatusCode::SUCCESS : StatusCode::FAILURE);
381 }
TrigMonTHistSvc.h
TrigMonTHistSvc::m_hists
std::unordered_map< std::string, THistID > m_hists
Registered histograms.
Definition: TrigMonTHistSvc.h:131
TrigMonTHistSvc::THistID::mutex
std::mutex * mutex
Definition: TrigMonTHistSvc.h:127
TrigMonTHistSvc::getHist_i
T * getHist_i(const std::string &id, const size_t &ind, bool quiet=false) const
Definition: TrigMonTHistSvc.cxx:144
OHLockedHist.h
OH histogram lock header file.
TrigMonTHistSvc::THistID
Helper struct that bundles the histogram, name and mutex.
Definition: TrigMonTHistSvc.h:122
TrigMonTHistSvc::m_excludeName
Gaudi::Property< std::string > m_excludeName
Definition: TrigMonTHistSvc.h:148
DiTauMassTools::TauTypes::lh
@ lh
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:53
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:128
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
quiet
bool quiet
Definition: TrigGlobEffCorrValidation.cxx:190
BeamSpot::mutex
std::mutex mutex
Definition: InDetBeamSpotVertex.cxx:18
plotmaker.hist
hist
Definition: plotmaker.py:148
initialize
void initialize()
Definition: run_EoverP.cxx:894
TrigMonTHistSvc::m_includeName
Gaudi::Property< std::string > m_includeName
Definition: TrigMonTHistSvc.h:149
TrigMonTHistSvc::m_excludeTypeRegex
boost::regex m_excludeTypeRegex
Definition: TrigMonTHistSvc.h:161
TrigMonTHistSvc::getHists
virtual std::vector< std::string > getHists() const override
Definition: TrigMonTHistSvc.cxx:223
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
TrigMonTHistSvc::m_svcMut
std::recursive_mutex m_svcMut
Protect access to histogram list.
Definition: TrigMonTHistSvc.h:167
sendEI_SPB.root
root
Definition: sendEI_SPB.py:34
TrigMonTHistSvc::regShared
virtual StatusCode regShared(const std::string &, std::unique_ptr< TH1 >, LockedHandle< TH1 > &) override
Definition: TrigMonTHistSvc.cxx:342
TrigMonTHistSvc::m_excludeNameRegex
boost::regex m_excludeNameRegex
Definition: TrigMonTHistSvc.h:163
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
TrigMonTHistSvc::regShared_i
LockedHandle< T > regShared_i(const std::string &id, std::unique_ptr< T > hist)
Definition: TrigMonTHistSvc.cxx:108
dq_make_web_display.recurse
def recurse(rdir, dqregion, ignorepath, reffile=None)
Definition: dq_make_web_display.py:23
TrigMonTHistSvc::m_excludeType
Gaudi::Property< std::string > m_excludeType
Definition: TrigMonTHistSvc.h:146
TrigMonTHistSvc::TrigMonTHistSvc
TrigMonTHistSvc(const std::string &name, ISvcLocator *svc)
Definition: TrigMonTHistSvc.cxx:23
PrepareReferenceFile.regex
regex
Definition: PrepareReferenceFile.py:43
TrigMonTHistSvc::getShared
virtual StatusCode getShared(const std::string &, LockedHandle< TH1 > &) const override
Definition: TrigMonTHistSvc.cxx:365
ATLAS_NOT_THREAD_SAFE
StatusCode TrigMonTHistSvc::initialize ATLAS_NOT_THREAD_SAFE()
Install fatal handler with default options.
Definition: TrigMonTHistSvc.cxx:26
instance
std::map< std::string, double > instance
Definition: Run_To_Get_Tags.h:8
TrigMonTHistSvc::deReg
virtual StatusCode deReg(TObject *obj) override
Definition: TrigMonTHistSvc.cxx:199
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
TrigMonTHistSvc::m_includeTypeRegex
boost::regex m_includeTypeRegex
Definition: TrigMonTHistSvc.h:162
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
oh_lock_histogram_mutex::reset_histogram_mutex
static void reset_histogram_mutex()
Reset (disable) histogram mutex.
Definition: OHLockedHist.h:39
TrigMonTHistSvc::isObjectAllowed
bool isObjectAllowed(const std::string &path, const TObject *o) const
Does the histogram follow the naming rules ?
Definition: TrigMonTHistSvc.cxx:232
TrigMonTHistSvc::existsHist
virtual bool existsHist(const std::string &name) const override
Definition: TrigMonTHistSvc.cxx:261
TrigMonTHistSvc::regHist
virtual StatusCode regHist(const std::string &name) override
Definition: TrigMonTHistSvc.cxx:270
Handler::svc
AthROOTErrorHandlerSvc * svc
Definition: AthROOTErrorHandlerSvc.cxx:10
TrigMonTHistSvc::getTHists
virtual StatusCode getTHists(TDirectory *td, TList &, bool recurse=false) const override
Definition: TrigMonTHistSvc.cxx:312
TrigMonTHistSvc::getTHists_i
StatusCode getTHists_i(const std::string &name, TList &) const
Get TList of registered histograms.
Definition: TrigMonTHistSvc.cxx:164
TrigMonTHistSvc::getHist
virtual StatusCode getHist(const std::string &id, TH1 *&hist, size_t ind) const override
Definition: TrigMonTHistSvc.cxx:292
TrigMonTHistSvc::getShared_i
LockedHandle< T > getShared_i(const std::string &id) const
Definition: TrigMonTHistSvc.cxx:176
beamspotman.dir
string dir
Definition: beamspotman.py:623
TrigMonTHistSvc::regHist_i
StatusCode regHist_i(std::unique_ptr< T > hist, const std::string &name, bool shared, THistID *&phid)
Definition: TrigMonTHistSvc.cxx:69
python.ExitCodes.what
def what(code)
Definition: ExitCodes.py:73
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
TrigMonTHistSvc::m_includeType
Gaudi::Property< std::string > m_includeType
Definition: TrigMonTHistSvc.h:147
gErrorIgnoreLevel
int gErrorIgnoreLevel
TrigMonTHistSvc::stop
virtual StatusCode stop() override
Definition: TrigMonTHistSvc.cxx:51
h
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
dqt_zlumi_alleff_HIST.tl
tl
Definition: dqt_zlumi_alleff_HIST.py:73
TrigMonTHistSvc::m_includeNameRegex
boost::regex m_includeNameRegex
Definition: TrigMonTHistSvc.h:164
oh_lock_histogram_mutex::set_histogram_mutex
static void set_histogram_mutex(std::mutex &mutex)
Set mutex to be used in oh_lock_histogram.
Definition: OHLockedHist.h:36
checker_macros.h
Define macros for attributes used to control the static checker.
TrigMonTHistSvc::finalize
virtual StatusCode finalize() override
Definition: TrigMonTHistSvc.cxx:59
checkFileSG.ind
list ind
Definition: checkFileSG.py:118
TSU::T
unsigned long long T
Definition: L1TopoDataTypes.h:35