ATLAS Offline Software
Classes | Public Member Functions | Public Attributes | Private Member Functions | Private Attributes | List of all members
GenericMonitoringTool Class Reference

#include <GenericMonitoringTool.h>

Inheritance diagram for GenericMonitoringTool:
Collaboration diagram for GenericMonitoringTool:

Classes

class  GenericMonitoringArray
 
class  GenericMonitoringTool
 

Public Member Functions

virtual ~GenericMonitoringTool () override
 
virtual StatusCode initialize () override
 
virtual StatusCode start () override
 
virtual StatusCode stop () override
 
void handle (const Incident &) override
 
void invokeFillers (const std::vector< std::reference_wrapper< Monitored::IMonitoredVariable >> &monitoredVariables) const
 feed the fillers More...
 
StatusCode book ()
 Book histograms. More...
 
void setPath (const std::string &newPath)
 Overrride configured booking path. More...
 
const std::string & getPath () const
 
virtual const ServiceHandle< ITHistSvc > & histogramService () const
 
virtual uint32_t runNumber ()
 
virtual uint32_t lumiBlock ()
 

Public Attributes

 log = logging.getLogger(__name__)
 

Private Member Functions

void invokeFillersDebug (const std::shared_ptr< Monitored::HistogramFiller > &filler, const std::vector< std::reference_wrapper< Monitored::IMonitoredVariable >> &monitoredVariables) const
 

Private Attributes

ServiceHandle< ITHistSvc > m_histSvc { this, "THistSvc", "THistSvc", "Histogramming svc" }
 THistSvc (do NOT fix the service type (only the name) to allow for a different implementation online. More...
 
Gaudi::Property< std::string > m_histoPath { this, "HistPath", {}, "Directory for histograms [name of parent if not set]" }
 
Gaudi::Property< std::vector< std::string > > m_histograms { this, "Histograms", {}, "Definitions of histograms", "OrderedSet<std::string>"}
 
Gaudi::Property< bool > m_explicitBooking { this, "ExplicitBooking", false, "Do not create histograms automatically in initialize but wait until the method book is called." }
 
Gaudi::Property< bool > m_failOnEmpty { this, "FailOnEmpty", true, "Fail in initialize() if no histograms defined" }
 
BooleanProperty m_useCache { this, "UseCache", true, "Cache filler lookups" }
 
BooleanProperty m_registerHandler { this, "RegisterHandler", true, "Use incident handler to make 'always book' plots (else only check once)" }
 
std::vector< std::shared_ptr< Monitored::HistogramFiller > > m_fillers
 plain list of fillers More...
 
std::vector< std::shared_ptr< Monitored::HistogramFiller > > m_alwaysCreateFillers
 fillers that need touching, usually empty More...
 
std::map< std::vector< std::string >, std::unique_ptr< std::vector< std::shared_ptr< Monitored::HistogramFiller > > >, std::less<> > m_fillerCacheMap ATLAS_THREAD_SAFE
 lookup map to speed up filler searches More...
 
std::mutex m_cacheMutex
 

Detailed Description

Definition at line 53 of file GenericMonitoringTool.h.

Constructor & Destructor Documentation

◆ ~GenericMonitoringTool()

GenericMonitoringTool::~GenericMonitoringTool ( )
overridevirtual

Definition at line 23 of file GenericMonitoringTool.cxx.

23 { }

Member Function Documentation

◆ book()

StatusCode GenericMonitoringTool::book ( )

Book histograms.

Definition at line 56 of file GenericMonitoringTool.cxx.

56  {
57 
58  // If no histogram path given use parent or our own name
59  if (m_histoPath.empty()) {
60  auto named = dynamic_cast<const INamedInterface*>(parent());
61  m_histoPath = named ? named->name() : name();
62  }
63 
64  // Replace dot (e.g. MyAlg.MyTool) with slash to create sub-directory
65  std::replace( m_histoPath.begin(), m_histoPath.end(), '.', '/' );
66 
67  ATH_MSG_DEBUG("Booking histograms in path: " << m_histoPath.value());
68 
69  HistogramFillerFactory factory(this, m_histoPath);
70 
71  for (const std::string& item : m_histograms) {
72  if (item.empty()) {
73  ATH_MSG_DEBUG( "Skipping empty histogram definition" );
74  continue;
75  }
76  ATH_MSG_DEBUG( "Configuring monitoring for: " << item );
78 
79  if (def.ok) {
80  std::shared_ptr<HistogramFiller> filler(factory.create(def));
81 
82  if (filler) {
83  if (def.kAlwaysCreate) {
84  if (m_registerHandler) {
85  m_alwaysCreateFillers.push_back(filler); // prepare list of fillers for handler
86  } else {
87  filler->touch(); // create now and be done with it
88  }
89  }
90  m_fillers.push_back(filler);
91  } else {
92  ATH_MSG_WARNING( "The histogram filler cannot be instantiated for: " << def.name );
93  }
94  } else {
95  ATH_MSG_ERROR( "Unparsable histogram definition: " << item );
96  return StatusCode::FAILURE;
97  }
98  ATH_MSG_DEBUG( "Monitoring for variable " << def.name << " prepared" );
99  }
100 
101  if ( m_fillers.empty() && m_failOnEmpty ) {
102  std::string hists;
103  for (const auto &h : m_histograms) hists += (h+",");
104  ATH_MSG_ERROR("No monitored variables created based on histogram definition: [" << hists <<
105  "] Remove this monitoring tool or check its configuration.");
106  return StatusCode::FAILURE;
107  }
108 
109  // are there some histograms that should always be made?
110  // then register to be notified on every event
111  if (! m_alwaysCreateFillers.empty() && m_registerHandler) {
112  ATH_MSG_DEBUG("Registering incident handler");
113  SmartIF<IIncidentSvc> incSvc{service("IncidentSvc")};
114  ATH_CHECK(incSvc.isValid());
115  incSvc->addListener(this, IncidentType::BeginEvent);
116  }
117 
118  return StatusCode::SUCCESS;
119 }

◆ getPath()

const std::string& GenericMonitoringTool::getPath ( ) const
inline

Definition at line 70 of file GenericMonitoringTool.h.

70 { return m_histoPath; }

◆ handle()

void GenericMonitoringTool::handle ( const Incident &  )
override

Definition at line 50 of file GenericMonitoringTool.cxx.

50  {
51  for (const auto& filler : m_alwaysCreateFillers) {
52  filler->touch();
53  }
54 }

◆ histogramService()

virtual const ServiceHandle<ITHistSvc>& GenericMonitoringTool::histogramService ( ) const
inlinevirtual

Definition at line 72 of file GenericMonitoringTool.h.

72 { return m_histSvc; }

◆ initialize()

StatusCode GenericMonitoringTool::initialize ( )
overridevirtual

Definition at line 25 of file GenericMonitoringTool.cxx.

25  {
26  ATH_CHECK(m_histSvc.retrieve());
27  return StatusCode::SUCCESS;
28 }

◆ invokeFillers()

void GenericMonitoringTool::invokeFillers ( const std::vector< std::reference_wrapper< Monitored::IMonitoredVariable >> &  monitoredVariables) const

feed the fillers

Definition at line 164 of file GenericMonitoringTool.cxx.

164  {
165  // This is the list of fillers to consider in the invocation.
166  // If we are using the cache then this may be a proper subset of m_fillers; otherwise will just be m_fillers
167  const std::vector<std::shared_ptr<Monitored::HistogramFiller>>* fillerList{nullptr};
168  // do we need to update the cache?
169  bool makeCache = false;
170  // pointer to list of matched fillers, if we need to update the cache (default doesn't create the vector)
171  std::unique_ptr<std::vector<std::shared_ptr<Monitored::HistogramFiller>>> matchedFillerList;
172  if (m_useCache) {
173  // lock the cache during lookup
174  std::scoped_lock cacheguard(m_cacheMutex);
175  const auto match = m_fillerCacheMap.find(monitoredVariables);
176  if (match != m_fillerCacheMap.end()) {
177  fillerList = match->second.get();
178  } else {
179  fillerList = &m_fillers;
180  matchedFillerList = std::make_unique<std::vector<std::shared_ptr<Monitored::HistogramFiller>>>();
181  makeCache = true;
182  }
183  } else {
184  fillerList = &m_fillers;
185  }
186 
187  for ( auto filler: *fillerList ) {
188  tl_vars.reset();
189  const int fillerCardinality = filler->histogramVariablesNames().size() + (filler->histogramWeightName().empty() ? 0: 1) + (filler->histogramCutMaskName().empty() ? 0 : 1);
190 
191  if ( fillerCardinality == 1 ) { // simplest case, optimising this to be super fast
192  for ( auto& var: monitoredVariables ) {
193  if ( var.get().name().compare( filler->histogramVariablesNames()[0] ) == 0 ) {
194  tl_vars.var[0] = &var.get();
195  {
196  auto guard{filler->getLock()};
197  filler->fill( tl_vars );
198  }
199  if (makeCache) {
200  matchedFillerList->push_back(filler);
201  }
202  break;
203  }
204  }
205  } else { // a more complicated case, and cuts or weights
206  int matchesCount = 0;
207  for ( const auto& var: monitoredVariables ) {
208  bool matched = false;
209  for ( unsigned fillerVarIndex = 0; fillerVarIndex < filler->histogramVariablesNames().size(); ++fillerVarIndex ) {
210  if ( var.get().name().compare( filler->histogramVariablesNames()[fillerVarIndex] ) == 0 ) {
211  tl_vars.set(fillerVarIndex, &var.get());
212  matched = true;
213  matchesCount++;
214  break;
215  }
216  }
217  if ( matchesCount == fillerCardinality ) break;
218  if ( not matched ) { // may be a weight or cut variable still
219  if ( var.get().name().compare( filler->histogramWeightName() ) == 0 ) {
220  tl_vars.weight = &var.get();
221  matchesCount ++;
222  } else if ( var.get().name().compare( filler->histogramCutMaskName() ) == 0 ) {
223  tl_vars.cut = &var.get();
224  matchesCount++;
225  }
226  }
227  if ( matchesCount == fillerCardinality ) break;
228  }
229  if ( matchesCount == fillerCardinality ) {
230  {
231  auto guard{filler->getLock()};
232  filler->fill( tl_vars );
233  }
234  if (makeCache) {
235  matchedFillerList->push_back(filler);
236  }
237  } else if ( ATH_UNLIKELY( matchesCount != 0 ) ) { // something has matched, but not all, worth informing user
238  invokeFillersDebug(filler, monitoredVariables);
239  }
240  }
241  }
242 
243  if (makeCache) {
244  // we may hit this multiple times. If another thread has updated the cache in the meanwhile, don't update
245  // (or we might delete the fillerList under another thread)
246  std::scoped_lock cacheguard(m_cacheMutex);
247  const auto match = m_fillerCacheMap.find(monitoredVariables);
248  if (match == m_fillerCacheMap.end()) {
249  std::vector<std::string> key;
250  key.reserve(monitoredVariables.size());
251  for (const auto& mv : monitoredVariables) {
252  key.push_back(mv.get().name());
253  }
254  m_fillerCacheMap[key].swap(matchedFillerList);
255  }
256  }
257 }

◆ invokeFillersDebug()

void GenericMonitoringTool::invokeFillersDebug ( const std::shared_ptr< Monitored::HistogramFiller > &  filler,
const std::vector< std::reference_wrapper< Monitored::IMonitoredVariable >> &  monitoredVariables 
) const
private

Definition at line 259 of file GenericMonitoringTool.cxx.

260  {
261  bool reasonFound = false;
262  if (ATH_UNLIKELY(!filler->histogramWeightName().empty() && !tl_vars.weight)) {
263  reasonFound = true;
264  ATH_MSG_DEBUG("Filler weight not found in monitoredVariables:"
265  << "\n Filler weight : " << filler->histogramWeightName()
266  << "\n Asked to fill from mon. tl_vars: " << monitoredVariables);
267  }
268  if (ATH_UNLIKELY(!filler->histogramCutMaskName().empty() && !tl_vars.cut)) {
269  reasonFound = true;
270  ATH_MSG_DEBUG("Filler cut mask not found in monitoredVariables:"
271  << "\n Filler cut mask : " << filler->histogramCutMaskName()
272  << "\n Asked to fill from mon. tl_vars: " << monitoredVariables);
273  }
274  if ( not reasonFound ) {
275  ATH_MSG_DEBUG("Filler has different variables than monitoredVariables:"
276  << "\n Filler variables : " << filler->histogramVariablesNames()
277  << "\n Asked to fill from mon. tl_vars: " << monitoredVariables
278  << "\n Selected monitored variables: " << tl_vars.names() );
279  }
280 }

◆ lumiBlock()

uint32_t GenericMonitoringTool::lumiBlock ( )
virtual

Definition at line 286 of file GenericMonitoringTool.cxx.

286  {
287  return Gaudi::Hive::currentContext().eventID().lumi_block();
288 }

◆ runNumber()

uint32_t GenericMonitoringTool::runNumber ( )
virtual

Definition at line 282 of file GenericMonitoringTool.cxx.

282  {
283  return Gaudi::Hive::currentContext().eventID().run_number();
284 }

◆ setPath()

void GenericMonitoringTool::setPath ( const std::string &  newPath)
inline

Overrride configured booking path.

Definition at line 69 of file GenericMonitoringTool.h.

69 { m_histoPath = newPath; }

◆ start()

StatusCode GenericMonitoringTool::start ( )
overridevirtual

Definition at line 30 of file GenericMonitoringTool.cxx.

30  {
31  if ( not m_explicitBooking ) {
32  ATH_MSG_DEBUG("Proceeding to histogram booking");
33  return book();
34  }
35  return StatusCode::SUCCESS;
36 }

◆ stop()

StatusCode GenericMonitoringTool::stop ( )
overridevirtual

Definition at line 38 of file GenericMonitoringTool.cxx.

38  {
39  m_alwaysCreateFillers.clear();
40  m_fillers.clear();
41  if (m_registerHandler) {
42  ATH_MSG_DEBUG("Deregistering incident handler");
43  SmartIF<IIncidentSvc> incSvc{service("IncidentSvc")};
44  ATH_CHECK(incSvc.isValid());
45  incSvc->removeListener(this, IncidentType::BeginEvent);
46  }
47  return StatusCode::SUCCESS;
48 }

Member Data Documentation

◆ ATLAS_THREAD_SAFE

std::map<std::vector<std::string>,std::unique_ptr<std::vector<std::shared_ptr<Monitored::HistogramFiller> > >,std::less<> > m_fillerCacheMap GenericMonitoringTool::ATLAS_THREAD_SAFE
mutableprivate

lookup map to speed up filler searches

Definition at line 91 of file GenericMonitoringTool.h.

◆ log

GenericMonitoringTool.log = logging.getLogger(__name__)

Definition at line 9 of file GenericMonitoringTool.py.

◆ m_alwaysCreateFillers

std::vector<std::shared_ptr<Monitored::HistogramFiller> > GenericMonitoringTool::m_alwaysCreateFillers
private

fillers that need touching, usually empty

Definition at line 90 of file GenericMonitoringTool.h.

◆ m_cacheMutex

std::mutex GenericMonitoringTool::m_cacheMutex
mutableprivate

Definition at line 92 of file GenericMonitoringTool.h.

◆ m_explicitBooking

Gaudi::Property<bool> GenericMonitoringTool::m_explicitBooking { this, "ExplicitBooking", false, "Do not create histograms automatically in initialize but wait until the method book is called." }
private

Definition at line 84 of file GenericMonitoringTool.h.

◆ m_failOnEmpty

Gaudi::Property<bool> GenericMonitoringTool::m_failOnEmpty { this, "FailOnEmpty", true, "Fail in initialize() if no histograms defined" }
private

Definition at line 85 of file GenericMonitoringTool.h.

◆ m_fillers

std::vector<std::shared_ptr<Monitored::HistogramFiller> > GenericMonitoringTool::m_fillers
private

plain list of fillers

Definition at line 89 of file GenericMonitoringTool.h.

◆ m_histograms

Gaudi::Property<std::vector<std::string> > GenericMonitoringTool::m_histograms { this, "Histograms", {}, "Definitions of histograms", "OrderedSet<std::string>"}
private

Definition at line 83 of file GenericMonitoringTool.h.

◆ m_histoPath

Gaudi::Property<std::string> GenericMonitoringTool::m_histoPath { this, "HistPath", {}, "Directory for histograms [name of parent if not set]" }
private

Definition at line 82 of file GenericMonitoringTool.h.

◆ m_histSvc

ServiceHandle<ITHistSvc> GenericMonitoringTool::m_histSvc { this, "THistSvc", "THistSvc", "Histogramming svc" }
private

THistSvc (do NOT fix the service type (only the name) to allow for a different implementation online.

Definition at line 81 of file GenericMonitoringTool.h.

◆ m_registerHandler

BooleanProperty GenericMonitoringTool::m_registerHandler { this, "RegisterHandler", true, "Use incident handler to make 'always book' plots (else only check once)" }
private

Definition at line 87 of file GenericMonitoringTool.h.

◆ m_useCache

BooleanProperty GenericMonitoringTool::m_useCache { this, "UseCache", true, "Cache filler lookups" }
private

Definition at line 86 of file GenericMonitoringTool.h.


The documentation for this class was generated from the following files:
replace
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition: hcg.cxx:307
GenericMonitoringTool::m_useCache
BooleanProperty m_useCache
Definition: GenericMonitoringTool.h:86
beamspotnt.var
var
Definition: bin/beamspotnt.py:1394
Monitored::HistogramFiller::histogramVariablesNames
const std::vector< std::string > & histogramVariablesNames() const
Definition: HistogramFiller.h:132
Monitored::HistogramFiller::histogramWeightName
const std::string & histogramWeightName() const
Definition: HistogramFiller.h:136
GenericMonitoringTool::m_histoPath
Gaudi::Property< std::string > m_histoPath
Definition: GenericMonitoringTool.h:82
parse
std::map< std::string, std::string > parse(const std::string &list)
Definition: egammaLayerRecalibTool.cxx:1054
GenericMonitoringTool::m_alwaysCreateFillers
std::vector< std::shared_ptr< Monitored::HistogramFiller > > m_alwaysCreateFillers
fillers that need touching, usually empty
Definition: GenericMonitoringTool.h:90
GenericMonitoringTool::m_histograms
Gaudi::Property< std::vector< std::string > > m_histograms
Definition: GenericMonitoringTool.h:83
GenericMonitoringTool::m_registerHandler
BooleanProperty m_registerHandler
Definition: GenericMonitoringTool.h:87
ATH_UNLIKELY
#define ATH_UNLIKELY(x)
Definition: AthUnlikelyMacros.h:17
GenericMonitoringTool::book
StatusCode book()
Book histograms.
Definition: GenericMonitoringTool.cxx:56
Monitored::HistogramDef
the internal class used to keep parsed Filler properties
Definition: HistogramDef.h:15
Monitored::HistogramDef::ok
bool ok
good declaration: parsing or copying successful
Definition: HistogramDef.h:77
GenericMonitoringTool::m_explicitBooking
Gaudi::Property< bool > m_explicitBooking
Definition: GenericMonitoringTool.h:84
GenericMonitoringTool::invokeFillersDebug
void invokeFillersDebug(const std::shared_ptr< Monitored::HistogramFiller > &filler, const std::vector< std::reference_wrapper< Monitored::IMonitoredVariable >> &monitoredVariables) const
Definition: GenericMonitoringTool.cxx:259
GenericMonitoringTool::m_cacheMutex
std::mutex m_cacheMutex
Definition: GenericMonitoringTool.h:92
GenericMonitoringTool::m_failOnEmpty
Gaudi::Property< bool > m_failOnEmpty
Definition: GenericMonitoringTool.h:85
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
h
Monitored::HistogramFiller::histogramCutMaskName
const std::string & histogramCutMaskName() const
Definition: HistogramFiller.h:140
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Monitored::HistogramDef::name
std::vector< std::string > name
names of monitored variables
Definition: HistogramDef.h:16
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
MakeTH3DFromTH2Ds.hists
hists
Definition: MakeTH3DFromTH2Ds.py:72
Monitored::HistogramFillerFactory
Factory of the histogram fillers.
Definition: HistogramFillerFactory.h:22
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
python.ElectronD3PDObject.matched
matched
Definition: ElectronD3PDObject.py:138
item
Definition: ItemListSvc.h:43
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Monitored::HistogramDef::kAlwaysCreate
bool kAlwaysCreate
always create this histogram, even if never filled
Definition: HistogramDef.h:52
GenericMonitoringTool::m_fillers
std::vector< std::shared_ptr< Monitored::HistogramFiller > > m_fillers
plain list of fillers
Definition: GenericMonitoringTool.h:89
match
bool match(std::string s1, std::string s2)
match the individual directories of two strings
Definition: hcg.cxx:356
GenericMonitoringTool::m_histSvc
ServiceHandle< ITHistSvc > m_histSvc
THistSvc (do NOT fix the service type (only the name) to allow for a different implementation online.
Definition: GenericMonitoringTool.h:81
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37