ATLAS Offline Software
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 
21 namespace 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
OHLockedHist.h
OH histogram lock header file.
beamspotnt.var
var
Definition: bin/beamspotnt.py:1394
python.SystemOfUnits.m
int m
Definition: SystemOfUnits.py:91
IMonitoredVariable.h
JetTiledMap::W
@ W
Definition: TiledEtaPhiMap.h:44
Monitored::Z
@ Z
Definition: HistogramFillerUtils.h:24
plotmaker.hist
hist
Definition: plotmaker.py:148
beamspotCutsPlots.labels
list labels
Definition: beamspotCutsPlots.py:38
Monitored::detail::getFillValue
double getFillValue(const H *hist, const IMonitoredVariable *var, size_t i)
Return value for filling i'th entry of var into AXIS for hist.
Definition: HistogramFillerUtils.h:56
yodamerge_tmp.axis
list axis
Definition: yodamerge_tmp.py:241
Monitored::detail::axis_name
constexpr std::array axis_name
Convert axis to ROOT-compatible character.
Definition: HistogramFillerUtils.h:32
TProfile2D
Definition: rootspy.cxx:531
bin
Definition: BinsDiffFromStripMedian.h:43
athena.value
value
Definition: athena.py:122
detail
Definition: extract_histogram_tag.cxx:14
ATH_UNLIKELY
#define ATH_UNLIKELY(x)
Definition: AthUnlikelyMacros.h:17
Monitored::X
@ X
Definition: HistogramFillerUtils.h:24
oh_scoped_lock_histogram
Scoped lock to be used for threaded histogram operations.
Definition: OHLockedHist.h:108
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:200
AthUnlikelyMacros.h
Monitored::detail::noCut
auto noCut
no cut for filling
Definition: HistogramFillerUtils.h:29
Monitored::detail::doFill
void doFill(H *hist, W weight, size_t i, const M &m1, const Ms &... m)
Perform (arbitrary dimension) histogram fill with weight.
Definition: HistogramFillerUtils.h:164
Monitored::IMonitoredVariable
Definition: IMonitoredVariable.h:14
H
#define H(x, y, z)
Definition: MD5.cxx:114
python.changerun.m1
m1
Definition: changerun.py:32
Monitored::detail::rebinHistogram
void rebinHistogram(H *hist, const double value)
Method that rebins a histogram.
Definition: HistogramFillerUtils.h:89
Monitored::detail::getAxis
constexpr auto getAxis(H *hist)
Helper to get corresponding TAxis selected by Monitored::Axis.
Definition: HistogramFillerUtils.h:40
lumiFormat.i
int i
Definition: lumiFormat.py:92
Monitored
Generic monitoring tool for athena components.
Definition: GenericMonitoringTool.h:30
lumiFormat.array
array
Definition: lumiFormat.py:98
Monitored::Y
@ Y
Definition: HistogramFillerUtils.h:24
Monitored::detail::noWeight
auto noWeight
no weight for filling
Definition: HistogramFillerUtils.h:28
TProfile
Definition: rootspy.cxx:515
Monitored::HistogramFactory::globalROOTMutex
static std::mutex & globalROOTMutex()
Definition: HistogramFactory.h:68
python.PyAthena.v
v
Definition: PyAthena.py:157
HistogramFactory.h
a
TList * a
Definition: liststreamerinfos.cxx:10
Monitored::Axis
Axis
Helper type for histogram axis selection.
Definition: HistogramFillerUtils.h:24
Monitored::detail::fillWillRebinHistogram
bool fillWillRebinHistogram(const TAxis *axis, T value)
Check if Fill would result in rebinning.
Definition: HistogramFillerUtils.h:113
Monitored::detail::axis_bit
constexpr std::array axis_bit
Definition: HistogramFillerUtils.h:33
Monitored::detail::shouldRebinHistogram
bool shouldRebinHistogram(const TAxis *axis, const double value)
Method checks if histogram should be rebinned.
Definition: HistogramFillerUtils.h:70