ATLAS Offline Software
Loading...
Searching...
No Matches
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
23TrigMonTHistSvc::TrigMonTHistSvc(const std::string& name, ISvcLocator* svc) : base_class(name, svc)
24{}
25
26StatusCode TrigMonTHistSvc::initialize ATLAS_NOT_THREAD_SAFE()
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
68template <typename T>
69StatusCode 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
107template <typename T>
108LockedHandle<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
143template <typename T>
144T* 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
164StatusCode 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
175template <typename T>
176LockedHandle<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
199StatusCode TrigMonTHistSvc::deReg(TObject* optr)
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
213StatusCode 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
223std::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
232bool 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
261bool 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 **************************************************************************************/
270StatusCode 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
277StatusCode 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
283StatusCode 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
292StatusCode 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
298StatusCode 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
304StatusCode 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
312StatusCode 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
318StatusCode 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
324StatusCode 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
332StatusCode 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
342StatusCode 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
349StatusCode 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
356StatusCode 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
365StatusCode 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
371StatusCode 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
377StatusCode 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}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
OH histogram lock header file.
StatusCode TrigMonTHistSvc::initialize ATLAS_NOT_THREAD_SAFE()
Install fatal handler with default options.
Define macros for attributes used to control the static checker.
Header file for AthHistogramAlgorithm.
Gaudi::Property< std::string > m_excludeType
virtual bool existsHist(const std::string &name) const override
boost::regex m_excludeTypeRegex
virtual StatusCode finalize() override
Gaudi::Property< std::string > m_includeName
std::recursive_mutex m_svcMut
Protect access to histogram list.
boost::regex m_includeNameRegex
virtual StatusCode deReg(TObject *obj) override
Gaudi::Property< std::string > m_includeType
boost::regex m_excludeNameRegex
StatusCode getTHists_i(const std::string &name, TList &) const
Get TList of registered histograms.
boost::regex m_includeTypeRegex
LockedHandle< T > regShared_i(const std::string &id, std::unique_ptr< T > hist)
Gaudi::Property< std::string > m_excludeName
virtual StatusCode regHist(const std::string &name) override
StatusCode regHist_i(std::unique_ptr< T > hist, const std::string &name, bool shared, THistID *&phid)
virtual std::vector< std::string > getHists() const override
virtual StatusCode regShared(const std::string &, std::unique_ptr< TH1 >, LockedHandle< TH1 > &) override
virtual StatusCode stop() override
LockedHandle< T > getShared_i(const std::string &id) const
T * getHist_i(const std::string &id, const size_t &ind, bool quiet=false) const
virtual StatusCode getHist(const std::string &id, TH1 *&hist, size_t ind) const override
bool isObjectAllowed(const std::string &path, const TObject *o) const
Does the histogram follow the naming rules ?
std::unordered_map< std::string, THistID > m_hists
Registered histograms.
virtual StatusCode getShared(const std::string &, LockedHandle< TH1 > &) const override
TrigMonTHistSvc(const std::string &name, ISvcLocator *svc)
virtual StatusCode getTHists(TDirectory *td, TList &, bool recurse=false) const override
static void reset_histogram_mutex()
Reset (disable) histogram mutex.
static void set_histogram_mutex(std::mutex &mutex)
Set mutex to be used in oh_lock_histogram.
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:138
Helper struct that bundles the histogram, name and mutex.