ATLAS Offline Software
Loading...
Searching...
No Matches
HistogramFillerUtils.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#ifndef AthenaMonitoringKernel_HistogramFillerUtils_h
6#define AthenaMonitoringKernel_HistogramFillerUtils_h
7
8#include <algorithm>
9#include <utility>
10
13#include "HistogramFactory.h"
14
15#include "TH1.h"
16#include "TProfile.h"
17#include "THashList.h"
18#include "TProfile2D.h"
19
20namespace Monitored {
21
23 enum Axis {X = 0, Y, Z};
24
25 namespace detail {
26
27 auto noWeight = [](size_t){ return 1.0; };
28 auto noCut = [](size_t){ return true; };
29
31 constexpr std::array axis_name{"X", "Y", "Z"};
32 constexpr std::array axis_bit{TH1::kXaxis, TH1::kYaxis, TH1::kZaxis};
33
38 template<Axis AXIS, typename H>
39 constexpr auto getAxis(H* hist) {
40 if constexpr (AXIS==Axis::X) return hist->GetXaxis();
41 else if constexpr (AXIS==Axis::Y) return hist->GetYaxis();
42 else return hist->GetZaxis();
43 }
44
54 template<Axis AXIS, typename H>
55 double getFillValue(const H* hist, const IMonitoredVariable* var, size_t i) {
56 if ( var->hasStringRepresentation() ) {
57 const TAxis* axis = getAxis<AXIS>(hist);
58 const int binNumber = axis->FindFixBin( var->getString(i).c_str() );
59 return axis->GetBinCenter(binNumber);
60 } else {
61 return var->get(i);
62 }
63 }
64
69 bool shouldRebinHistogram(const TAxis* axis, const double value) {
70 return axis ? axis->GetXmax() <= value : false;
71 }
72
87 template<Axis AXIS, typename H>
88 void rebinHistogram(H* hist, const double value) {
89 hist->SetCanExtend(axis_bit[AXIS]);
90 TAxis* a = getAxis<AXIS>(hist);
91
92 // Rebinning requires to take OH lock in online (no-op offline)
94 // Rebinning requires a lock on the global ROOT directory state
95 std::scoped_lock<std::mutex> dirLock(HistogramFactory::globalROOTMutex());
96 do {
97 // need to unset cleanup bit of parent histogram during this operation
98 // since it gets copied to a hidden temporary (probably unintentionally)
99 bool curcleanup = hist->TestBit(TObject::kMustCleanup);
100 hist->ResetBit(TObject::kMustCleanup);
101 hist->LabelsInflate(axis_name[AXIS]);
102 hist->SetBit(TObject::kMustCleanup, curcleanup);
103 } while (shouldRebinHistogram(a, value));
104 }
105
111 template<typename T>
112 bool fillWillRebinHistogram(const TAxis* axis, T value) {
113 if (not axis) return false;
114 const int bin = axis->FindFixBin(value);
115 // if under/overflow
116 if ( bin==0 or bin==axis->GetNbins()+1 ) {
117 return true;
118 }
119 return false;
120 }
121
128 template<>
129 bool fillWillRebinHistogram(const TAxis* axis, const char* value) {
130 // valid bin found
131 if ( not axis or axis->FindFixBin(value)>0 ) return false;
132
133 // If there are no labels yet at least one unlabeled bin is available
134 const THashList* labels = axis->GetLabels();
135 if ( not labels ) return false;
136
137 return true;
138 }
139
147 template<typename H, typename T, T... a, typename ...Vs>
148 bool fillWillRebinHistogram(H* hist, std::integer_sequence<T, a...>, const Vs&... v) {
149 // First check if axis is extensible, then if value would be outside of range
150 return (... || (getAxis<static_cast<Axis>(a)>(hist)->CanExtend() and
151 detail::fillWillRebinHistogram(getAxis<static_cast<Axis>(a)>(hist), v)));
152 }
153
162 template<typename H, typename W, typename M, typename ...Ms>
163 void doFill(H* hist, W weight, size_t i, const M& m1, const Ms&... m) {
164
165 // Template magic: Recursively convert all M to double or string
166 if constexpr(std::is_same_v<M, Monitored::IMonitoredVariable>) {
167 // For >=2D: If one variable has a single entry, do repeated fills with that value
168 const size_t j = m1.size()==1 ? 0 : i;
169 if (not m1.hasStringRepresentation())
170 doFill(hist, weight, i, m..., m1.get(j));
171 else
172 doFill(hist, weight, i, m..., m1.getString(j).c_str());
173 } else {
174 // In case re-binning occurs need to take the OH lock for online (no-op offline)
175 if (fillWillRebinHistogram(hist, std::index_sequence_for<M, Ms...>{},
176 m1, m...)) [[unlikely]] {
178 // Rebinning requires a lock on the global ROOT directory state
179 std::scoped_lock<std::mutex> dirLock(HistogramFactory::globalROOTMutex());
180 hist->Fill(m1, m..., weight(i));
181 }
182 else hist->Fill(m1, m..., weight(i));
183 }
184 }
185
186 // TProfile does not support string as y-value.
187 // (this terminates the above pack expansion)
188 template<typename W>
189 void doFill(TProfile*, W, size_t, const double&, const char* const&) {}
190 template<typename W>
191 void doFill(TProfile*, W, size_t, const char* const&, const char* const&) {}
192 template<typename W>
193 void doFill(TProfile2D*, W, size_t, const double&, const double&, const char* const&) {}
194 template<typename W>
195 void doFill(TProfile2D*, W, size_t, const char* const&, const char* const&, const char* const&) {}
196 template<typename W>
197 void doFill(TProfile2D*, W, size_t, const char* const&, const double&, const char* const&) {}
198 template<typename W>
199 void doFill(TProfile2D*, W, size_t, const double&, const char* const&, const char* const&) {}
200 }
201}
202
203#endif
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
static Double_t a
#define H(x, y, z)
Definition MD5.cxx:114
OH histogram lock header file.
static std::mutex & globalROOTMutex()
Scoped lock to be used for threaded histogram operations.
bool fillWillRebinHistogram(const TAxis *axis, T value)
Check if Fill would result in rebinning.
constexpr auto getAxis(H *hist)
Helper to get corresponding TAxis selected by Monitored::Axis.
auto noWeight
no weight for filling
void doFill(H *hist, W weight, size_t i, const M &m1, const Ms &... m)
Perform (arbitrary dimension) histogram fill with weight.
constexpr std::array axis_bit
constexpr std::array axis_name
Convert axis to ROOT-compatible character.
bool shouldRebinHistogram(const TAxis *axis, const double value)
Method checks if histogram should be rebinned.
auto noCut
no cut for filling
double getFillValue(const H *hist, const IMonitoredVariable *var, size_t i)
Return value for filling i'th entry of var into AXIS for hist.
void rebinHistogram(H *hist, const double value)
Method that rebins a histogram.
Generic monitoring tool for athena components.
Axis
Helper type for histogram axis selection.
#define unlikely(x)