Logo ROOT  
Reference Guide
RDFHistoModels.cxx
Go to the documentation of this file.
1// Author: Enrico Guiraud, Danilo Piparo CERN 09/2017
2
3/*************************************************************************
4 * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers. *
5 * All rights reserved. *
6 * *
7 * For the licensing terms see $ROOTSYS/LICENSE. *
8 * For the list of contributors see $ROOTSYS/README/CREDITS. *
9 *************************************************************************/
10
12#include <ROOT/TSeq.hxx>
13#include <TProfile.h>
14#include <TProfile2D.h>
15#include <stddef.h>
16#include <vector>
17
18#include "TAxis.h"
19#include "TH1.h"
20#include "TH2.h"
21#include "TH3.h"
22#include "THn.h"
23
24/**
25 * \class ROOT::RDF::TH1DModel
26 * \ingroup dataframe
27 * \brief A struct which stores the parameters of a TH1D
28 *
29 * \class ROOT::RDF::TH2DModel
30 * \ingroup dataframe
31 * \brief A struct which stores the parameters of a TH2D
32 *
33 * \class ROOT::RDF::TH3DModel
34 * \ingroup dataframe
35 * \brief A struct which stores the parameters of a TH3D
36 *
37 * \class ROOT::RDF::THnDModel
38 * \ingroup dataframe
39 * \brief A struct which stores the parameters of a THnD
40 *
41 * \class ROOT::RDF::TProfile1DModel
42 * \ingroup dataframe
43 * \brief A struct which stores the parameters of a TProfile
44 *
45 * \class ROOT::RDF::TProfile2DModel
46 * \ingroup dataframe
47 * \brief A struct which stores the parameters of a TProfile2D
48 */
49
50template <typename T>
51inline void FillVector(std::vector<double> &v, int size, T *a)
52{
53 v.reserve(size);
54 for (auto i : ROOT::TSeq<int>(size + 1))
55 v.push_back(a[i]);
56}
57
58template <>
59inline void FillVector<double>(std::vector<double> &v, int size, double *a)
60{
61 v.assign(a, a + (size_t)(size + 1));
62}
63
64inline void SetAxisProperties(const TAxis *axis, double &low, double &up, std::vector<double> &edges)
65{
66 // Check if this histo has fixed binning
67 // Same technique of "Int_t TAxis::FindBin(Double_t)"
68 if (!axis->GetXbins()->fN) {
69 low = axis->GetXmin();
70 up = axis->GetXmax();
71 } else {
72 // This histo has variable binning
73 const auto size = axis->GetNbins() + 1;
74 edges.reserve(size);
75 for (auto i : ROOT::TSeq<int>(1, size))
76 edges.push_back(axis->GetBinLowEdge(i));
77 edges.push_back(axis->GetBinUpEdge(size - 1));
78 }
79}
80
81namespace ROOT {
82
83namespace RDF {
84
85TH1DModel::TH1DModel(const ::TH1D &h) : fName(h.GetName()), fTitle(h.GetTitle()), fNbinsX(h.GetNbinsX())
86{
88}
89TH1DModel::TH1DModel(const char *name, const char *title, int nbinsx, double xlow, double xup)
90 : fName(name), fTitle(title), fNbinsX(nbinsx), fXLow(xlow), fXUp(xup)
91{
92}
93TH1DModel::TH1DModel(const char *name, const char *title, int nbinsx, const float *xbins)
94 : fName(name), fTitle(title), fNbinsX(nbinsx)
95{
96 FillVector(fBinXEdges, nbinsx, xbins);
97}
98TH1DModel::TH1DModel(const char *name, const char *title, int nbinsx, const double *xbins)
99 : fName(name), fTitle(title), fNbinsX(nbinsx)
100{
101 FillVector(fBinXEdges, nbinsx, xbins);
102}
103std::shared_ptr<::TH1D> TH1DModel::GetHistogram() const
104{
105 std::shared_ptr<::TH1D> h;
106 if (fBinXEdges.empty())
107 h = std::make_shared<::TH1D>(fName, fTitle, fNbinsX, fXLow, fXUp);
108 else
109 h = std::make_shared<::TH1D>(fName, fTitle, fNbinsX, fBinXEdges.data());
110
111 h->SetDirectory(nullptr); // object's lifetime is managed by the shared_ptr, detach it from ROOT's memory management
112 return h;
113}
115{
116}
117
119 : fName(h.GetName()), fTitle(h.GetTitle()), fNbinsX(h.GetNbinsX()), fNbinsY(h.GetNbinsY())
120{
121 SetAxisProperties(h.GetXaxis(), fXLow, fXUp, fBinXEdges);
122 SetAxisProperties(h.GetYaxis(), fYLow, fYUp, fBinYEdges);
123}
124TH2DModel::TH2DModel(const char *name, const char *title, int nbinsx, double xlow, double xup, int nbinsy, double ylow,
125 double yup)
126 : fName(name), fTitle(title), fNbinsX(nbinsx), fXLow(xlow), fXUp(xup), fNbinsY(nbinsy), fYLow(ylow), fYUp(yup)
127{
128}
129TH2DModel::TH2DModel(const char *name, const char *title, int nbinsx, const double *xbins, int nbinsy, double ylow,
130 double yup)
131 : fName(name), fTitle(title), fNbinsX(nbinsx), fNbinsY(nbinsy), fYLow(ylow), fYUp(yup)
132{
133 FillVector(fBinXEdges, nbinsx, xbins);
134}
135TH2DModel::TH2DModel(const char *name, const char *title, int nbinsx, double xlow, double xup, int nbinsy,
136 const double *ybins)
137 : fName(name), fTitle(title), fNbinsX(nbinsx), fXLow(xlow), fXUp(xup), fNbinsY(nbinsy)
138{
139 FillVector(fBinYEdges, nbinsy, ybins);
140}
141TH2DModel::TH2DModel(const char *name, const char *title, int nbinsx, const double *xbins, int nbinsy,
142 const double *ybins)
143 : fName(name), fTitle(title), fNbinsX(nbinsx), fNbinsY(nbinsy)
144{
145 FillVector(fBinXEdges, nbinsx, xbins);
146 FillVector(fBinYEdges, nbinsy, ybins);
147}
148TH2DModel::TH2DModel(const char *name, const char *title, int nbinsx, const float *xbins, int nbinsy,
149 const float *ybins)
150 : fName(name), fTitle(title), fNbinsX(nbinsx), fNbinsY(nbinsy)
151{
152 FillVector(fBinXEdges, nbinsx, xbins);
153 FillVector(fBinYEdges, nbinsy, ybins);
154}
155std::shared_ptr<::TH2D> TH2DModel::GetHistogram() const
156{
157 auto xEdgesEmpty = fBinXEdges.empty();
158 auto yEdgesEmpty = fBinYEdges.empty();
159 std::shared_ptr<::TH2D> h;
160 if (xEdgesEmpty && yEdgesEmpty)
161 h = std::make_shared<::TH2D>(fName, fTitle, fNbinsX, fXLow, fXUp, fNbinsY, fYLow, fYUp);
162 else if (!xEdgesEmpty && yEdgesEmpty)
163 h = std::make_shared<::TH2D>(fName, fTitle, fNbinsX, fBinXEdges.data(), fNbinsY, fYLow, fYUp);
164 else if (xEdgesEmpty && !yEdgesEmpty)
165 h = std::make_shared<::TH2D>(fName, fTitle, fNbinsX, fXLow, fXUp, fNbinsY, fBinYEdges.data());
166 else
167 h = std::make_shared<::TH2D>(fName, fTitle, fNbinsX, fBinXEdges.data(), fNbinsY, fBinYEdges.data());
168
169 h->SetDirectory(nullptr); // object's lifetime is managed by the shared_ptr, detach it from ROOT's memory management
170 return h;
171}
173{
174}
175
177 : fName(h.GetName()), fTitle(h.GetTitle()), fNbinsX(h.GetNbinsX()), fNbinsY(h.GetNbinsY()), fNbinsZ(h.GetNbinsZ())
178{
179 SetAxisProperties(h.GetXaxis(), fXLow, fXUp, fBinXEdges);
180 SetAxisProperties(h.GetYaxis(), fYLow, fYUp, fBinYEdges);
181 SetAxisProperties(h.GetZaxis(), fZLow, fZUp, fBinZEdges);
182}
183TH3DModel::TH3DModel(const char *name, const char *title, int nbinsx, double xlow, double xup, int nbinsy, double ylow,
184 double yup, int nbinsz, double zlow, double zup)
185 : fName(name), fTitle(title), fNbinsX(nbinsx), fXLow(xlow), fXUp(xup), fNbinsY(nbinsy), fYLow(ylow), fYUp(yup),
186 fNbinsZ(nbinsz), fZLow(zlow), fZUp(zup)
187{
188}
189TH3DModel::TH3DModel(const char *name, const char *title, int nbinsx, const double *xbins, int nbinsy,
190 const double *ybins, int nbinsz, const double *zbins)
191 : fName(name), fTitle(title), fNbinsX(nbinsx), fNbinsY(nbinsy), fNbinsZ(nbinsz)
192{
193 FillVector(fBinXEdges, nbinsx, xbins);
194 FillVector(fBinYEdges, nbinsy, ybins);
195 FillVector(fBinZEdges, nbinsz, zbins);
196}
197TH3DModel::TH3DModel(const char *name, const char *title, int nbinsx, const float *xbins, int nbinsy,
198 const float *ybins, int nbinsz, const float *zbins)
199 : fName(name), fTitle(title), fNbinsX(nbinsx), fNbinsY(nbinsy), fNbinsZ(nbinsz)
200{
201 FillVector(fBinXEdges, nbinsx, xbins);
202 FillVector(fBinYEdges, nbinsy, ybins);
203 FillVector(fBinZEdges, nbinsz, zbins);
204}
205std::shared_ptr<::TH3D> TH3DModel::GetHistogram() const
206{
207 std::shared_ptr<::TH3D> h;
208 if (fBinXEdges.empty() && fBinYEdges.empty() && fBinZEdges.empty())
209 h = std::make_shared<::TH3D>(fName, fTitle, fNbinsX, fXLow, fXUp, fNbinsY, fYLow, fYUp, fNbinsZ, fZLow, fZUp);
210 else
211 h = std::make_shared<::TH3D>(fName, fTitle, fNbinsX, fBinXEdges.data(), fNbinsY, fBinYEdges.data(), fNbinsZ,
212 fBinZEdges.data());
213
214 h->SetDirectory(nullptr);
215 return h;
216}
218{
219}
220
222 : fName(h.GetName()), fTitle(h.GetTitle()), fDim(h.GetNdimensions()), fNbins(fDim), fXmin(fDim), fXmax(fDim),
223 fBinEdges(fDim)
224{
225 for (int idim = 0; idim < fDim; ++idim) {
226 fNbins[idim] = h.GetAxis(idim)->GetNbins();
227 SetAxisProperties(h.GetAxis(idim), fXmin[idim], fXmax[idim], fBinEdges[idim]);
228 }
229}
230
231THnDModel::THnDModel(const char *name, const char *title, int dim, const int *nbins, const double *xmin,
232 const double *xmax)
233 : fName(name), fTitle(title), fDim(dim), fBinEdges(dim)
234{
235 fNbins.reserve(fDim);
236 fXmin.reserve(fDim);
237 fXmax.reserve(fDim);
238 for (int idim = 0; idim < fDim; ++idim) {
239 fNbins.push_back(nbins[idim]);
240 fXmin.push_back(xmin[idim]);
241 fXmax.push_back(xmax[idim]);
242 }
243}
244
245THnDModel::THnDModel(const char *name, const char *title, int dim, const std::vector<int> &nbins,
246 const std::vector<double> &xmin, const std::vector<double> &xmax)
247 : fName(name), fTitle(title), fDim(dim), fNbins(nbins), fXmin(xmin), fXmax(xmax), fBinEdges(dim)
248{
249}
250
251THnDModel::THnDModel(const char *name, const char *title, int dim, const int *nbins,
252 const std::vector<std::vector<double>> &xbins)
253 : fName(name), fTitle(title), fDim(dim), fXmin(dim, 0.), fXmax(dim, 64.), fBinEdges(xbins)
254{
255 fNbins.reserve(fDim);
256 for (int idim = 0; idim < fDim; ++idim) {
257 fNbins.push_back(nbins[idim]);
258 }
259}
260
261THnDModel::THnDModel(const char *name, const char *title, int dim, const std::vector<int> &nbins,
262 const std::vector<std::vector<double>> &xbins)
263 : fName(name), fTitle(title), fDim(dim), fNbins(nbins), fXmin(dim, 0.), fXmax(dim, 64.), fBinEdges(xbins)
264{
265}
266
267std::shared_ptr<::THnD> THnDModel::GetHistogram() const
268{
269 bool varbinning = false;
270 for (const auto &bins : fBinEdges) {
271 if (bins.size()) {
272 varbinning = true;
273 break;
274 }
275 }
276 std::shared_ptr<::THnD> h;
277 if (varbinning) {
278 h = std::make_shared<::THnD>(fName, fTitle, fDim, fNbins.data(), fBinEdges);
279 } else {
280 h = std::make_shared<::THnD>(fName, fTitle, fDim, fNbins.data(), fXmin.data(), fXmax.data());
281 }
282 return h;
283}
285
286// Profiles
287
289 : fName(h.GetName()), fTitle(h.GetTitle()), fNbinsX(h.GetNbinsX()), fXLow(h.GetXaxis()->GetXmin()),
290 fXUp(h.GetXaxis()->GetXmax()), fYLow(h.GetYmin()), fYUp(h.GetYmax()), fOption(h.GetErrorOption())
291{
292 SetAxisProperties(h.GetXaxis(), fXLow, fXUp, fBinXEdges);
293}
294TProfile1DModel::TProfile1DModel(const char *name, const char *title, int nbinsx, double xlow, double xup,
295 const char *option)
296 : fName(name), fTitle(title), fNbinsX(nbinsx), fXLow(xlow), fXUp(xup), fOption(option)
297{
298}
299
300TProfile1DModel::TProfile1DModel(const char *name, const char *title, int nbinsx, double xlow, double xup, double ylow,
301 double yup, const char *option)
302 : fName(name), fTitle(title), fNbinsX(nbinsx), fXLow(xlow), fXUp(xup), fYLow(ylow), fYUp(yup), fOption(option)
303{
304}
305
306TProfile1DModel::TProfile1DModel(const char *name, const char *title, int nbinsx, const float *xbins,
307 const char *option)
308 : fName(name), fTitle(title), fNbinsX(nbinsx), fOption(option)
309{
310 FillVector(fBinXEdges, nbinsx, xbins);
311}
312TProfile1DModel::TProfile1DModel(const char *name, const char *title, int nbinsx, const double *xbins,
313 const char *option)
314 : fName(name), fTitle(title), fNbinsX(nbinsx), fOption(option)
315{
316 FillVector(fBinXEdges, nbinsx, xbins);
317}
318TProfile1DModel::TProfile1DModel(const char *name, const char *title, int nbinsx, const double *xbins, double ylow,
319 double yup, const char *option)
320 : fName(name), fTitle(title), fNbinsX(nbinsx), fYLow(ylow), fYUp(yup), fOption(option)
321{
322 FillVector(fBinXEdges, nbinsx, xbins);
323}
324std::shared_ptr<::TProfile> TProfile1DModel::GetProfile() const
325{
326 std::shared_ptr<::TProfile> prof;
327
328 if (fBinXEdges.empty())
329 prof = std::make_shared<::TProfile>(fName, fTitle, fNbinsX, fXLow, fXUp, fYLow, fYUp, fOption);
330 else
331 prof = std::make_shared<::TProfile>(fName, fTitle, fNbinsX, fBinXEdges.data(), fYLow, fYUp, fOption);
332
333 prof->SetDirectory(nullptr); // lifetime is managed by the shared_ptr, detach from ROOT's memory management
334 return prof;
335}
337{
338}
339
341 : fName(h.GetName()), fTitle(h.GetTitle()), fNbinsX(h.GetNbinsX()), fXLow(h.GetXaxis()->GetXmin()),
342 fXUp(h.GetXaxis()->GetXmax()), fNbinsY(h.GetNbinsY()), fYLow(h.GetYaxis()->GetXmin()),
343 fYUp(h.GetYaxis()->GetXmax()), fZLow(h.GetZmin()), fZUp(h.GetZmax()), fOption(h.GetErrorOption())
344{
345 SetAxisProperties(h.GetXaxis(), fXLow, fXUp, fBinXEdges);
346 SetAxisProperties(h.GetYaxis(), fYLow, fYUp, fBinYEdges);
347}
348TProfile2DModel::TProfile2DModel(const char *name, const char *title, int nbinsx, double xlow, double xup, int nbinsy,
349 double ylow, double yup, const char *option)
350 : fName(name), fTitle(title), fNbinsX(nbinsx), fXLow(xlow), fXUp(xup), fNbinsY(nbinsy), fYLow(ylow), fYUp(yup),
351 fOption(option)
352{
353}
354
355TProfile2DModel::TProfile2DModel(const char *name, const char *title, int nbinsx, double xlow, double xup, int nbinsy,
356 double ylow, double yup, double zlow, double zup, const char *option)
357 : fName(name), fTitle(title), fNbinsX(nbinsx), fXLow(xlow), fXUp(xup), fNbinsY(nbinsy), fYLow(ylow), fYUp(yup),
358 fZLow(zlow), fZUp(zup), fOption(option)
359{
360}
361
362TProfile2DModel::TProfile2DModel(const char *name, const char *title, int nbinsx, const double *xbins, int nbinsy,
363 double ylow, double yup, const char *option)
364 : fName(name), fTitle(title), fNbinsX(nbinsx), fNbinsY(nbinsy), fYLow(ylow), fYUp(yup), fOption(option)
365{
366 FillVector(fBinXEdges, nbinsx, xbins);
367}
368
369TProfile2DModel::TProfile2DModel(const char *name, const char *title, int nbinsx, double xlow, double xup, int nbinsy,
370 const double *ybins, const char *option)
371 : fName(name), fTitle(title), fNbinsX(nbinsx), fXLow(xlow), fXUp(xup), fNbinsY(nbinsy), fOption(option)
372{
373 FillVector(fBinYEdges, nbinsy, ybins);
374}
375
376TProfile2DModel::TProfile2DModel(const char *name, const char *title, int nbinsx, const double *xbins, int nbinsy,
377 const double *ybins, const char *option)
378 : fName(name), fTitle(title), fNbinsX(nbinsx), fNbinsY(nbinsy), fOption(option)
379{
380 FillVector(fBinXEdges, nbinsx, xbins);
381 FillVector(fBinYEdges, nbinsy, ybins);
382}
383
384std::shared_ptr<::TProfile2D> TProfile2DModel::GetProfile() const
385{
386 // In this method we decide how to build the profile based on the input given in the constructor of the model.
387 // There are 4 cases:
388 // 1. No custom binning for both the x and y axes: we return a profile with equally spaced binning
389 // 2./3. Custom binning only for x(y): we return a profile with custom binning for x(y) and equally spaced for y(x).
390 // 4. No custom binning: we return a profile with equally spaced bins on both axes
391 auto xEdgesEmpty = fBinXEdges.empty();
392 auto yEdgesEmpty = fBinYEdges.empty();
393 std::shared_ptr<::TProfile2D> prof;
394 if (xEdgesEmpty && yEdgesEmpty) {
395 prof = std::make_shared<::TProfile2D>(fName, fTitle, fNbinsX, fXLow, fXUp, fNbinsY, fYLow, fYUp, fZLow, fZUp,
396 fOption);
397 } else if (!xEdgesEmpty && yEdgesEmpty) {
398 prof = std::make_shared<::TProfile2D>(fName, fTitle, fNbinsX, fBinXEdges.data(), fNbinsY, fYLow, fYUp, fOption);
399 } else if (xEdgesEmpty && !yEdgesEmpty) {
400 prof = std::make_shared<::TProfile2D>(fName, fTitle, fNbinsX, fXLow, fXUp, fNbinsY, fBinYEdges.data(), fOption);
401 } else {
402 prof =
403 std::make_shared<::TProfile2D>(fName, fTitle, fNbinsX, fBinXEdges.data(), fNbinsY, fBinYEdges.data(), fOption);
404 }
405
406 prof->SetDirectory(
407 nullptr); // object's lifetime is managed by the shared_ptr, detach it from ROOT's memory management
408 return prof;
409}
410
412{
413}
414
415} // ns RDF
416
417} // ns ROOT
void FillVector< double >(std::vector< double > &v, int size, double *a)
void FillVector(std::vector< double > &v, int size, T *a)
void SetAxisProperties(const TAxis *axis, double &low, double &up, std::vector< double > &edges)
#define h(i)
Definition: RSha256.hxx:106
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
Option_t Option_t option
char name[80]
Definition: TGX11.cxx:110
float xmin
Definition: THbookFile.cxx:95
float xmax
Definition: THbookFile.cxx:95
THnT< Double_t > THnD
Definition: THn.h:244
A pseudo container class which is a generator of indices.
Definition: TSeq.hxx:67
Int_t fN
Definition: TArray.h:38
Class to manage histogram axis.
Definition: TAxis.h:30
const TArrayD * GetXbins() const
Definition: TAxis.h:131
Double_t GetXmax() const
Definition: TAxis.h:135
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition: TAxis.cxx:519
Double_t GetXmin() const
Definition: TAxis.h:134
Int_t GetNbins() const
Definition: TAxis.h:121
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition: TAxis.cxx:529
double T(double x)
Definition: ChebyshevPol.h:34
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
const double xbins[xbins_n]
std::shared_ptr<::TH1D > GetHistogram() const
std::vector< double > fBinXEdges
Definition: HistoModels.hxx:36
std::vector< double > fBinYEdges
Definition: HistoModels.hxx:58
std::vector< double > fBinXEdges
Definition: HistoModels.hxx:57
std::shared_ptr<::TH2D > GetHistogram() const
std::vector< double > fBinZEdges
Definition: HistoModels.hxx:87
std::vector< double > fBinYEdges
Definition: HistoModels.hxx:86
std::vector< double > fBinXEdges
Definition: HistoModels.hxx:85
std::shared_ptr<::TH3D > GetHistogram() const
std::vector< double > fXmax
std::vector< std::vector< double > > fBinEdges
std::shared_ptr<::THnD > GetHistogram() const
std::vector< double > fXmin
std::vector< int > fNbins
std::shared_ptr<::TProfile > GetProfile() const
std::vector< double > fBinXEdges
std::vector< double > fBinXEdges
std::shared_ptr<::TProfile2D > GetProfile() const
std::vector< double > fBinYEdges
auto * a
Definition: textangle.C:12