Project
Loading...
Searching...
No Matches
HistogramSpec.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#ifndef FRAMEWORK_HISTOGRAMSPEC_H_
13#define FRAMEWORK_HISTOGRAMSPEC_H_
14
15#include <string>
16#include <utility>
17#include <variant>
18#include <optional>
19
22
23#include "Framework/StepTHn.h"
24#include <TH1.h>
25#include <TH2.h>
26#include <TH3.h>
27#include <THn.h>
28#include <THnSparse.h>
29#include <TProfile.h>
30#include <TProfile2D.h>
31#include <TProfile3D.h>
32
33namespace o2::framework
34{
35// Available root histogram types
74
75// variant of all possible root pointers; here we use only the interface types since the underlying data representation (int,float,double,long,char) is irrelevant
76using HistPtr = 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>>;
77
78//**************************************************************************************************
82//**************************************************************************************************
83// flag to mark variable bin size in configurable bin edges
84constexpr double VARIABLE_WIDTH = 0.;
85
86struct AxisSpec {
87 // Defined out of line in HistogramSpec.cxx on purpose. These run once per
88 // histogram at init() time, so inlining them buys nothing at runtime, while
89 // a task that books a few hundred histograms in one init() pays for every
90 // expansion: each one materialises a std::vector<double> and two
91 // std::optional<std::string> at the call site, with the matching destructor
92 // and exception-unwind paths. Under -g that also means a debug record per
93 // temporary, which is what makes the register allocator's rewrite pass go
94 // superlinear on such functions.
95 AxisSpec(std::vector<double> binEdges_, std::optional<std::string> title_ = std::nullopt, std::optional<std::string> name_ = std::nullopt);
96
97 AxisSpec(int nBins_, double binMin_, double binMax_, std::optional<std::string> title_ = std::nullopt, std::optional<std::string> name_ = std::nullopt);
98
99 // first entry is assumed to be the number of bins; in case of variable size binning it must be set to zero
100 AxisSpec(ConfigurableAxis binEdges_, std::optional<std::string> title_ = std::nullopt, std::optional<std::string> name_ = std::nullopt);
101
102 // Out of line too, and for the same reason: every registry.add() call site
103 // materialises AxisSpec temporaries, so the *destructor* is expanded there as
104 // well -- on both the normal and the exception-unwind path. Measured with
105 // -Rpass=inline on a 276-histogram init(): ~optional<string> inlined 2164
106 // times, ~vector<AxisSpec> 552, ~vector<double> 367, ~AxisSpec 279.
107 //
108 // Declaring a destructor suppresses the implicit move operations, so all five
109 // are declared here to keep AxisSpec movable. The moves are explicitly
110 // noexcept: an out-of-line defaulted function does NOT inherit the implicit
111 // exception specification, and without it vector<AxisSpec> reallocation would
112 // silently fall back to copying.
115 AxisSpec(AxisSpec&&) noexcept;
116 AxisSpec& operator=(AxisSpec const&);
117 AxisSpec& operator=(AxisSpec&&) noexcept;
118
119 [[nodiscard]] long getNbins() const;
120
122 void makeLogarithmic();
123
125 std::optional<int> nBins{};
126 std::vector<double> binEdges{};
127 std::optional<std::string> title{};
128 std::optional<std::string> name{};
129};
130
131//**************************************************************************************************
135//**************************************************************************************************
137 // Out of line for the same reason as the AxisSpec constructors above.
138 HistogramConfigSpec(HistType type_, std::vector<AxisSpec> axes_, uint8_t nSteps_ = 1);
142 // Out of line: inlined 552 times into a single 276-histogram init().
143 // The copy/move constructors above stay declared, so this does not suppress
144 // them.
146
147 void addAxis(const AxisSpec& axis)
148 {
149 axes.push_back(axis);
150 }
151
152 void addAxis(int nBins_, double binMin_, double binMax_, std::optional<std::string> title_ = std::nullopt, std::optional<std::string> name_ = std::nullopt)
153 {
154 axes.emplace_back(nBins_, binMin_, binMax_, title_, name_);
155 }
156
157 void addAxis(std::vector<double> binEdges_, std::optional<std::string> title_ = std::nullopt, std::optional<std::string> name_ = std::nullopt)
158 {
159 axes.emplace_back(binEdges_, title_, name_);
160 }
161
162 void addAxes(std::vector<AxisSpec> axes_)
163 {
164 axes.insert(axes.end(), axes_.begin(), axes_.end());
165 }
166
167 // add axes defined in other HistogramConfigSpec object
169 {
170 axes.insert(axes.end(), other.axes.begin(), other.axes.end());
171 }
172
174 std::vector<AxisSpec> axes{};
175 uint32_t nSteps{1}; // variable used only in StepTHn
176};
177
178//**************************************************************************************************
182//**************************************************************************************************
184 HistogramSpec(char const* name_, char const* const title_, HistogramConfigSpec config_, bool callSumw2_ = false)
185 : name(name_),
186 hash(runtime_hash(name_)),
187 title(title_),
188 config(std::move(config_)),
189 callSumw2(callSumw2_)
190 {
191 }
192
193 HistogramSpec() = default;
196
197 std::string name{};
198 uint32_t hash = 0;
199 std::string title{};
201 bool callSumw2{}; // wether or not hist needs heavy error structure produced by Sumw2()
202};
203
204//**************************************************************************************************
209//**************************************************************************************************
211
212 // create histogram of type T with the axes defined in HistogramSpec
213 template <typename T>
214 static std::unique_ptr<T> createHist(const HistogramSpec& histSpec);
215
216 // runtime version of the above
217 static HistPtr createHistVariant(const HistogramSpec& histSpec);
218
219 // helper function to get the axis via index for any type of root histogram
220 template <typename T>
221 static TAxis* getAxis(const int i, T* hist);
222};
223
224#define DECLAREEXT(HType) \
225 extern template std::unique_ptr<HType> HistFactory::createHist<HType>(const HistogramSpec& histSpec);
250DECLAREEXT(THnSparseD);
251DECLAREEXT(THnSparseF);
252DECLAREEXT(THnSparseI);
253DECLAREEXT(THnSparseC);
254DECLAREEXT(THnSparseS);
255DECLAREEXT(THnSparseL);
256DECLAREEXT(TProfile);
257DECLAREEXT(TProfile2D);
258DECLAREEXT(TProfile3D);
261#undef DECLAREEXT
262
263} // namespace o2::framework
264#endif // FRAMEWORK_HISTOGRAMSPEC_H_
int32_t i
#define DECLAREEXT(HType)
constexpr uint32_t runtime_hash(char const *str)
GLuint const GLchar * name
Definition glcorearb.h:781
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
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
void makeLogarithmic()
Function to make the axis logarithmic.
std::optional< int > nBins
Data members.
std::optional< std::string > title
Edges of the bin. For fixed bin width these are the limits of the binning.
std::vector< double > binEdges
Number of bins (only used for fixed bin width axis)
AxisSpec(AxisSpec const &)
AxisSpec(AxisSpec &&) noexcept
static HistPtr createHistVariant(const HistogramSpec &histSpec)
static TAxis * getAxis(const int i, T *hist)
static std::unique_ptr< T > createHist(const HistogramSpec &histSpec)
void addAxes(const HistogramConfigSpec &other)
HistogramConfigSpec(HistogramConfigSpec const &other)=default
void addAxis(int nBins_, double binMin_, double binMax_, std::optional< std::string > title_=std::nullopt, std::optional< std::string > name_=std::nullopt)
HistogramConfigSpec(HistogramConfigSpec &&other)=default
void addAxis(const AxisSpec &axis)
void addAxes(std::vector< AxisSpec > axes_)
void addAxis(std::vector< double > binEdges_, std::optional< std::string > title_=std::nullopt, std::optional< std::string > name_=std::nullopt)
HistogramSpec(HistogramSpec const &other)=default
HistogramSpec(HistogramSpec &&other)=default
HistogramSpec(char const *name_, char const *const title_, HistogramConfigSpec config_, bool callSumw2_=false)
HistogramConfigSpec config
VectorOfTObjectPtrs other