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);
181 OutputRef ref(uint16_t idx, uint16_t pipelineSize)
const;
189 template <
typename...
Ts>
190 void fill(
const HistName& histName,
Ts... positionAndWeight)
194 template <
typename... Cs,
typename T>
198 double getSize(
const HistName& histName,
double fillFraction = 1.);
201 double getSize(
double fillFraction = 1.);
204 void print(
bool showAxisDetails =
false);
214 template <
typename T>
215 HistPtr insertClone(
const HistName& histName,
const std::shared_ptr<T> originalHist);
218 void validateHistName(
const std::string&
name,
const uint32_t hash);
221 template <
typename T>
222 uint32_t getHistIndex(
const T& histName)
const;
224 constexpr uint32_t imask(uint32_t
i)
const
226 return i & REGISTRY_BITMASK;
230 std::deque<std::string> splitPath(
const std::string& pathAndNameUser);
233 void registerName(
const std::string&
name);
238 bool mCreateRegistryDir{};
240 uint32_t mTaskHash{};
241 std::vector<std::string> mRegisteredNames{};
245 static constexpr uint32_t REGISTRY_BITMASK{0x1FF};
246 static constexpr uint32_t MAX_REGISTRY_SIZE{REGISTRY_BITMASK + 1};
247 std::array<uint32_t, MAX_REGISTRY_SIZE> mRegistryKey{};
248 std::array<HistPtr, MAX_REGISTRY_SIZE> mRegistryValue{};
259template <
typename T,
typename... Ts>
263 hist->Fill(
static_cast<double>(positionAndWeight)...);
266template <
typename T,
typename...
Ts>
270 constexpr int nArgs =
sizeof...(Ts);
272 double tempArray[] = {
static_cast<double>(positionAndWeight)...};
274 constexpr int nArgsMinusOne = nArgs - 1;
275 if (hist->GetNdimensions() == nArgsMinusOne) {
276 weight = tempArray[nArgsMinusOne];
277 }
else if (hist->GetNdimensions() != nArgs) {
278 badHistogramFill(hist->GetName());
280 hist->Fill(tempArray,
weight);
283template <
typename T,
typename... Ts>
285 requires ValidComplexFillStep<
T,
sizeof...(Ts)> && (FillValue<Ts> && ...)
287 hist->Fill(positionAndWeight...);
290template <
typename T,
typename... Ts>
293 HistFiller::badHistogramFill(hist->GetName());
296template <
typename... Cs,
typename R,
typename T>
302 for (
auto& t : filtered) {
303 fillHistAny(hist, (*(
static_cast<Cs
>(t).getIterator()))...);
307template <
typename... Cs,
typename R,
typename T>
310 HistFiller::badHistogramFill(hist->GetName());
317 if constexpr (std::is_base_of_v<TH1, T>) {
318 size = hist->GetNcells() * (HistFiller::getBaseElementSize(hist.get()) + ((hist->GetSumw2()->fN) ?
sizeof(
double) : 0.));
319 }
else if constexpr (std::is_base_of_v<THn, T>) {
320 size = hist->GetNbins() * (HistFiller::getBaseElementSize(hist.get()) + ((hist->GetSumw2() != -1.) ?
sizeof(
double) : 0.));
321 }
else if constexpr (std::is_base_of_v<THnSparse, T>) {
323 double nBinsTotal = 1.;
324 int compCoordSize = 0;
325 for (
int d = 0; d < hist->GetNdimensions(); ++d) {
326 int nBins = hist->GetAxis(d)->GetNbins() + 2;
336 compCoordSize = (compCoordSize + 7) / 8;
339 double nBinsFilled = fillFraction * nBinsTotal;
340 int nCunks = ceil(nBinsFilled / hist->GetChunkSize());
341 int chunkOverhead =
sizeof(THnSparseArrayChunk);
344 double binSize = compCoordSize + HistFiller::getBaseElementSize(hist.get()) + ((hist->GetSumw2() != -1.) ?
sizeof(
double) : 0.);
345 size = nCunks * (chunkOverhead + hist->GetChunkSize() * binSize);
349 size += nBinsFilled * 3 *
sizeof(Long64_t);
351 return size / 1048576.;
355int HistFiller::getBaseElementSize(T*
ptr)
357 if constexpr (std::is_base_of_v<TH1, T> || std::is_base_of_v<THnSparse, T>) {
358 return getBaseElementSize<TArrayD, TArrayF, TArrayC, TArrayI, TArrayC, TArrayL>(
ptr);
360 return getBaseElementSize<double, float, int, short, char, long>(
ptr);
364template <
typename T,
typename Next,
typename... Rest,
typename P>
365int HistFiller::getBaseElementSize(
P*
ptr)
367 if (
auto size = getBaseElementSize<T>(
ptr)) {
370 return getBaseElementSize<Next, Rest...>(
ptr);
373template <
typename B,
typename T>
374int HistFiller::getBaseElementSize(T*
ptr)
376 if constexpr (std::is_base_of_v<THn, T>) {
377 if (
dynamic_cast<THnT<B>*
>(
ptr)) {
380 }
else if constexpr (std::is_base_of_v<THnSparse, T>) {
381 if (
dynamic_cast<THnSparseT<B>*
>(
ptr)) {
382 TDataMember* dm = B::Class()->GetDataMember(
"fArray");
383 return dm ? dm->GetDataType()->Size() : 0;
385 }
else if constexpr (std::is_base_of_v<TH1, T>) {
386 if (
auto arrayPtr =
dynamic_cast<B*
>(
ptr)) {
387 return sizeof(arrayPtr->At(0));
399template <
char... chars>
400constexpr HistogramRegistry::HistName::HistName(
const ConstStr<chars...>& hashedHistName)
401 :
str(hashedHistName.
str),
402 hash(hashedHistName.hash),
403 idx(hash & REGISTRY_BITMASK)
410 return add<T>(
name.c_str(), title, histType, axes, callSumw2);
416 if (
auto histPtr = std::get_if<std::shared_ptr<T>>(&mRegistryValue[getHistIndex(histName)])) {
419 throw runtime_error_f(R
"(Histogram type specified in get<>(HIST("%s")) does not match the actual type of the histogram!)", histName.str);
426 return get<T>(histName);
430uint32_t HistogramRegistry::getHistIndex(
const T& histName)
const
435 for (
auto i = 1u;
i < MAX_REGISTRY_SIZE; ++
i) {
436 if (histName.hash == mRegistryKey[imask(histName.idx +
i)]) {
437 return imask(histName.idx +
i);
440 throw runtime_error_f(R
"(Could not find histogram "%s" in HistogramRegistry "%s"!)", histName.str, mName.data());
443template <
typename... Ts>
447 std::visit([positionAndWeight...](
auto&& hist) { HistFiller::fillHistAny(hist, positionAndWeight...); }, mRegistryValue[getHistIndex(histName)]);
454extern template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<TH1>);
455extern template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<TH2>);
456extern template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<TH3>);
457extern template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<TProfile>);
458extern template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<TProfile2D>);
459extern template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<TProfile3D>);
460extern template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<THnSparse>);
461extern template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<THn>);
462extern template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<StepTHn>);
464extern template std::shared_ptr<TH1> HistogramRegistry::add<TH1>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
465extern 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);
466extern template std::shared_ptr<TH2> HistogramRegistry::add<TH2>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
467extern 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);
468extern template std::shared_ptr<TH3> HistogramRegistry::add<TH3>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
469extern 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);
470extern template std::shared_ptr<TProfile> HistogramRegistry::add<TProfile>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
471extern 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);
472extern template std::shared_ptr<TProfile2D> HistogramRegistry::add<TProfile2D>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
473extern 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);
474extern template std::shared_ptr<TProfile3D> HistogramRegistry::add<TProfile3D>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
475extern 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);
476extern template std::shared_ptr<THn> HistogramRegistry::add<THn>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
477extern 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);
478extern template std::shared_ptr<THnSparse> HistogramRegistry::add<THnSparse>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
479extern 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);
480extern template std::shared_ptr<StepTHn> HistogramRegistry::add<StepTHn>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
481extern 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);
483template <
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)
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)
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
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
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.