ATLAS Offline Software
Loading...
Searching...
No Matches
HistogramFillerUtils.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 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"
15
16#include "TH1.h"
17#include "TProfile.h"
18#include "THashList.h"
19#include "TProfile2D.h"
20
21namespace Monitored {
22
24 enum Axis {X = 0, Y, Z};
25
26 namespace detail {
27
28 auto noWeight = [](size_t){ return 1.0; };
29 auto noCut = [](size_t){ return true; };
30
32 constexpr std::array axis_name{"X", "Y", "Z"};
33 constexpr std::array axis_bit{TH1::kXaxis, TH1::kYaxis, TH1::kZaxis};
34
39 template<Axis AXIS, typename H>
40 constexpr auto getAxis(H* hist) {
41 if constexpr (AXIS==Axis::X) return hist->GetXaxis();
42 else if constexpr (AXIS==Axis::Y) return hist->GetYaxis();
43 else return hist->GetZaxis();
44 }
45
55 template<Axis AXIS, typename H>
56 double getFillValue(const H* hist, const IMonitoredVariable* var, size_t i) {
57 if ( var->hasStringRepresentation() ) {
58 const TAxis* axis = getAxis<AXIS>(hist);
59 const int binNumber = axis->FindFixBin( var->getString(i).c_str() );
60 return axis->GetBinCenter(binNumber);
61 } else {
62 return var->get(i);
63 }
64 }
65
70 bool shouldRebinHistogram(const TAxis* axis, const double value) {
71 return axis ? axis->GetXmax() <= value : false;
72 }
73
88 template<Axis AXIS, typename H>
89 void rebinHistogram(H* hist, const double value) {
90 hist->SetCanExtend(axis_bit[AXIS]);
91 TAxis* a = getAxis<AXIS>(hist);
92
93 // Rebinning requires to take OH lock in online (no-op offline)
95 // Rebinning requires a lock on the global ROOT directory state
96 std::scoped_lock<std::mutex> dirLock(HistogramFactory::globalROOTMutex());
97 do {
98 // need to unset cleanup bit of parent histogram during this operation
99 // since it gets copied to a hidden temporary (probably unintentionally)
100 bool curcleanup = hist->TestBit(TObject::kMustCleanup);
101 hist->ResetBit(TObject::kMustCleanup);
102 hist->LabelsInflate(axis_name[AXIS]);
103 hist->SetBit(TObject::kMustCleanup, curcleanup);
104 } while (shouldRebinHistogram(a, value));
105 }
106
112 template<typename T>
113 bool fillWillRebinHistogram(const TAxis* axis, T value) {
114 if (not axis) return false;
115 const int bin = axis->FindFixBin(value);
116 // if under/overflow
117 if ( bin==0 or bin==axis->GetNbins()+1 ) {
118 return true;
119 }
120 return false;
121 }
122
129 template<>
130 bool fillWillRebinHistogram(const TAxis* axis, const char* value) {
131 // valid bin found
132 if ( not axis or axis->FindFixBin(value)>0 ) return false;
133
134 // If there are no labels yet at least one unlabeled bin is available
135 const THashList* labels = axis->GetLabels();
136 if ( not labels ) return false;
137
138 return true;
139 }
140
148 template<typename H, typename T, T... a, typename ...Vs>
149 bool fillWillRebinHistogram(H* hist, std::integer_sequence<T, a...>, const Vs&... v) {
150 // First check if axis is extensible, then if value would be outside of range
151 return (... || (getAxis<static_cast<Axis>(a)>(hist)->CanExtend() and
152 detail::fillWillRebinHistogram(getAxis<static_cast<Axis>(a)>(hist), v)));
153 }
154
163 template<typename H, typename W, typename M, typename ...Ms>
164 void doFill(H* hist, W weight, size_t i, const M& m1, const Ms&... m) {
165
166 // Template magic: Recursively convert all M to double or string
167 if constexpr(std::is_same_v<M, Monitored::IMonitoredVariable>) {
168 // For >=2D: If one variable has a single entry, do repeated fills with that value
169 const size_t j = m1.size()==1 ? 0 : i;
170 if (not m1.hasStringRepresentation())
171 doFill(hist, weight, i, m..., m1.get(j));
172 else
173 doFill(hist, weight, i, m..., m1.getString(j).c_str());
174 } else {
175 // In case re-binning occurs need to take the OH lock for online (no-op offline)
176 if ( ATH_UNLIKELY(fillWillRebinHistogram(hist, std::index_sequence_for<M, Ms...>{},
177 m1, m...)) ){
179 // Rebinning requires a lock on the global ROOT directory state
180 std::scoped_lock<std::mutex> dirLock(HistogramFactory::globalROOTMutex());
181 hist->Fill(m1, m..., weight(i));
182 }
183 else hist->Fill(m1, m..., weight(i));
184 }
185 }
186
187 // TProfile does not support string as y-value.
188 // (this terminates the above pack expansion)
189 template<typename W>
190 void doFill(TProfile*, W, size_t, const double&, const char* const&) {}
191 template<typename W>
192 void doFill(TProfile*, W, size_t, const char* const&, const char* const&) {}
193 template<typename W>
194 void doFill(TProfile2D*, W, size_t, const double&, const double&, const char* const&) {}
195 template<typename W>
196 void doFill(TProfile2D*, W, size_t, const char* const&, const char* const&, const char* const&) {}
197 template<typename W>
198 void doFill(TProfile2D*, W, size_t, const char* const&, const double&, const char* const&) {}
199 template<typename W>
200 void doFill(TProfile2D*, W, size_t, const double&, const char* const&, const char* const&) {}
201 }
202}
203
204#endif
#define ATH_UNLIKELY(x)
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.