star-travex
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
H3D.cxx
Go to the documentation of this file.
1 #include "StiRootIO/H3D.h"
2 
3 #include "TROOT.h"
4 #include "TH2D.h"
5 #include "TError.h"
6 #include "TMath.h"
7 
9 
10 
11 TH2D *H3D::DoProject2D(const char* name, const char * title, TAxis* projX, TAxis* projY,
12  bool computeErrors, bool originalRange,
13  bool useUF, bool useOF) const
14 {
15  // internal method performing the projection to a 2D histogram
16  // called from TH3::Project3D
17 
18  TH2D *h2 = 0;
19 
20  // Get range to use as well as bin limits
21  Int_t ixmin = projX->GetFirst();
22  Int_t ixmax = projX->GetLast();
23  Int_t iymin = projY->GetFirst();
24  Int_t iymax = projY->GetLast();
25  if (ixmin == 0 && ixmax == 0) { ixmin = 1; ixmax = projX->GetNbins(); }
26  if (iymin == 0 && iymax == 0) { iymin = 1; iymax = projY->GetNbins(); }
27  Int_t nx = ixmax-ixmin+1;
28  Int_t ny = iymax-iymin+1;
29 
30  // Create the histogram, either reseting a preexisting one
31  // or creating one from scratch.
32  // Does an object with the same name exists?
33  TObject *h2obj = gROOT->FindObject(name);
34  if (h2obj && h2obj->InheritsFrom(TH1::Class())) {
35  if ( h2obj->IsA() != TH2D::Class() ) {
36  Error("DoProject2D","Histogram with name %s must be a TH2D and is a %s",name,h2obj->ClassName());
37  return 0;
38  }
39  h2 = (TH2D*)h2obj;
40  // reset histogram and its axes
41  h2->Reset();
42  const TArrayD *xbins = projX->GetXbins();
43  const TArrayD *ybins = projY->GetXbins();
44  if ( originalRange ) {
45  h2->SetBins(projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
46  ,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
47  // set bins for mixed axis do not exists - need to set afterwards the variable bins
48  if (ybins->fN != 0)
49  h2->GetXaxis()->Set(projY->GetNbins(),&ybins->fArray[iymin-1]);
50  if (xbins->fN != 0)
51  h2->GetYaxis()->Set(projX->GetNbins(),&xbins->fArray[ixmin-1]);
52  } else {
53  h2->SetBins(ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
54  ,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
55  if (ybins->fN != 0)
56  h2->GetXaxis()->Set(ny,&ybins->fArray[iymin-1]);
57  if (xbins->fN != 0)
58  h2->GetYaxis()->Set(nx,&xbins->fArray[ixmin-1]);
59  }
60  }
61 
62 
63  if (!h2) {
64  const TArrayD *xbins = projX->GetXbins();
65  const TArrayD *ybins = projY->GetXbins();
66  if ( originalRange )
67  {
68  if (xbins->fN == 0 && ybins->fN == 0) {
69  h2 = new TH2D(name,title,projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
70  ,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
71  } else if (ybins->fN == 0) {
72  h2 = new TH2D(name,title,projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
73  ,projX->GetNbins(),&xbins->fArray[ixmin-1]);
74  } else if (xbins->fN == 0) {
75  h2 = new TH2D(name,title,projY->GetNbins(),&ybins->fArray[iymin-1]
76  ,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
77  } else {
78  h2 = new TH2D(name,title,projY->GetNbins(),&ybins->fArray[iymin-1],projX->GetNbins(),&xbins->fArray[ixmin-1]);
79  }
80  } else {
81  if (xbins->fN == 0 && ybins->fN == 0) {
82  h2 = new TH2D(name,title,ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
83  ,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
84  } else if (ybins->fN == 0) {
85  h2 = new TH2D(name,title,ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
86  ,nx,&xbins->fArray[ixmin-1]);
87  } else if (xbins->fN == 0) {
88  h2 = new TH2D(name,title,ny,&ybins->fArray[iymin-1]
89  ,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
90  } else {
91  h2 = new TH2D(name,title,ny,&ybins->fArray[iymin-1],nx,&xbins->fArray[ixmin-1]);
92  }
93  }
94  }
95 
96  h2->SetLineColor(this->GetLineColor());
97  h2->SetFillColor(this->GetFillColor());
98  h2->SetMarkerColor(this->GetMarkerColor());
99  h2->SetMarkerStyle(this->GetMarkerStyle());
100 
101  // Activate errors
102  if ( computeErrors) h2->Sumw2();
103 
104  // Set references to the axis, so that the bucle has no branches.
105  const TAxis* out = 0;
106  if ( projX != GetXaxis() && projY != GetXaxis() ) {
107  out = GetXaxis();
108  } else if ( projX != GetYaxis() && projY != GetYaxis() ) {
109  out = GetYaxis();
110  } else {
111  out = GetZaxis();
112  }
113 
114  Int_t *refX = 0, *refY = 0, *refZ = 0;
115  Int_t ixbin, iybin, outbin;
116  if ( projX == GetXaxis() && projY == GetYaxis() ) { refX = &ixbin; refY = &iybin; refZ = &outbin; }
117  if ( projX == GetYaxis() && projY == GetXaxis() ) { refX = &iybin; refY = &ixbin; refZ = &outbin; }
118  if ( projX == GetXaxis() && projY == GetZaxis() ) { refX = &ixbin; refY = &outbin; refZ = &iybin; }
119  if ( projX == GetZaxis() && projY == GetXaxis() ) { refX = &iybin; refY = &outbin; refZ = &ixbin; }
120  if ( projX == GetYaxis() && projY == GetZaxis() ) { refX = &outbin; refY = &ixbin; refZ = &iybin; }
121  if ( projX == GetZaxis() && projY == GetYaxis() ) { refX = &outbin; refY = &iybin; refZ = &ixbin; }
122  R__ASSERT (refX != 0 && refY != 0 && refZ != 0);
123 
124  // Fill the projected histogram excluding underflow/overflows if considered in the option
125  // if specified in the option (by default they considered)
126  Double_t totcont = 0;
127 
128  Int_t outmin = out->GetFirst();
129  Int_t outmax = out->GetLast();
130  // GetFirst(), GetLast() can return (0,0) when the range bit is set artifically (see TAxis::SetRange)
131  if (outmin == 0 && outmax == 0) { outmin = 1; outmax = out->GetNbins(); }
132  // correct for underflow/overflows
133  if (useUF && !out->TestBit(TAxis::kAxisRange) ) outmin -= 1;
134  if (useOF && !out->TestBit(TAxis::kAxisRange) ) outmax += 1;
135 
136  for (ixbin=0;ixbin<=1+projX->GetNbins();ixbin++){
137  if ( projX->TestBit(TAxis::kAxisRange) && ( ixbin < ixmin || ixbin > ixmax )) continue;
138  Int_t ix = h2->GetYaxis()->FindBin( projX->GetBinCenter(ixbin) );
139 
140  for (iybin=0;iybin<=1+projY->GetNbins();iybin++){
141  if ( projY->TestBit(TAxis::kAxisRange) && ( iybin < iymin || iybin > iymax )) continue;
142  Int_t iy = h2->GetXaxis()->FindBin( projY->GetBinCenter(iybin) );
143 
144  Double_t cont = 0;
145  Double_t err2 = 0;
146 
147  // loop on the bins to be integrated (outbin should be called inbin)
148  for (outbin = outmin; outbin <= outmax; outbin++){
149 
150  Int_t bin = GetBin(*refX,*refY,*refZ);
151 
152  // sum the bin contents and errors if needed
153  cont += GetBinContent(bin);
154  if (computeErrors) {
155  Double_t exyz = GetBinError(bin);
156  err2 += exyz*exyz;
157  }
158 
159  }
160 
161  // remember axis are inverted
162  h2->SetBinContent(iy , ix, cont);
163  if (computeErrors) h2->SetBinError(iy, ix, TMath::Sqrt(err2) );
164  // sum all content
165  totcont += cont;
166 
167  }
168  }
169 
170  // since we use fill we need to reset and recalculate the statistics (see comment in DoProject1D )
171  // or keep original statistics if consistent sumw2
172  bool resetStats = true;
173  double eps = 1.E-12;
174  if (IsA() == TH3F::Class() ) eps = 1.E-6;
175  if (fTsumw != 0 && TMath::Abs( fTsumw - totcont) < TMath::Abs(fTsumw) * eps) resetStats = false;
176 
178  // entries are calculated using underflow/overflow. If excluded entries must be reset
179  resetEntries |= !useUF || !useOF;
180 
181  if (!resetStats) {
182  Double_t stats[kNstat];
183  Double_t oldst[kNstat]; // old statistics
184  for (Int_t i = 0; i < kNstat; ++i) { oldst[i] = 0; }
185  GetStats(oldst);
186  std::copy(oldst,oldst+kNstat,stats);
187  // not that projX refer to Y axis and projX refer to the X axis of projected histogram
188  // nothing to do for projection in Y vs X
189  if ( projY == GetXaxis() && projX == GetZaxis() ) { // case XZ
190  stats[4] = oldst[7];
191  stats[5] = oldst[8];
192  stats[6] = oldst[9];
193  }
194  if ( projY == GetYaxis() ) {
195  stats[2] = oldst[4];
196  stats[3] = oldst[5];
197  if ( projX == GetXaxis() ) { // case YX
198  stats[4] = oldst[2];
199  stats[5] = oldst[3];
200  }
201  if ( projX == GetZaxis() ) { // case YZ
202  stats[4] = oldst[7];
203  stats[5] = oldst[8];
204  stats[6] = oldst[10];
205  }
206  }
207  else if ( projY == GetZaxis() ) {
208  stats[2] = oldst[7];
209  stats[3] = oldst[8];
210  if ( projX == GetXaxis() ) { // case ZX
211  stats[4] = oldst[2];
212  stats[5] = oldst[3];
213  stats[6] = oldst[9];
214  }
215  if ( projX == GetYaxis() ) { // case ZY
216  stats[4] = oldst[4];
217  stats[5] = oldst[5];
218  stats[6] = oldst[10];
219  }
220  }
221  // set the new statistics
222  h2->PutStats(stats);
223  }
224  else {
225  // recalculate the statistics
226  h2->ResetStats();
227  }
228 
229  if (resetEntries) {
230  // use the effective entries for the entries
231  // since this is the only way to estimate them
232  Double_t entries = h2->GetEffectiveEntries();
233  if (!computeErrors) entries = TMath::Floor( entries + 0.5); // to avoid numerical rounding
234  h2->SetEntries( entries );
235  }
236  else {
237  h2->SetEntries( fEntries );
238  }
239 
240 
241  return h2;
242 }
243 
244 
245 void H3D::Print(Option_t *option) const
246 {
247  // Print some global quantities for this histogram.
248  //
249  // If option "base" is given, number of bins and ranges are also printed
250  // If option "range" is given, bin contents and errors are also printed
251  // for all bins in the current range (default 1-->nbins)
252  // If option "all" is given, bin contents and errors are also printed
253  // for all bins including under and overflows.
254 
255  printf( "TH1.Print Name = %s, Entries= %d, Total sum= %g\n",GetName(),Int_t(fEntries),GetSumOfWeights());
256  return;
257  TString opt = option;
258  opt.ToLower();
259  Int_t all;
260  if (opt.Contains("all")) all = 0;
261  else if (opt.Contains("range")) all = 1;
262  else if (opt.Contains("base")) all = 2;
263  else return;
264 
265  Int_t bin, binx, biny, binz;
266  Int_t firstx=0,lastx=0,firsty=0,lasty=0,firstz=0,lastz=0;
267  if (all == 0) {
268  lastx = fXaxis.GetNbins()+1;
269  if (fDimension > 1) lasty = fYaxis.GetNbins()+1;
270  if (fDimension > 2) lastz = fZaxis.GetNbins()+1;
271  } else {
272  firstx = fXaxis.GetFirst(); lastx = fXaxis.GetLast();
273  if (fDimension > 1) {firsty = fYaxis.GetFirst(); lasty = fYaxis.GetLast();}
274  if (fDimension > 2) {firstz = fZaxis.GetFirst(); lastz = fZaxis.GetLast();}
275  }
276 
277  if (all== 2) {
278  printf(" Title = %s\n", GetTitle());
279  printf(" NbinsX= %d, xmin= %g, xmax=%g", fXaxis.GetNbins(), fXaxis.GetXmin(), fXaxis.GetXmax());
280  if( fDimension > 1) printf(", NbinsY= %d, ymin= %g, ymax=%g", fYaxis.GetNbins(), fYaxis.GetXmin(), fYaxis.GetXmax());
281  if( fDimension > 2) printf(", NbinsZ= %d, zmin= %g, zmax=%g", fZaxis.GetNbins(), fZaxis.GetXmin(), fZaxis.GetXmax());
282  printf("\n");
283  return;
284  }
285 
286  Double_t w,e;
287  Double_t x,y,z;
288  if (fDimension == 1) {
289  for (binx=firstx;binx<=lastx;binx++) {
290  x = fXaxis.GetBinCenter(binx);
291  w = GetBinContent(binx);
292  e = GetBinError(binx);
293  if(fSumw2.fN) printf(" fSumw[%d]=%g, x=%g, error=%g\n",binx,w,x,e);
294  else printf(" fSumw[%d]=%g, x=%g\n",binx,w,x);
295  }
296  }
297  if (fDimension == 2) {
298  for (biny=firsty;biny<=lasty;biny++) {
299  y = fYaxis.GetBinCenter(biny);
300  for (binx=firstx;binx<=lastx;binx++) {
301  bin = GetBin(binx,biny,0);
302  x = fXaxis.GetBinCenter(binx);
303  w = GetBinContent(bin);
304  e = GetBinError(bin);
305  if (!w & !e) continue;
306  if(fSumw2.fN) printf(" fSumw[%d][%d]=%g, x=%g, y=%g, error=%g\n",binx,biny,w,x,y,e);
307  else printf(" fSumw[%d][%d]=%g, x=%g, y=%g\n",binx,biny,w,x,y);
308  }
309  }
310  }
311  if (fDimension == 3) {
312  for (binz=firstz;binz<=lastz;binz++) {
313  z = fZaxis.GetBinCenter(binz);
314  for (biny=firsty;biny<=lasty;biny++) {
315  y = fYaxis.GetBinCenter(biny);
316  for (binx=firstx;binx<=lastx;binx++) {
317  bin = GetBin(binx,biny,binz);
318  x = fXaxis.GetBinCenter(binx);
319  w = GetBinContent(bin);
320  e = GetBinError(bin);
321  if (!w & !e) continue;
322  if(fSumw2.fN) printf(" fSumw[%d][%d][%d]=%g, x=%g, y=%g, z=%g, error=%g\n",binx,biny,binz,w,x,y,z,e);
323  else printf(" fSumw[%d][%d][%d]=%g, x=%g, y=%g, z=%g\n",binx,biny,binz,w,x,y,z);
324  }
325  }
326  }
327  }
328 }
Int_t ixmax
Definition: H3D.cxx:22
Int_t outmin
Definition: H3D.cxx:128
Definition: H3D.h:7
double eps
Definition: H3D.cxx:173
ClassImp(AgUStep) extern"C"
Definition: AgUStep.cxx:8
Int_t * refX
Definition: H3D.cxx:114
Int_t * refY
Definition: H3D.cxx:114
Int_t ixbin
Definition: H3D.cxx:115
Double_t totcont
Definition: H3D.cxx:126
R__ASSERT(refX!=0 &&refY!=0 &&refZ!=0)
Int_t nx
Definition: H3D.cxx:27
return h2
Definition: H3D.cxx:241
Int_t outbin
Definition: H3D.cxx:115
void Print(Option_t *option) const
Definition: H3D.cxx:245
bool resetStats
Definition: H3D.cxx:172
Int_t iybin
Definition: H3D.cxx:115
Int_t outmax
Definition: H3D.cxx:129
ClassImp(H3D) TH2D *H3D Int_t ixmin
Definition: H3D.cxx:21
Int_t * refZ
Definition: H3D.cxx:114
Int_t ny
Definition: H3D.cxx:28
Int_t iymin
Definition: H3D.cxx:23
bool resetEntries
Definition: H3D.cxx:177
TObject * h2obj
Definition: H3D.cxx:33
Int_t iymax
Definition: H3D.cxx:24
const TAxis * out
Definition: H3D.cxx:105