Logo ROOT  
Reference Guide
THnChain.cxx
Go to the documentation of this file.
1// @(#)root/hist:$Id$
2// Author: Benjamin Bannier, August 2016
3
4/*************************************************************************
5 * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include "THnChain.h"
13
14#include "TArray.h"
15#include "TAxis.h"
16#include "TDirectory.h"
17#include "TFile.h"
18#include "TH1.h"
19#include "TH2.h"
20#include "TH3.h"
21#include "THnBase.h"
22#include "TMath.h"
23
24void THnChain::AddFile(const char* fileName)
25{
26 fFiles.emplace_back(fileName);
27
28 // Initialize axes from first seen instance.
29 if (fAxes.empty()) {
30 THnBase* hs = ReadHistogram(fileName);
31
32 if (hs) {
33 const Int_t naxes = hs->GetNdimensions();
34 for (Int_t i = 0; i < naxes; ++i) {
35 fAxes.push_back(hs->GetAxis(i));
36 }
37 } else {
38 Warning("AddFile",
39 "Could not find histogram %s in file %s",
40 fName.c_str(),
41 fileName);
42 }
43 }
44}
45
47{
48 if (i < 0 || i >= static_cast<Int_t>(fAxes.size())) {
49 return nullptr;
50 }
51
52 return fAxes[i];
53}
54
55TObject* THnChain::ProjectionAny(Int_t ndim, const Int_t* dim, Option_t* option) const
56{
57 if (ndim <= 0) {
58 return nullptr;
59 }
60
61 TObject* h_merged = nullptr;
62 for (const auto& file : fFiles) {
63 THnBase* hs = ReadHistogram(file.c_str());
64
65 if (!hs) {
66 Warning("ProjectionAny",
67 "Could not find histogram %s in file %s",
68 fName.c_str(),
69 file.c_str());
70
71 continue;
72 }
73
74 if (!CheckConsistency(*hs, fAxes)) {
75 Warning("ProjectionAny",
76 "Histogram %s from file %s is inconsistent with the histogram from file %s",
77 fName.c_str(),
78 file.c_str(),
79 fFiles[0].c_str());
80
81 continue;
82 }
83
84 SetupAxes(*hs);
85
86 // Perform projection.
87 TObject* h = nullptr;
88
89 if (ndim == 1) {
90 h = hs->Projection(dim[0], option);
91 } else if (ndim == 2) {
92 h = hs->Projection(dim[0], dim[1], option);
93 } else if (ndim == 3) {
94 h = hs->Projection(dim[0], dim[1], dim[2], option);
95 } else {
96 h = hs->ProjectionND(ndim, dim, option);
97 }
98
99 delete hs;
100
101 // Add this histogram.
102 if (h_merged) {
103 if (ndim < 3) {
104 static_cast<TH1*>(h_merged)->Add(static_cast<TH1*>(h));
105 } else {
106 static_cast<THnBase*>(h_merged)->Add(static_cast<THnBase*>(h));
107 }
108
109 delete h;
110 } else {
111 h_merged = h;
112 }
113 }
114
115 return h_merged;
116}
117
118THnBase* THnChain::ReadHistogram(const char* fileName) const
119{
121
122 TFile* f = TFile::Open(fileName);
123
124 if (!f) {
125 return nullptr;
126 }
127
128 THnBase* hs = nullptr;
129 f->GetObject(fName.c_str(), hs);
130 delete f;
131
132 return hs;
133}
134
136{
137 const Int_t naxes = fAxes.size();
138 for (Int_t i = 0; i < naxes; ++i) {
139 const TAxis* ax_ref = fAxes[i];
140 TAxis* ax = hs.GetAxis(i);
141 ax_ref->Copy(*ax);
142 }
143}
144
145bool THnChain::CheckConsistency(const THnBase& h, const std::vector<TAxis*>& axes)
146{
147 // We would prefer to directly use `TH1::CheckEqualAxes` here;
148 // however it is protected so we inherit the parts we care about.
149 // FIXME(bbannier): It appears that functionality like `TH1::CheckEqualAxes` could
150 // just as well live in `TAxis` so that anyone using axes could make use of it.
151 const Int_t naxes = h.GetNdimensions();
152 const Int_t naxes2 = axes.size();
153
154 if (naxes != naxes2) {
155 return false;
156 }
157
158 for (Int_t i = 0; i < naxes; ++i) {
159 const TAxis* ax1 = h.GetAxis(i);
160 const TAxis* ax2 = axes[i];
161
162 if (ax1->GetNbins() != ax2->GetNbins()) {
163 return false;
164 }
165
166 // Copied from `TH1::CheckAxisLimits.`
167 if (!TMath::AreEqualRel(ax1->GetXmin(), ax2->GetXmin(), 1.E-12) ||
168 !TMath::AreEqualRel(ax1->GetXmax(), ax2->GetXmax(), 1.E-12)) {
169 return false;
170 }
171
172 // Copied from `TH1::CheckBinLimits`.
173 const TArrayD* h1Array = ax1->GetXbins();
174 const TArrayD* h2Array = ax2->GetXbins();
175 Int_t fN = h1Array->fN;
176 if (fN != 0) {
177 if (h2Array->fN != fN) {
178 return false;
179 } else {
180 for (int ibin = 0; ibin < fN; ++ibin) {
181 if (!TMath::AreEqualRel(h1Array->GetAt(ibin), h2Array->GetAt(ibin), 1E-10)) {
182 return false;
183 }
184 }
185 }
186 }
187
188 // We ignore checking for equal bin labels here. A check
189 // for that is implemented in `TH1::CheckBinLabels`.
190 }
191
192 return true;
193}
194
196{
197 // Forwards to `THnBase::Projection()`.
198 Int_t dim[1] = {xDim};
199 return static_cast<TH1*>(ProjectionAny(1, dim, option));
200}
201
202TH2* THnChain::Projection(Int_t yDim, Int_t xDim, Option_t* option) const
203{
204 // Forwards to `THnBase::Projection()`.
205 Int_t dim[2] = {xDim, yDim};
206 return static_cast<TH2*>(ProjectionAny(2, dim, option));
207}
208
209TH3* THnChain::Projection(Int_t xDim, Int_t yDim, Int_t zDim, Option_t* option) const
210{
211 // Forwards to `THnBase::Projection()`.
212 Int_t dim[3] = {xDim, yDim, zDim};
213 return static_cast<TH3*>(ProjectionAny(3, dim, option));
214}
215
216THnBase* THnChain::ProjectionND(Int_t ndim, const Int_t* dim, Option_t* option) const
217{
218 // Forwards to `THnBase::ProjectionND()`.
219 return static_cast<THnBase*>(ProjectionAny(ndim, dim, option));
220}
#define f(i)
Definition: RSha256.hxx:104
#define h(i)
Definition: RSha256.hxx:106
const char Option_t
Definition: RtypesCore.h:64
#define gDirectory
Definition: TDirectory.h:229
Array of doubles (64 bits per element).
Definition: TArrayD.h:27
Double_t GetAt(Int_t i) const
Definition: TArrayD.h:45
Int_t fN
Definition: TArray.h:38
Class to manage histogram axis.
Definition: TAxis.h:30
const TArrayD * GetXbins() const
Definition: TAxis.h:130
Double_t GetXmax() const
Definition: TAxis.h:134
virtual void Copy(TObject &axis) const
Copy axis structure to another axis.
Definition: TAxis.cxx:207
Double_t GetXmin() const
Definition: TAxis.h:133
Int_t GetNbins() const
Definition: TAxis.h:121
Small helper to keep current directory context.
Definition: TDirectory.h:47
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition: TFile.h:53
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
Definition: TFile.cxx:3942
The TH1 histogram class.
Definition: TH1.h:56
Service class for 2-Dim histogram classes.
Definition: TH2.h:30
The 3-D histogram classes derived from the 1-D histogram classes.
Definition: TH3.h:31
Multidimensional histogram base.
Definition: THnBase.h:43
TH1D * Projection(Int_t xDim, Option_t *option="") const
Project all bins into a 1-dimensional histogram, keeping only axis "xDim".
Definition: THnBase.h:197
Int_t GetNdimensions() const
Definition: THnBase.h:135
THnBase * ProjectionND(Int_t ndim, const Int_t *dim, Option_t *option="") const
Definition: THnBase.h:228
TAxis * GetAxis(Int_t dim) const
Definition: THnBase.h:125
TAxis * GetAxis(Int_t i) const
Get an axis from the histogram.
Definition: THnChain.cxx:46
std::vector< TAxis * > fAxes
the list of histogram axes
Definition: THnChain.h:90
THnBase * ReadHistogram(const char *fileName) const
Retrieve a histogram from a file.
Definition: THnChain.cxx:118
void SetupAxes(THnBase &hs) const
Copy the properties of all axes to a histogram.
Definition: THnChain.cxx:135
THnBase * ProjectionND(Int_t ndim, const Int_t *dim, Option_t *option="") const
See THnBase::Projection for the intended behavior.
Definition: THnChain.cxx:216
TObject * ProjectionAny(Int_t ndim, const Int_t *dim, Option_t *option="") const
Projects all histograms in the chain.
Definition: THnChain.cxx:55
static bool CheckConsistency(const THnBase &h, const std::vector< TAxis * > &axes)
Ensure a histogram has axes similar to the ones we expect.
Definition: THnChain.cxx:145
void AddFile(const char *fileName)
Add a new file to this chain.
Definition: THnChain.cxx:24
TH1 * Projection(Int_t xDim, Option_t *option="") const
See THnBase::Projection for the intended behavior.
Definition: THnChain.cxx:195
std::string fName
name of the histogram
Definition: THnChain.h:87
std::vector< std::string > fFiles
a list of files to extract the histogram from
Definition: THnChain.h:89
Mother of all ROOT objects.
Definition: TObject.h:37
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:877
void Add(RHist< DIMENSIONS, PRECISION, STAT_TO... > &to, const RHist< DIMENSIONS, PRECISION, STAT_FROM... > &from)
Add two histograms.
Definition: RHist.hxx:323
constexpr Double_t E()
Base of natural log:
Definition: TMath.h:97
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Definition: TMath.h:418
Definition: file.py:1