12#ifndef FRAMEWORK_HISTOGRAMREGISTRY_H_
13#define FRAMEWORK_HISTOGRAMREGISTRY_H_
23#include <TDataMember.h>
27#include <TProfile2D.h>
35#define HIST(name) CONST_STR(name)
45concept FillValue = std::is_integral_v<T> || std::is_floating_point_v<T> || std::is_enum_v<T>;
47template <
typename T,
int dimensions>
48concept ValidTH3 = std::same_as<T, TH3> && (dimensions == 3 || dimensions == 4);
50template <
typename T,
int dimensions>
51concept ValidTH2 = std::same_as<T, TH2> && (dimensions == 2 || dimensions == 3);
53template <
typename T,
int dimensions>
54concept ValidTH1 = std::same_as<T, TH1> && (dimensions == 1 || dimensions == 2);
56template <
typename T,
int dimensions>
57concept ValidTProfile3D = std::same_as<T, TProfile3D> && (dimensions == 4 || dimensions == 5);
59template <
typename T,
int dimensions>
60concept ValidTProfile2D = std::same_as<T, TProfile2D> && (dimensions == 3 || dimensions == 4);
62template <
typename T,
int dimensions>
63concept ValidTProfile = std::same_as<T, TProfile> && (dimensions == 2 || dimensions == 3);
65template <
typename T,
int D>
68template <
typename T,
int D>
71template <
typename T,
int D>
74template <
typename T,
int D>
79 template <
typename T,
typename...
Ts>
80 static void fillHistAny(std::shared_ptr<T> hist,
Ts... positionAndWeight)
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)
92 template <
typename T,
typename...
Ts>
93 static void fillHistAny(std::shared_ptr<T> hist,
Ts... positionAndWeight);
96 template <
typename... Cs,
typename R,
typename T>
101 template <
typename... Cs,
typename R,
typename T>
105 template <
typename T>
106 static double getSize(std::shared_ptr<T> hist,
double fillFraction = 1.);
110 template <
typename T>
111 static int getBaseElementSize(T*
ptr);
113 template <
typename T,
typename Next,
typename... Rest,
typename P>
114 static int getBaseElementSize(
P*
ptr);
116 template <
typename B,
typename T>
117 static int getBaseElementSize(T*
ptr);
119 static void badHistogramFill(
char const*
name);
132 template <
char... chars>
134 char const*
const str{};
135 const uint32_t
hash{};
136 const uint32_t idx{};
141 constexpr HistName(
char const*
const name);
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);
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);
163 bool contains(
const HistName& histName);
166 template <
typename T>
167 std::shared_ptr<T>
get(
const HistName& histName);
169 template <
typename T>
170 std::shared_ptr<T>
operator()(
const HistName& histName);
177 OutputRef ref(uint16_t idx, uint16_t pipelineSize)
const;
185 template <
typename...
Ts>
186 void fill(
const HistName& histName,
Ts... positionAndWeight)
190 template <
typename... Cs,
typename T>
194 double getSize(
const HistName& histName,
double fillFraction = 1.);
197 double getSize(
double fillFraction = 1.);
200 void print(
bool showAxisDetails =
false);
210 template <
typename T>
211 HistPtr insertClone(
const HistName& histName,
const std::shared_ptr<T> originalHist);
214 void validateHistName(
const std::string&
name,
const uint32_t
hash);
217 template <
typename T>
218 uint32_t getHistIndex(
const T& histName)
const;
220 constexpr uint32_t imask(uint32_t
i)
const
222 return i & REGISTRY_BITMASK;
226 std::deque<std::string> splitPath(
const std::string& pathAndNameUser);
229 void registerName(
const std::string&
name);
234 bool mCreateRegistryDir{};
236 uint32_t mTaskHash{};
237 std::vector<std::string> mRegisteredNames{};
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{};
255template <
typename T,
typename... Ts>
259 hist->Fill(
static_cast<double>(positionAndWeight)...);
262template <
typename T,
typename...
Ts>
266 constexpr int nArgs =
sizeof...(Ts);
268 double tempArray[] = {
static_cast<double>(positionAndWeight)...};
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());
276 hist->Fill(tempArray,
weight);
279template <
typename T,
typename... Ts>
281 requires ValidComplexFillStep<
T,
sizeof...(Ts)> && (FillValue<Ts> && ...)
283 hist->Fill(positionAndWeight...);
286template <
typename T,
typename... Ts>
289 HistFiller::badHistogramFill(hist->GetName());
292template <
typename... Cs,
typename R,
typename T>
298template <
typename... Cs,
typename R,
typename T>
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>) {
313 double nBinsTotal = 1.;
314 int compCoordSize = 0;
315 for (
int d = 0; d < hist->GetNdimensions(); ++d) {
316 int nBins = hist->GetAxis(d)->GetNbins() + 2;
326 compCoordSize = (compCoordSize + 7) / 8;
329 double nBinsFilled = fillFraction * nBinsTotal;
330 int nCunks = ceil(nBinsFilled / hist->GetChunkSize());
331 int chunkOverhead =
sizeof(THnSparseArrayChunk);
334 double binSize = compCoordSize + HistFiller::getBaseElementSize(hist.get()) + ((hist->GetSumw2() != -1.) ?
sizeof(
double) : 0.);
335 size = nCunks * (chunkOverhead + hist->GetChunkSize() * binSize);
339 size += nBinsFilled * 3 *
sizeof(Long64_t);
341 return size / 1048576.;
345int HistFiller::getBaseElementSize(T*
ptr)
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);
350 return getBaseElementSize<double, float, int, short, char, long>(
ptr);
354template <
typename T,
typename Next,
typename... Rest,
typename P>
355int HistFiller::getBaseElementSize(
P*
ptr)
357 if (
auto size = getBaseElementSize<T>(
ptr)) {
360 return getBaseElementSize<Next, Rest...>(
ptr);
363template <
typename B,
typename T>
364int HistFiller::getBaseElementSize(T*
ptr)
366 if constexpr (std::is_base_of_v<THn, T>) {
367 if (
dynamic_cast<THnT<B>*
>(
ptr)) {
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;
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));
389template <
char... chars>
390constexpr HistogramRegistry::HistName::HistName(
const ConstStr<chars...>& hashedHistName)
391 :
str(hashedHistName.
str),
400 return add<T>(
name.c_str(), title, histType, axes, callSumw2);
406 if (
auto histPtr = std::get_if<std::shared_ptr<T>>(&mRegistryValue[getHistIndex(histName)])) {
409 throw runtime_error_f(R
"(Histogram type specified in get<>(HIST("%s")) does not match the actual type of the histogram!)", histName.str);
416 return get<T>(histName);
420uint32_t HistogramRegistry::getHistIndex(
const T& histName)
const
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);
430 throw runtime_error_f(R
"(Could not find histogram "%s" in HistogramRegistry "%s"!)", histName.str, mName.data());
433template <
typename... Ts>
437 std::visit([positionAndWeight...](
auto&& hist) { HistFiller::fillHistAny(hist, positionAndWeight...); }, mRegistryValue[getHistIndex(histName)]);
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>);
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);
473template <
typename... Cs,
typename T>
#define O2_BUILTIN_LIKELY(x)
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
Defining ITS Vertex 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.