Project
Loading...
Searching...
No Matches
HistogramRegistry.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#ifndef FRAMEWORK_HISTOGRAMREGISTRY_H_
13#define FRAMEWORK_HISTOGRAMREGISTRY_H_
14
16#include "Framework/OutputRef.h"
21#include "StepTHn.h"
22
23#include <TDataMember.h>
24#include <TDataType.h>
25#include <TArrayL.h>
26#include <THnSparse.h>
27#include <TProfile2D.h>
28#include <fmt/core.h>
29
30#include <concepts>
31#include <deque>
32
33class TList;
34
35#define HIST(name) CONST_STR(name)
36
37namespace o2::framework
38{
39//**************************************************************************************************
43//**************************************************************************************************
44template <typename T>
45concept FillValue = std::is_integral_v<T> || std::is_floating_point_v<T> || std::is_enum_v<T>;
46
47template <typename T, int dimensions>
48concept ValidTH3 = std::same_as<T, TH3> && (dimensions == 3 || dimensions == 4);
49
50template <typename T, int dimensions>
51concept ValidTH2 = std::same_as<T, TH2> && (dimensions == 2 || dimensions == 3);
52
53template <typename T, int dimensions>
54concept ValidTH1 = std::same_as<T, TH1> && (dimensions == 1 || dimensions == 2);
55
56template <typename T, int dimensions>
57concept ValidTProfile3D = std::same_as<T, TProfile3D> && (dimensions == 4 || dimensions == 5);
58
59template <typename T, int dimensions>
60concept ValidTProfile2D = std::same_as<T, TProfile2D> && (dimensions == 3 || dimensions == 4);
61
62template <typename T, int dimensions>
63concept ValidTProfile = std::same_as<T, TProfile> && (dimensions == 2 || dimensions == 3);
64
65template <typename T, int D>
67
68template <typename T, int D>
69concept ValidComplexFill = std::is_base_of_v<THnBase, T>;
70
71template <typename T, int D>
72concept ValidComplexFillStep = std::is_base_of_v<StepTHn, T>;
73
74template <typename T, int D>
76
77struct HistFiller {
78 // fill any type of histogram (if weight was requested it must be the last argument)
79 template <typename T, typename... Ts>
80 static void fillHistAny(std::shared_ptr<T> hist, Ts... positionAndWeight)
81 requires ValidSimpleFill<T, sizeof...(Ts)> && (FillValue<Ts> && ...);
82
83 template <typename T, typename... Ts>
84 static void fillHistAny(std::shared_ptr<T> hist, Ts... positionAndWeight)
85 requires ValidComplexFill<T, sizeof...(Ts)> && (FillValue<Ts> && ...);
86
87 template <typename T, typename... Ts>
88 static void fillHistAny(std::shared_ptr<T> hist, Ts... positionAndWeight)
89 requires ValidComplexFillStep<T, sizeof...(Ts)> && (FillValue<Ts> && ...);
90
91 // This applies only for the non-viable cases
92 template <typename T, typename... Ts>
93 static void fillHistAny(std::shared_ptr<T> hist, Ts... positionAndWeight);
94
95 // fill any type of histogram with columns (Cs) of a filtered table (if weight is requested it must reside the last specified column)
96 template <typename... Cs, typename R, typename T>
97 static void fillHistAny(std::shared_ptr<R> hist, const T& table, const o2::framework::expressions::Filter& filter)
98 requires(!ValidComplexFillStep<R, sizeof...(Cs)>) && requires(T t) { t.asArrowTable(); };
99
100 // fill any type of histogram with columns (Cs) of a filtered table (if weight is requested it must reside the last specified column)
101 template <typename... Cs, typename R, typename T>
102 static void fillHistAny(std::shared_ptr<R> hist, const T& table, const o2::framework::expressions::Filter& filter);
103
104 // function that returns rough estimate for the size of a histogram in MB
105 template <typename T>
106 static double getSize(std::shared_ptr<T> hist, double fillFraction = 1.);
107
108 private:
109 // helper function to determine base element size of histograms (in bytes)
110 template <typename T>
111 static int getBaseElementSize(T* ptr);
112
113 template <typename T, typename Next, typename... Rest, typename P>
114 static int getBaseElementSize(P* ptr);
115
116 template <typename B, typename T>
117 static int getBaseElementSize(T* ptr);
118
119 static void badHistogramFill(char const* name);
120};
121
122//**************************************************************************************************
126//**************************************************************************************************
128{
129 // HistogramName class providing the associated hash and a first guess for the index in the registry
130 struct HistName {
131 // ctor for histogram names that are already hashed at compile time via HIST("myHistName")
132 template <char... chars>
133 constexpr HistName(const ConstStr<chars...>& hashedHistName);
134 char const* const str{};
135 const uint32_t hash{};
136 const uint32_t idx{};
137
138 protected:
139 friend class HistogramRegistry;
140 // ctor that does the hashing at runtime (for internal use only)
141 constexpr HistName(char const* const name);
142 };
143
144 public:
145 HistogramRegistry(char const* const name = "histograms", std::vector<HistogramSpec> histSpecs = {}, OutputObjHandlingPolicy policy = OutputObjHandlingPolicy::AnalysisObject, bool sortHistos = false, bool createRegistryDir = false);
146
147 // functions to add histograms to the registry
148 HistPtr add(const HistogramSpec& histSpec);
149 HistPtr add(char const* const name, char const* const title, const HistogramConfigSpec& histConfigSpec, bool callSumw2 = false);
150 HistPtr add(char const* const name, char const* const title, HistType histType, const std::vector<AxisSpec>& axes, bool callSumw2 = false);
151 HistPtr add(const std::string& name, char const* const title, HistType histType, const std::vector<AxisSpec>& axes, bool callSumw2 = false);
152
153 template <typename T>
154 std::shared_ptr<T> add(char const* const name, char const* const title, const HistogramConfigSpec& histConfigSpec, bool callSumw2 = false);
155 template <typename T>
156 std::shared_ptr<T> add(char const* const name, char const* const title, HistType histType, const std::vector<AxisSpec>& axes, bool callSumw2 = false);
157 template <typename T>
158 std::shared_ptr<T> add(const std::string& name, char const* const title, HistType histType, const std::vector<AxisSpec>& axes, bool callSumw2 = false);
159
160 void addClone(const std::string& source, const std::string& target);
161
162 // function to query if name is already in use
163 bool contains(const HistName& histName);
164
165 // get the underlying histogram pointer
166 template <typename T>
167 std::shared_ptr<T> get(const HistName& histName);
168
169 template <typename T>
170 std::shared_ptr<T> operator()(const HistName& histName);
171
172 // Apply @a callback on every single entry in the registry
173 void apply(std::function<void(HistogramRegistry const&, TNamed* named)> callback) const;
174 // return the OutputSpec associated to the HistogramRegistry
175 OutputSpec const spec();
176
177 OutputRef ref(uint16_t idx, uint16_t pipelineSize) const;
178
179 void setHash(uint32_t hash);
180
182 void clean();
183
184 // fill hist with values
185 template <typename... Ts>
186 void fill(const HistName& histName, Ts... positionAndWeight)
187 requires(FillValue<Ts> && ...);
188
189 // fill hist with content of (filtered) table columns
190 template <typename... Cs, typename T>
191 void fill(const HistName& histName, const T& table, const o2::framework::expressions::Filter& filter);
192
193 // get rough estimate for size of histogram stored in registry
194 double getSize(const HistName& histName, double fillFraction = 1.);
195
196 // get rough estimate for size of all histograms stored in registry
197 double getSize(double fillFraction = 1.);
198
199 // print summary of the histograms stored in registry
200 void print(bool showAxisDetails = false);
201
202 // lookup distance counter for benchmarking
203 mutable uint32_t lookup = 0;
204
205 private:
206 // create histogram from specification and insert it into the registry
207 HistPtr insert(const HistogramSpec& histSpec);
208
209 // clone an existing histogram and insert it into the registry
210 template <typename T>
211 HistPtr insertClone(const HistName& histName, const std::shared_ptr<T> originalHist);
212
213 // helper function that checks if histogram name can be used in registry
214 void validateHistName(const std::string& name, const uint32_t hash);
215
216 // helper function to find the histogram position in the registry
217 template <typename T>
218 uint32_t getHistIndex(const T& histName) const;
219
220 constexpr uint32_t imask(uint32_t i) const
221 {
222 return i & REGISTRY_BITMASK;
223 }
224
225 // helper function to split user defined path/to/hist/name string
226 std::deque<std::string> splitPath(const std::string& pathAndNameUser);
227
228 // helper function that checks if name of histogram is reasonable and keeps track of names already in use
229 void registerName(const std::string& name);
230
231 std::string mName{};
232 uint32_t nameHash;
233 OutputObjHandlingPolicy mPolicy{};
234 bool mCreateRegistryDir{};
235 bool mSortHistos{};
236 uint32_t mTaskHash{};
237 std::vector<std::string> mRegisteredNames{};
238
239 // the maximum number of histograms in buffer is currently set to 512
240 // which seems to be both reasonably large and allowing for very fast lookup
241 static constexpr uint32_t REGISTRY_BITMASK{0x1FF};
242 static constexpr uint32_t MAX_REGISTRY_SIZE{REGISTRY_BITMASK + 1};
243 std::array<uint32_t, MAX_REGISTRY_SIZE> mRegistryKey{};
244 std::array<HistPtr, MAX_REGISTRY_SIZE> mRegistryValue{};
245};
246
247template <typename T>
248concept is_histogram_registry = std::same_as<T, HistogramRegistry>;
249
250//--------------------------------------------------------------------------------------------------
251//--------------------------------------------------------------------------------------------------
252// Implementation of HistFiller template functions.
253//--------------------------------------------------------------------------------------------------
254//--------------------------------------------------------------------------------------------------
255template <typename T, typename... Ts>
256void HistFiller::fillHistAny(std::shared_ptr<T> hist, Ts... positionAndWeight)
257 requires ValidSimpleFill<T, sizeof...(Ts)> && (FillValue<Ts> && ...)
258{
259 hist->Fill(static_cast<double>(positionAndWeight)...);
260}
261
262template <typename T, typename... Ts>
263void HistFiller::fillHistAny(std::shared_ptr<T> hist, Ts... positionAndWeight)
264 requires ValidComplexFill<T, sizeof...(Ts)> && (FillValue<Ts> && ...)
265{
266 constexpr int nArgs = sizeof...(Ts);
267
268 double tempArray[] = {static_cast<double>(positionAndWeight)...};
269 double weight{1.};
270 constexpr int nArgsMinusOne = nArgs - 1;
271 if (hist->GetNdimensions() == nArgsMinusOne) {
272 weight = tempArray[nArgsMinusOne];
273 } else if (hist->GetNdimensions() != nArgs) {
274 badHistogramFill(hist->GetName());
275 }
276 hist->Fill(tempArray, weight);
277}
278
279template <typename T, typename... Ts>
280void HistFiller::fillHistAny(std::shared_ptr<T> hist, Ts... positionAndWeight)
281 requires ValidComplexFillStep<T, sizeof...(Ts)> && (FillValue<Ts> && ...)
282{
283 hist->Fill(positionAndWeight...); // first argument in pack is iStep, dimension check is done in StepTHn itself
284}
285
286template <typename T, typename... Ts>
287void HistFiller::fillHistAny(std::shared_ptr<T> hist, Ts... positionAndWeight)
288{
289 HistFiller::badHistogramFill(hist->GetName());
290}
291
292template <typename... Cs, typename R, typename T>
293void HistFiller::fillHistAny(std::shared_ptr<R>, const T&, const o2::framework::expressions::Filter&)
294 requires(!ValidComplexFillStep<R, sizeof...(Cs)>) && requires(T t) { t.asArrowTable(); }
295{
296}
297
298template <typename... Cs, typename R, typename T>
299void HistFiller::fillHistAny(std::shared_ptr<R>, const T&, const o2::framework::expressions::Filter&)
300{
301}
302
303template <typename T>
304double HistFiller::getSize(std::shared_ptr<T> hist, double fillFraction)
305{
306 double size{0.};
307 if constexpr (std::is_base_of_v<TH1, T>) {
308 size = hist->GetNcells() * (HistFiller::getBaseElementSize(hist.get()) + ((hist->GetSumw2()->fN) ? sizeof(double) : 0.));
309 } else if constexpr (std::is_base_of_v<THn, T>) {
310 size = hist->GetNbins() * (HistFiller::getBaseElementSize(hist.get()) + ((hist->GetSumw2() != -1.) ? sizeof(double) : 0.));
311 } else if constexpr (std::is_base_of_v<THnSparse, T>) {
312 // THnSparse has massive overhead and should only be used when histogram is large and a very small fraction of bins is filled
313 double nBinsTotal = 1.;
314 int compCoordSize = 0; // size required to store a compact coordinate representation
315 for (int d = 0; d < hist->GetNdimensions(); ++d) {
316 int nBins = hist->GetAxis(d)->GetNbins() + 2;
317 nBinsTotal *= nBins;
318
319 // number of bits needed to store compact coordinates
320 int b = 1;
321 while (nBins /= 2) {
322 ++b;
323 }
324 compCoordSize += b;
325 }
326 compCoordSize = (compCoordSize + 7) / 8; // turn bits into bytes
327
328 // THnSparse stores the data in an array of chunks (THnSparseArrayChunk), each containing a fixed number of bins (e.g. 1024 * 16)
329 double nBinsFilled = fillFraction * nBinsTotal;
330 int nCunks = ceil(nBinsFilled / hist->GetChunkSize());
331 int chunkOverhead = sizeof(THnSparseArrayChunk);
332
333 // each chunk holds array of compact bin-coordinates and an array of bin content (+ one of bin error if requested)
334 double binSize = compCoordSize + HistFiller::getBaseElementSize(hist.get()) + ((hist->GetSumw2() != -1.) ? sizeof(double) : 0.);
335 size = nCunks * (chunkOverhead + hist->GetChunkSize() * binSize);
336 // since THnSparse must keep track of all the stored bins, it stores a map that
337 // relates the compact bin coordinates (or a hash thereof) to a linear index
338 // this index determines in which chunk and therein at which position to find / store bin coordinate and content
339 size += nBinsFilled * 3 * sizeof(Long64_t); // hash, key, value; not sure why 3 are needed here...
340 }
341 return size / 1048576.;
342}
343
344template <typename T>
345int HistFiller::getBaseElementSize(T* ptr)
346{
347 if constexpr (std::is_base_of_v<TH1, T> || std::is_base_of_v<THnSparse, T>) {
348 return getBaseElementSize<TArrayD, TArrayF, TArrayC, TArrayI, TArrayC, TArrayL>(ptr);
349 } else {
350 return getBaseElementSize<double, float, int, short, char, long>(ptr);
351 }
352}
353
354template <typename T, typename Next, typename... Rest, typename P>
355int HistFiller::getBaseElementSize(P* ptr)
356{
357 if (auto size = getBaseElementSize<T>(ptr)) {
358 return size;
359 }
360 return getBaseElementSize<Next, Rest...>(ptr);
361}
362
363template <typename B, typename T>
364int HistFiller::getBaseElementSize(T* ptr)
365{
366 if constexpr (std::is_base_of_v<THn, T>) {
367 if (dynamic_cast<THnT<B>*>(ptr)) {
368 return sizeof(B);
369 }
370 } else if constexpr (std::is_base_of_v<THnSparse, T>) {
371 if (dynamic_cast<THnSparseT<B>*>(ptr)) {
372 TDataMember* dm = B::Class()->GetDataMember("fArray");
373 return dm ? dm->GetDataType()->Size() : 0;
374 }
375 } else if constexpr (std::is_base_of_v<TH1, T>) {
376 if (auto arrayPtr = dynamic_cast<B*>(ptr)) {
377 return sizeof(arrayPtr->At(0));
378 }
379 }
380 return 0;
381}
382
383//--------------------------------------------------------------------------------------------------
384//--------------------------------------------------------------------------------------------------
385// Implementation of HistogramRegistry template functions.
386//--------------------------------------------------------------------------------------------------
387//--------------------------------------------------------------------------------------------------
388
389template <char... chars>
390constexpr HistogramRegistry::HistName::HistName(const ConstStr<chars...>& hashedHistName)
391 : str(hashedHistName.str),
392 hash(hashedHistName.hash),
393 idx(hash & REGISTRY_BITMASK)
394{
395}
396
397template <typename T>
398std::shared_ptr<T> HistogramRegistry::add(const std::string& name, char const* const title, HistType histType, const std::vector<AxisSpec>& axes, bool callSumw2)
399{
400 return add<T>(name.c_str(), title, histType, axes, callSumw2);
401}
402
403template <typename T>
404std::shared_ptr<T> HistogramRegistry::get(const HistName& histName)
405{
406 if (auto histPtr = std::get_if<std::shared_ptr<T>>(&mRegistryValue[getHistIndex(histName)])) {
407 return *histPtr;
408 } else {
409 throw runtime_error_f(R"(Histogram type specified in get<>(HIST("%s")) does not match the actual type of the histogram!)", histName.str);
410 }
411}
412
413template <typename T>
414std::shared_ptr<T> HistogramRegistry::operator()(const HistName& histName)
415{
416 return get<T>(histName);
417}
418
419template <typename T>
420uint32_t HistogramRegistry::getHistIndex(const T& histName) const
421{
422 if (O2_BUILTIN_LIKELY(histName.hash == mRegistryKey[histName.idx])) {
423 return histName.idx;
424 }
425 for (auto i = 1u; i < MAX_REGISTRY_SIZE; ++i) {
426 if (histName.hash == mRegistryKey[imask(histName.idx + i)]) {
427 return imask(histName.idx + i);
428 }
429 }
430 throw runtime_error_f(R"(Could not find histogram "%s" in HistogramRegistry "%s"!)", histName.str, mName.data());
431}
432
433template <typename... Ts>
434void HistogramRegistry::fill(const HistName& histName, Ts... positionAndWeight)
435 requires(FillValue<Ts> && ...)
436{
437 std::visit([positionAndWeight...](auto&& hist) { HistFiller::fillHistAny(hist, positionAndWeight...); }, mRegistryValue[getHistIndex(histName)]);
438}
439
440extern template void HistogramRegistry::fill(const HistName& histName, double);
441extern template void HistogramRegistry::fill(const HistName& histName, float);
442extern template void HistogramRegistry::fill(const HistName& histName, int);
443
444extern template HistPtr HistogramRegistry::insertClone(const HistName&, const std::shared_ptr<TH1>);
445extern template HistPtr HistogramRegistry::insertClone(const HistName&, const std::shared_ptr<TH2>);
446extern template HistPtr HistogramRegistry::insertClone(const HistName&, const std::shared_ptr<TH3>);
447extern template HistPtr HistogramRegistry::insertClone(const HistName&, const std::shared_ptr<TProfile>);
448extern template HistPtr HistogramRegistry::insertClone(const HistName&, const std::shared_ptr<TProfile2D>);
449extern template HistPtr HistogramRegistry::insertClone(const HistName&, const std::shared_ptr<TProfile3D>);
450extern template HistPtr HistogramRegistry::insertClone(const HistName&, const std::shared_ptr<THnSparse>);
451extern template HistPtr HistogramRegistry::insertClone(const HistName&, const std::shared_ptr<THn>);
452extern template HistPtr HistogramRegistry::insertClone(const HistName&, const std::shared_ptr<StepTHn>);
453
454extern template std::shared_ptr<TH1> HistogramRegistry::add<TH1>(char const* const name, char const* const title, const HistogramConfigSpec& histConfigSpec, bool callSumw2);
455extern template std::shared_ptr<TH1> HistogramRegistry::add<TH1>(char const* const name, char const* const title, HistType histType, const std::vector<AxisSpec>& axes, bool callSumw2);
456extern template std::shared_ptr<TH2> HistogramRegistry::add<TH2>(char const* const name, char const* const title, const HistogramConfigSpec& histConfigSpec, bool callSumw2);
457extern template std::shared_ptr<TH2> HistogramRegistry::add<TH2>(char const* const name, char const* const title, HistType histType, const std::vector<AxisSpec>& axes, bool callSumw2);
458extern template std::shared_ptr<TH3> HistogramRegistry::add<TH3>(char const* const name, char const* const title, const HistogramConfigSpec& histConfigSpec, bool callSumw2);
459extern template std::shared_ptr<TH3> HistogramRegistry::add<TH3>(char const* const name, char const* const title, HistType histType, const std::vector<AxisSpec>& axes, bool callSumw2);
460extern template std::shared_ptr<TProfile> HistogramRegistry::add<TProfile>(char const* const name, char const* const title, const HistogramConfigSpec& histConfigSpec, bool callSumw2);
461extern template std::shared_ptr<TProfile> HistogramRegistry::add<TProfile>(char const* const name, char const* const title, HistType histType, const std::vector<AxisSpec>& axes, bool callSumw2);
462extern template std::shared_ptr<TProfile2D> HistogramRegistry::add<TProfile2D>(char const* const name, char const* const title, const HistogramConfigSpec& histConfigSpec, bool callSumw2);
463extern template std::shared_ptr<TProfile2D> HistogramRegistry::add<TProfile2D>(char const* const name, char const* const title, HistType histType, const std::vector<AxisSpec>& axes, bool callSumw2);
464extern template std::shared_ptr<TProfile3D> HistogramRegistry::add<TProfile3D>(char const* const name, char const* const title, const HistogramConfigSpec& histConfigSpec, bool callSumw2);
465extern template std::shared_ptr<TProfile3D> HistogramRegistry::add<TProfile3D>(char const* const name, char const* const title, HistType histType, const std::vector<AxisSpec>& axes, bool callSumw2);
466extern template std::shared_ptr<THn> HistogramRegistry::add<THn>(char const* const name, char const* const title, const HistogramConfigSpec& histConfigSpec, bool callSumw2);
467extern template std::shared_ptr<THn> HistogramRegistry::add<THn>(char const* const name, char const* const title, HistType histType, const std::vector<AxisSpec>& axes, bool callSumw2);
468extern template std::shared_ptr<THnSparse> HistogramRegistry::add<THnSparse>(char const* const name, char const* const title, const HistogramConfigSpec& histConfigSpec, bool callSumw2);
469extern template std::shared_ptr<THnSparse> HistogramRegistry::add<THnSparse>(char const* const name, char const* const title, HistType histType, const std::vector<AxisSpec>& axes, bool callSumw2);
470extern template std::shared_ptr<StepTHn> HistogramRegistry::add<StepTHn>(char const* const name, char const* const title, const HistogramConfigSpec& histConfigSpec, bool callSumw2);
471extern template std::shared_ptr<StepTHn> HistogramRegistry::add<StepTHn>(char const* const name, char const* const title, HistType histType, const std::vector<AxisSpec>& axes, bool callSumw2);
472
473template <typename... Cs, typename T>
474void HistogramRegistry::fill(const HistName& histName, const T& table, const o2::framework::expressions::Filter& filter)
475{
476 std::visit([&table, &filter](auto&& hist) { HistFiller::fillHistAny<Cs...>(hist, table, filter); }, mRegistryValue[getHistIndex(histName)]);
477}
478} // namespace o2::framework
479#endif // FRAMEWORK_HISTOGRAMREGISTRY_H_
#define O2_BUILTIN_LIKELY(x)
uint32_t hash
void print() const
int32_t i
TBranch * ptr
Definition B.h:16
bool contains(const HistName &histName)
double getSize(const HistName &histName, double fillFraction=1.)
void fill(const HistName &histName, Ts... positionAndWeight)
void addClone(const std::string &source, const std::string &target)
std::shared_ptr< T > operator()(const HistName &histName)
HistPtr add(const HistogramSpec &histSpec)
void apply(std::function< void(HistogramRegistry const &, TNamed *named)> callback) const
std::shared_ptr< T > get(const HistName &histName)
void clean()
deletes all the histograms from the registry
GLsizeiptr size
Definition glcorearb.h:659
GLuint const GLchar * name
Definition glcorearb.h:781
GLuint GLuint GLfloat weight
Definition glcorearb.h:5477
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLsizei GLsizei GLchar * source
Definition glcorearb.h:798
GLenum target
Definition glcorearb.h:1641
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition glcorearb.h:1308
GLint ref
Definition glcorearb.h:291
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
std::variant< std::shared_ptr< THn >, std::shared_ptr< THnSparse >, std::shared_ptr< TH3 >, std::shared_ptr< TH2 >, std::shared_ptr< TH1 >, std::shared_ptr< TProfile3D >, std::shared_ptr< TProfile2D >, std::shared_ptr< TProfile >, std::shared_ptr< StepTHn > > HistPtr
RuntimeErrorRef runtime_error_f(const char *,...)
OutputObjHandlingPolicy
Policy enum to determine OutputObj handling when writing.
static void fillHistAny(std::shared_ptr< T > hist, Ts... positionAndWeight)
static void fillHistAny(std::shared_ptr< T > hist, Ts... positionAndWeight)
static void fillHistAny(std::shared_ptr< R > hist, const T &table, const o2::framework::expressions::Filter &filter)
static double getSize(std::shared_ptr< T > hist, double fillFraction=1.)
static void fillHistAny(std::shared_ptr< T > hist, Ts... positionAndWeight)
static void fillHistAny(std::shared_ptr< T > hist, Ts... positionAndWeight)
A struct, containing the root of the expression tree.
const std::string str