19AxisSpec::AxisSpec(std::vector<double> binEdges_, std::optional<std::string> title_, std::optional<std::string> name_)
20 : nBins(
std::nullopt),
21 binEdges(
std::move(binEdges_)),
22 title(
std::move(title_)),
27AxisSpec::AxisSpec(
int nBins_,
double binMin_,
double binMax_, std::optional<std::string> title_, std::optional<std::string> name_)
29 binEdges({binMin_, binMax_}),
30 title(std::move(title_)),
31 name(std::move(name_))
33 if (binMin_ > binMax_) {
34 LOG(fatal) <<
"Defined ill-defined axis";
39 : nBins(
std::nullopt),
40 binEdges(
std::vector<double>(binEdges_)),
41 title(
std::move(title_)),
56 axes(
std::move(axes_)),
72 if (binEdges.size() > 2) {
73 LOG(fatal) <<
"Cannot make a variabled bin width axis logaritmic";
76 const double min = binEdges[0];
78 LOG(fatal) <<
"Cannot have the first bin limit of the log. axis below 0: " <<
min;
80 const double max = binEdges[1];
82 const double logmin = std::log10(
min);
83 const double logmax = std::log10(
max);
84 const int nbins = nBins.value();
85 const double logdelta = (logmax - logmin) / (
static_cast<double>(nbins));
86 LOG(
debug) <<
"Making a logaritmic binning from " <<
min <<
" to " <<
max <<
" with " << nbins <<
" bins";
87 for (
int i = 0;
i < nbins + 1;
i++) {
88 const auto nextEdge = std::pow(10, logmin +
i * logdelta);
89 LOG(
debug) <<
i <<
"/" << nbins - 1 <<
": " << nextEdge;
90 binEdges.push_back(nextEdge);
98 if (
nBins.has_value()) {
107 const int nBins[],
const double lowerBounds[],
const double upperBounds[],
const int nSteps)
109 if constexpr (std::is_base_of_v<StepTHn, T>) {
110 return new T(
name.data(), title.data(), nSteps, nDim, nBins, lowerBounds, upperBounds);
111 }
else if constexpr (std::is_base_of_v<THnBase, T>) {
112 return new T(
name.data(), title.data(), nDim, nBins, lowerBounds, upperBounds);
113 }
else if constexpr (std::is_base_of_v<TH3, T>) {
114 return (nDim != 3) ? nullptr
115 :
new T(
name.data(), title.data(), nBins[0], lowerBounds[0],
116 upperBounds[0], nBins[1], lowerBounds[1], upperBounds[1],
117 nBins[2], lowerBounds[2], upperBounds[2]);
118 }
else if constexpr (std::is_base_of_v<TH2, T>) {
119 return (nDim != 2) ? nullptr
120 :
new T(
name.data(), title.data(), nBins[0], lowerBounds[0],
121 upperBounds[0], nBins[1], lowerBounds[1], upperBounds[1]);
122 }
else if constexpr (std::is_base_of_v<TH1, T>) {
125 :
new T(
name.data(), title.data(), nBins[0], lowerBounds[0], upperBounds[0]);
131template <
typename T,
typename BASE>
132static std::unique_ptr<BASE> createHistFull(
const HistogramSpec& histSpec)
134 constexpr std::size_t MAX_DIM{20};
135 const std::size_t nAxes{histSpec.
config.
axes.size()};
136 if (nAxes == 0 || nAxes > MAX_DIM) {
137 LOGF(fatal,
"The histogram specification contains no (or too many) axes.");
140 int nBins[MAX_DIM]{0};
141 double lowerBounds[MAX_DIM]{0.};
142 double upperBounds[MAX_DIM]{0.};
145 for (std::size_t
i = 0;
i < nAxes;
i++) {
147 lowerBounds[
i] = histSpec.
config.
axes[
i].binEdges.front();
148 upperBounds[
i] = histSpec.
config.
axes[
i].binEdges.back();
152 std::unique_ptr<BASE> hist{generateHist<T>(histSpec.
name, histSpec.
title, nAxes, nBins, lowerBounds, upperBounds, histSpec.
config.
nSteps)};
154 LOGF(fatal,
"The number of dimensions specified for histogram %s does not match the type.", histSpec.
name);
158 for (std::size_t
i = 0;
i < nAxes;
i++) {
162 axis->SetTitle((*histSpec.
config.
axes[
i].title).data());
166 if constexpr (std::is_base_of_v<THnBase, T>) {
168 axis->SetName((std::string(axis->GetName()) +
"-" + *histSpec.
config.
axes[
i].name).data());
174 if (!std::is_sorted(std::begin(histSpec.
config.
axes[
i].binEdges), std::end(histSpec.
config.
axes[
i].binEdges))) {
175 LOGF(fatal,
"The bin edges in histogram %s are not in increasing order!", histSpec.
name);
177 axis->Set(nBins[
i], histSpec.
config.
axes[
i].binEdges.data());
190 return createHistFull<T, T>(histSpec);
194#define CREATE_HIST_CASE(HType, BType) \
196 return std::shared_ptr<BType>(createHistFull<HType, BType>(histSpec));
252 if constexpr (std::is_base_of_v<THnBase, T> || std::is_base_of_v<StepTHn, T>) {
253 return hist->GetAxis(
i);
256 return hist->GetXaxis();
258 return hist->GetYaxis();
260 return hist->GetZaxis();
268#define EXPIMPL(HType) \
269 template std::unique_ptr<HType> HistFactory::createHist<HType>(const HistogramSpec& histSpec);
#define CREATE_HIST_CASE(HType, BType)
GLuint const GLchar * name
GLint GLint GLsizei GLint GLenum GLenum type
Defining ITS Vertex explicitly as messageable.
RuntimeErrorRef runtime_error(const char *)
T * generateHist(const std::string &name, const std::string &title, const std::size_t nDim, const int nBins[], const double lowerBounds[], const double upperBounds[], const int nSteps)
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
constexpr double VARIABLE_WIDTH
std::optional< int > nBins
Data members.
AxisSpec(std::vector< double > binEdges_, std::optional< std::string > title_=std::nullopt, std::optional< std::string > name_=std::nullopt)
std::vector< double > binEdges
Number of bins (only used for fixed bin width axis)
static HistPtr createHistVariant(const HistogramSpec &histSpec)
static TAxis * getAxis(const int i, T *hist)
static std::unique_ptr< T > createHist(const HistogramSpec &histSpec)
HistogramConfigSpec()=default
std::vector< AxisSpec > axes
HistogramConfigSpec config
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"