Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 88 additions & 34 deletions Framework/Core/include/Framework/HistogramRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@
#include <TDataMember.h>
#include <TDataType.h>
#include <TArrayL.h>
#include <TProfile2D.h>
#include <fmt/core.h>

#include <concepts>
#include <deque>

class TList;
Expand All @@ -43,11 +46,58 @@ namespace o2::framework
template <typename T>
concept FillValue = std::is_integral_v<T> || std::is_floating_point_v<T> || std::is_enum_v<T>;

template <typename T, int dimensions>
concept ValidTH3 = std::same_as<T, TH3> && (dimensions == 3 || dimensions == 4);

template <typename T, int dimensions>
concept ValidTH2 = std::same_as<T, TH2> && (dimensions == 2 || dimensions == 3);

template <typename T, int dimensions>
concept ValidTH1 = std::same_as<T, TH1> && (dimensions == 1 || dimensions == 2);

template <typename T, int dimensions>
concept ValidTProfile3D = std::same_as<T, TProfile3D> && (dimensions == 4 || dimensions == 5);

template <typename T, int dimensions>
concept ValidTProfile2D = std::same_as<T, TProfile2D> && (dimensions == 3 || dimensions == 4);

template <typename T, int dimensions>
concept ValidTProfile = std::same_as<T, TProfile> && (dimensions == 2 || dimensions == 3);

template <typename T, int D>
concept ValidSimpleFill = ValidTH1<T, D> || ValidTH2<T, D> || ValidTH3<T, D> || ValidTProfile<T, D> || ValidTProfile2D<T, D> || ValidTProfile3D<T, D>;

template <typename T, int D>
concept ValidComplexFill = std::is_base_of_v<THnBase, T>;

template <typename T, int D>
concept ValidComplexFillStep = std::is_base_of_v<StepTHn, T>;

template <typename T, int D>
concept ValidFill = ValidSimpleFill<T, D> || ValidComplexFill<T, D> || ValidComplexFillStep<T, D>;

struct HistFiller {
// fill any type of histogram (if weight was requested it must be the last argument)
template <typename T, typename... Ts>
static void fillHistAny(std::shared_ptr<T> hist, Ts... positionAndWeight)
requires(FillValue<Ts> && ...);
requires ValidSimpleFill<T, sizeof...(Ts)> && (FillValue<Ts> && ...);

template <typename T, typename... Ts>
static void fillHistAny(std::shared_ptr<T> hist, Ts... positionAndWeight)
requires ValidComplexFill<T, sizeof...(Ts)> && (FillValue<Ts> && ...);

template <typename T, typename... Ts>
static void fillHistAny(std::shared_ptr<T> hist, Ts... positionAndWeight)
requires ValidComplexFillStep<T, sizeof...(Ts)> && (FillValue<Ts> && ...);

// This applies only for the non-viable cases
template <typename T, typename... Ts>
static void fillHistAny(std::shared_ptr<T> hist, Ts... positionAndWeight);

// fill any type of histogram with columns (Cs) of a filtered table (if weight is requested it must reside the last specified column)
template <typename... Cs, typename R, typename T>
static void fillHistAny(std::shared_ptr<R> hist, const T& table, const o2::framework::expressions::Filter& filter)
requires(!ValidComplexFillStep<R, sizeof...(Cs)>) && requires(T t) { t.asArrowTable(); };

// fill any type of histogram with columns (Cs) of a filtered table (if weight is requested it must reside the last specified column)
template <typename... Cs, typename R, typename T>
Expand All @@ -67,6 +117,8 @@ struct HistFiller {

template <typename B, typename T>
static int getBaseElementSize(T* ptr);

static void badHistogramFill(char const* name);
};

//**************************************************************************************************
Expand Down Expand Up @@ -203,58 +255,60 @@ class HistogramRegistry
// Implementation of HistFiller template functions.
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
template <typename T, typename... Ts>
void HistFiller::fillHistAny(std::shared_ptr<T> hist, Ts... positionAndWeight)
requires ValidSimpleFill<T, sizeof...(Ts)> && (FillValue<Ts> && ...)
{
hist->Fill(static_cast<double>(positionAndWeight)...);
}

template <typename T, typename... Ts>
void HistFiller::fillHistAny(std::shared_ptr<T> hist, Ts... positionAndWeight)
requires(FillValue<Ts> && ...)
requires ValidComplexFill<T, sizeof...(Ts)> && (FillValue<Ts> && ...)
{
constexpr int nArgs = sizeof...(Ts);

constexpr bool validTH3 = (std::is_same_v<TH3, T> && (nArgs == 3 || nArgs == 4));
constexpr bool validTH2 = (std::is_same_v<TH2, T> && (nArgs == 2 || nArgs == 3));
constexpr bool validTH1 = (std::is_same_v<TH1, T> && (nArgs == 1 || nArgs == 2));
constexpr bool validTProfile3D = (std::is_same_v<TProfile3D, T> && (nArgs == 4 || nArgs == 5));
constexpr bool validTProfile2D = (std::is_same_v<TProfile2D, T> && (nArgs == 3 || nArgs == 4));
constexpr bool validTProfile = (std::is_same_v<TProfile, T> && (nArgs == 2 || nArgs == 3));

constexpr bool validSimpleFill = validTH1 || validTH2 || validTH3 || validTProfile || validTProfile2D || validTProfile3D;
// unfortunately we dont know at compile the dimension of THn(Sparse)
constexpr bool validComplexFill = std::is_base_of_v<THnBase, T>;
constexpr bool validComplexFillStep = std::is_base_of_v<StepTHn, T>;

if constexpr (validSimpleFill) {
hist->Fill(static_cast<double>(positionAndWeight)...);
} else if constexpr (validComplexFillStep) {
hist->Fill(positionAndWeight...); // first argument in pack is iStep, dimension check is done in StepTHn itself
} else if constexpr (validComplexFill) {
double tempArray[] = {static_cast<double>(positionAndWeight)...};
double weight{1.};
constexpr int nArgsMinusOne = nArgs - 1;
if (hist->GetNdimensions() == nArgsMinusOne) {
weight = tempArray[nArgsMinusOne];
} else if (hist->GetNdimensions() != nArgs) {
LOGF(fatal, "The number of arguments in fill function called for histogram %s is incompatible with histogram dimensions.", hist->GetName());
}
hist->Fill(tempArray, weight);
} else {
LOGF(fatal, "The number of arguments in fill function called for histogram %s is incompatible with histogram dimensions.", hist->GetName());
double tempArray[] = {static_cast<double>(positionAndWeight)...};
double weight{1.};
constexpr int nArgsMinusOne = nArgs - 1;
if (hist->GetNdimensions() == nArgsMinusOne) {
weight = tempArray[nArgsMinusOne];
} else if (hist->GetNdimensions() != nArgs) {
badHistogramFill(hist->GetName());
}
hist->Fill(tempArray, weight);
}

template <typename T, typename... Ts>
void HistFiller::fillHistAny(std::shared_ptr<T> hist, Ts... positionAndWeight)
requires ValidComplexFillStep<T, sizeof...(Ts)> && (FillValue<Ts> && ...)
{
hist->Fill(positionAndWeight...); // first argument in pack is iStep, dimension check is done in StepTHn itself
}

template <typename T, typename... Ts>
void HistFiller::fillHistAny(std::shared_ptr<T> hist, Ts... positionAndWeight)
{
HistFiller::badHistogramFill(hist->GetName());
}

template <typename... Cs, typename R, typename T>
void HistFiller::fillHistAny(std::shared_ptr<R> hist, const T& table, const o2::framework::expressions::Filter& filter)
requires(!ValidComplexFillStep<R, sizeof...(Cs)>) && requires(T t) { t.asArrowTable(); }
{
if constexpr (std::is_base_of_v<StepTHn, T>) {
LOGF(fatal, "Table filling is not (yet?) supported for StepTHn.");
return;
}
auto s = o2::framework::expressions::createSelection(table.asArrowTable(), filter);
auto filtered = o2::soa::Filtered<T>{{table.asArrowTable()}, s};
for (auto& t : filtered) {
fillHistAny(hist, (*(static_cast<Cs>(t).getIterator()))...);
}
}

template <typename... Cs, typename R, typename T>
void HistFiller::fillHistAny(std::shared_ptr<R> hist, const T& table, const o2::framework::expressions::Filter& filter)
{
HistFiller::badHistogramFill(hist->GetName());
}

template <typename T>
double HistFiller::getSize(std::shared_ptr<T> hist, double fillFraction)
{
Expand Down
5 changes: 5 additions & 0 deletions Framework/Core/src/HistogramRegistry.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -409,4 +409,9 @@ void HistogramRegistry::registerName(const std::string& name)
mRegisteredNames.push_back(name);
}

void HistFiller::badHistogramFill(char const* name)
{
LOGF(fatal, "The number of arguments in fill function called for histogram %s is incompatible with histogram dimensions.", name);
}

} // namespace o2::framework
Loading