12#ifndef FRAMEWORK_HISTOGRAMREGISTRY_H_
13#define FRAMEWORK_HISTOGRAMREGISTRY_H_
27#include <TDataMember.h>
31#include <TProfile2D.h>
39#define HIST(name) CONST_STR(name)
49concept FillValue = std::is_integral_v<T> || std::is_floating_point_v<T> || std::is_enum_v<T>;
51template <
typename T,
int dimensions>
52concept ValidTH3 = std::same_as<T, TH3> && (dimensions == 3 || dimensions == 4);
54template <
typename T,
int dimensions>
55concept ValidTH2 = std::same_as<T, TH2> && (dimensions == 2 || dimensions == 3);
57template <
typename T,
int dimensions>
58concept ValidTH1 = std::same_as<T, TH1> && (dimensions == 1 || dimensions == 2);
60template <
typename T,
int dimensions>
61concept ValidTProfile3D = std::same_as<T, TProfile3D> && (dimensions == 4 || dimensions == 5);
63template <
typename T,
int dimensions>
64concept ValidTProfile2D = std::same_as<T, TProfile2D> && (dimensions == 3 || dimensions == 4);
66template <
typename T,
int dimensions>
67concept ValidTProfile = std::same_as<T, TProfile> && (dimensions == 2 || dimensions == 3);
69template <
typename T,
int D>
72template <
typename T,
int D>
75template <
typename T,
int D>
78template <
typename T,
int D>
83 template <
typename T,
typename...
Ts>
84 static void fillHistAny(std::shared_ptr<T> hist,
Ts... positionAndWeight)
87 template <
typename T,
typename...
Ts>
88 static void fillHistAny(std::shared_ptr<T> hist,
Ts... positionAndWeight)
91 template <
typename T,
typename...
Ts>
92 static void fillHistAny(std::shared_ptr<T> hist,
Ts... positionAndWeight)
96 template <
typename T,
typename...
Ts>
97 static void fillHistAny(std::shared_ptr<T> hist,
Ts... positionAndWeight);
100 template <
typename... Cs,
typename R,
typename T>
105 template <
typename... Cs,
typename R,
typename T>
109 template <
typename T>
110 static double getSize(std::shared_ptr<T> hist,
double fillFraction = 1.);
114 template <
typename T>
115 static int getBaseElementSize(T*
ptr);
117 template <
typename T,
typename Next,
typename... Rest,
typename P>
118 static int getBaseElementSize(P*
ptr);
120 template <
typename B,
typename T>
121 static int getBaseElementSize(T*
ptr);
123 static void badHistogramFill(
char const*
name);
136 template <
char... chars>
138 char const*
const str{};
139 const uint32_t hash{};
140 const uint32_t idx{};
145 constexpr HistName(
char const*
const name);
154 HistPtr add(
char const*
const name,
char const*
const title,
HistType histType,
const std::vector<AxisSpec>& axes,
bool callSumw2 =
false);
155 HistPtr add(
const std::string&
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(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2 =
false);
159 template <
typename T>
160 std::shared_ptr<T>
add(
char const*
const name,
char const*
const title,
HistType histType,
const std::vector<AxisSpec>& axes,
bool callSumw2 =
false);
161 template <
typename T>
162 std::shared_ptr<T>
add(
const std::string&
name,
char const*
const title,
HistType histType,
const std::vector<AxisSpec>& axes,
bool callSumw2 =
false);
167 bool contains(
const HistName& histName);
170 template <
typename T>
171 std::shared_ptr<T>
get(
const HistName& histName);
173 template <
typename T>
174 std::shared_ptr<T>
operator()(
const HistName& histName);
190 template <
typename...
Ts>
191 void fill(
const HistName& histName,
Ts... positionAndWeight)
195 template <
typename... Cs,
typename T>
199 double getSize(
const HistName& histName,
double fillFraction = 1.);
202 double getSize(
double fillFraction = 1.);
205 void print(
bool showAxisDetails =
false);
215 template <
typename T>
216 HistPtr insertClone(
const HistName& histName,
const std::shared_ptr<T> originalHist);
219 void validateHistName(
const std::string&
name,
const uint32_t hash);
222 template <
typename T>
223 uint32_t getHistIndex(
const T& histName);
225 constexpr uint32_t imask(uint32_t
i)
const
227 return i & REGISTRY_BITMASK;
231 TList* getSubList(TList*
list, std::deque<std::string>&
path);
234 std::deque<std::string> splitPath(
const std::string& pathAndNameUser);
237 void registerName(
const std::string&
name);
242 bool mCreateRegistryDir{};
244 uint32_t mTaskHash{};
245 std::vector<std::string> mRegisteredNames{};
249 static constexpr uint32_t REGISTRY_BITMASK{0x1FF};
250 static constexpr uint32_t MAX_REGISTRY_SIZE{REGISTRY_BITMASK + 1};
251 std::array<uint32_t, MAX_REGISTRY_SIZE> mRegistryKey{};
252 std::array<HistPtr, MAX_REGISTRY_SIZE> mRegistryValue{};
263template <
typename T,
typename... Ts>
267 hist->Fill(
static_cast<double>(positionAndWeight)...);
270template <
typename T,
typename...
Ts>
274 constexpr int nArgs =
sizeof...(Ts);
276 double tempArray[] = {
static_cast<double>(positionAndWeight)...};
278 constexpr int nArgsMinusOne = nArgs - 1;
279 if (hist->GetNdimensions() == nArgsMinusOne) {
280 weight = tempArray[nArgsMinusOne];
281 }
else if (hist->GetNdimensions() != nArgs) {
282 badHistogramFill(hist->GetName());
284 hist->Fill(tempArray,
weight);
287template <
typename T,
typename... Ts>
289 requires ValidComplexFillStep<
T,
sizeof...(Ts)> && (FillValue<Ts> && ...)
291 hist->Fill(positionAndWeight...);
294template <
typename T,
typename... Ts>
297 HistFiller::badHistogramFill(hist->GetName());
300template <
typename... Cs,
typename R,
typename T>
306 for (
auto& t : filtered) {
307 fillHistAny(hist, (*(
static_cast<Cs
>(t).getIterator()))...);
311template <
typename... Cs,
typename R,
typename T>
314 HistFiller::badHistogramFill(hist->GetName());
321 if constexpr (std::is_base_of_v<TH1, T>) {
322 size = hist->GetNcells() * (HistFiller::getBaseElementSize(hist.get()) + ((hist->GetSumw2()->fN) ?
sizeof(
double) : 0.));
323 }
else if constexpr (std::is_base_of_v<THn, T>) {
324 size = hist->GetNbins() * (HistFiller::getBaseElementSize(hist.get()) + ((hist->GetSumw2() != -1.) ?
sizeof(
double) : 0.));
325 }
else if constexpr (std::is_base_of_v<THnSparse, T>) {
327 double nBinsTotal = 1.;
328 int compCoordSize = 0;
329 for (
int d = 0; d < hist->GetNdimensions(); ++d) {
330 int nBins = hist->GetAxis(d)->GetNbins() + 2;
340 compCoordSize = (compCoordSize + 7) / 8;
343 double nBinsFilled = fillFraction * nBinsTotal;
344 int nCunks = ceil(nBinsFilled / hist->GetChunkSize());
345 int chunkOverhead =
sizeof(THnSparseArrayChunk);
348 double binSize = compCoordSize + HistFiller::getBaseElementSize(hist.get()) + ((hist->GetSumw2() != -1.) ?
sizeof(
double) : 0.);
349 size = nCunks * (chunkOverhead + hist->GetChunkSize() * binSize);
353 size += nBinsFilled * 3 *
sizeof(Long64_t);
355 return size / 1048576.;
359int HistFiller::getBaseElementSize(T*
ptr)
361 if constexpr (std::is_base_of_v<TH1, T> || std::is_base_of_v<THnSparse, T>) {
362 return getBaseElementSize<TArrayD, TArrayF, TArrayC, TArrayI, TArrayC, TArrayL>(
ptr);
364 return getBaseElementSize<double, float, int, short, char, long>(
ptr);
368template <
typename T,
typename Next,
typename... Rest,
typename P>
369int HistFiller::getBaseElementSize(P*
ptr)
371 if (
auto size = getBaseElementSize<T>(
ptr)) {
374 return getBaseElementSize<Next, Rest...>(
ptr);
377template <
typename B,
typename T>
378int HistFiller::getBaseElementSize(T*
ptr)
380 if constexpr (std::is_base_of_v<THn, T>) {
381 if (
dynamic_cast<THnT<B>*
>(
ptr)) {
384 }
else if constexpr (std::is_base_of_v<THnSparse, T>) {
385 if (
dynamic_cast<THnSparseT<B>*
>(
ptr)) {
386 TDataMember* dm = B::Class()->GetDataMember(
"fArray");
387 return dm ? dm->GetDataType()->Size() : 0;
389 }
else if constexpr (std::is_base_of_v<TH1, T>) {
390 if (
auto arrayPtr =
dynamic_cast<B*
>(
ptr)) {
391 return sizeof(arrayPtr->At(0));
403template <
char... chars>
404constexpr HistogramRegistry::HistName::HistName(
const ConstStr<chars...>& hashedHistName)
405 :
str(hashedHistName.
str),
406 hash(hashedHistName.hash),
407 idx(hash & REGISTRY_BITMASK)
414 return add<T>(
name.c_str(), title, histType, axes, callSumw2);
420 if (
auto histPtr = std::get_if<std::shared_ptr<T>>(&mRegistryValue[getHistIndex(histName)])) {
423 throw runtime_error_f(R
"(Histogram type specified in get<>(HIST("%s")) does not match the actual type of the histogram!)", histName.str);
430 return get<T>(histName);
434uint32_t HistogramRegistry::getHistIndex(
const T& histName)
439 for (
auto i = 1u;
i < MAX_REGISTRY_SIZE; ++
i) {
440 if (histName.hash == mRegistryKey[imask(histName.idx +
i)]) {
441 return imask(histName.idx +
i);
444 throw runtime_error_f(R
"(Could not find histogram "%s" in HistogramRegistry "%s"!)", histName.str, mName.data());
447template <
typename... Ts>
451 std::visit([positionAndWeight...](
auto&& hist) { HistFiller::fillHistAny(hist, positionAndWeight...); }, mRegistryValue[getHistIndex(histName)]);
458extern template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<TH1>);
459extern template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<TH2>);
460extern template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<TH3>);
461extern template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<TProfile>);
462extern template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<TProfile2D>);
463extern template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<TProfile3D>);
464extern template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<THnSparse>);
465extern template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<THn>);
466extern template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<StepTHn>);
468extern template std::shared_ptr<TH1> HistogramRegistry::add<TH1>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
469extern 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);
470extern template std::shared_ptr<TH2> HistogramRegistry::add<TH2>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
471extern 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);
472extern template std::shared_ptr<TH3> HistogramRegistry::add<TH3>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
473extern 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);
474extern template std::shared_ptr<TProfile> HistogramRegistry::add<TProfile>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
475extern 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);
476extern template std::shared_ptr<TProfile2D> HistogramRegistry::add<TProfile2D>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
477extern 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);
478extern template std::shared_ptr<TProfile3D> HistogramRegistry::add<TProfile3D>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
479extern 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);
480extern template std::shared_ptr<THn> HistogramRegistry::add<THn>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
481extern 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);
482extern template std::shared_ptr<THnSparse> HistogramRegistry::add<THnSparse>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
483extern 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);
484extern template std::shared_ptr<StepTHn> HistogramRegistry::add<StepTHn>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
485extern 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);
487template <
typename... Cs,
typename T>
#define O2_BUILTIN_LIKELY(x)
Type wrappers for enfording a specific serialization method.
bool contains(const HistName &histName)
double getSize(const HistName &histName, double fillFraction=1.)
void fill(const HistName &histName, Ts... positionAndWeight)
TList * getListOfHistograms()
returns the list of histograms, properly sorted for writing.
void addClone(const std::string &source, const std::string &target)
std::shared_ptr< T > operator()(const HistName &histName)
void setHash(uint32_t hash)
HistPtr add(const HistogramSpec &histSpec)
std::shared_ptr< T > get(const HistName &histName)
void clean()
deletes all the histograms from the registry
GLuint const GLchar * name
GLuint GLuint GLfloat weight
GLboolean GLboolean GLboolean b
GLsizei GLsizei GLchar * source
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLsizei const GLchar *const * path
gandiva::Selection createSelection(std::shared_ptr< arrow::Table > const &table, Filter const &expression)
Function for creating gandiva selection from our internal filter tree.
Defining PrimaryVertex explicitly as messageable.
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.