StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
TH1Helper.cxx
1 /***************************************************************************
2  *
3  * $Id: TH1Helper.cxx,v 1.5 2021/05/17 17:38:27 perev Exp $
4  *
5  ***************************************************************************
6  *
7  * Description:
8  *
9  ***************************************************************************
10  **************************************************************************/
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <assert.h>
15 
16 #include "TH1Helper.h"
17 #include "TMath.h"
18 
19 //ClassImp(TH1Helper)
20 //______________________________________________________________________________
21 void TH1Helper::SetCanRebin(TH1 *h, int axis)
22 {
23 #if ROOT_VERSION_CODE < ROOT_VERSION(6,0,0)
24  h->SetBit(TH1::kCanRebin);
25 #else
26  if (!axis) axis = TH1::kAllAxes;
27  h->SetCanExtend(axis);
28 #endif
29 }
30 
31 //______________________________________________________________________________
32 TH1Helper::TH1Helper(const TH1 *h, int binMin, int binMax)
33 {
34  fNonZeros=0;
35  if(h==0) return;
36  Set(h,binMin,binMax);
37 }
38 //______________________________________________________________________________
39 TH1Helper::TH1Helper(const TH1 *h, double xMin, double xMax)
40 {
41  Set(h,xMin,xMax);
42 }
43 //______________________________________________________________________________
44 void TH1Helper::Set(const TH1 *h, double xMin, double xMax)
45 {
46  fH1 = h;
47  fBMin = 0;
48  fBMax = 0;
49  fXMin = xMin;
50  fXMax = xMax;
51  Build();
52 }
53 //______________________________________________________________________________
54 void TH1Helper::Set(const TH1 *h, int binMin, int binMax)
55 {
56  fH1 = h;
57  fBMin = binMin;
58  fBMax = binMax;
59  fXMin = 0;
60  fXMax = 0;
61  Build();
62 }
63 //______________________________________________________________________________
64 TH1Helper::~TH1Helper()
65 {
66 }
67 //______________________________________________________________________________
68 void TH1Helper::Build()
69 {
70  const TAxis *ax = fH1->GetXaxis();
71  int nbins = ax->GetNbins();
72  if (fBMax) { //1st constructor
73  if (fBMin < 1) fBMin = 1;
74  if (fBMax > nbins) fBMax = nbins;
75  fXMin = ax->GetBinLowEdge(fBMin);
76  fXMax = ax->GetBinUpEdge (fBMax);
77  } else { //2nd constructor
78 
79  fBMin = ax->FindFixBin(fXMin);
80  if (fBMin < 1) fBMin = 1;
81  fBMax = ax->FindFixBin(fXMax);
82  if (fBMax > nbins) fBMax = nbins;
83  if (fXMin < ax->GetBinLowEdge(fBMin)) fXMin = ax->GetBinLowEdge(fBMin);
84  if (fXMax > ax->GetBinUpEdge (fBMax)) fXMax = ax->GetBinUpEdge (fBMax);
85  }
86  memset(fMom,0,sizeof(fMom));
87  fNonZeros = 0;
88  for (int i=fBMin; i<=fBMax; i++) if(fH1->GetBinContent(i)) fNonZeros++;
89 
90  fMom[0] = 9.e-99;
91 
92 }
93 
94 //______________________________________________________________________________
95 void TH1Helper::Aver()
96 {
97  if (!fNonZeros) return;
98  if (fMom[2]) return;
99  const TAxis *ax = fH1->GetXaxis();
100  double ovl[2][6];
101  double h,error,content,part,center,low,upp;
102 
103 // first bin overlap
104  error = fH1->GetBinError (fBMin);
105  content = fH1->GetBinContent(fBMin);
106  h = ax ->GetBinWidth (fBMin);
107  low = fXMin;
108  upp = ax->GetBinUpEdge(fBMin);
109  if (upp>fXMax) upp = fXMax;
110  ovl[0][0] = 0.5*(low + upp); //partial Center
111  ovl[0][1] = (upp-low); //partial width
112  part = ovl[0][1]/h;
113  ovl[0][2] = content*part; //partial content
114  ovl[0][3] = error*TMath::Sqrt(part); //partial error
115  ovl[0][4] = low; //low edge
116  ovl[0][5] = upp; //upp edge
117 
118 
119 // last bin overlap
120  error = fH1->GetBinError (fBMax);
121  content = fH1->GetBinContent(fBMax);
122  h = ax ->GetBinWidth (fBMax);
123  low = ax->GetBinLowEdge (fBMax);
124  if (low<ovl[0][5]) low = ovl[0][5];
125  upp = fXMax;
126  part = (upp-low)/h;
127  ovl[1][0] = 0.5*(low+upp); //partial Center
128  ovl[1][1] = (upp-low); //partial width
129  ovl[1][2] = content*part; //partial content
130  ovl[1][3] = error*TMath::Sqrt(part); //partial error
131  ovl[1][4] = low; //low edge
132  ovl[1][5] = upp; //upp edge
133  double wtot=0,wt,fun;
134  for (int iter=0;iter <=2;iter++) {
135  for (int ibin = fBMin; ibin <= fBMax; ibin++) {
136  int jk = -1;
137  if (ibin == fBMin) jk=0;
138  if (ibin == fBMax) jk=1;
139 
140  if (jk>=0) {
141  center = ovl[jk][0];
142  h = ovl[jk][1];
143  content = ovl[jk][2];
144  error = ovl[jk][3];
145  low = ovl[jk][4];
146  upp = ovl[jk][5];
147  } else {
148  center = ax->GetBinCenter(ibin);
149  h = ax ->GetBinWidth(ibin);
150  content = fH1->GetBinContent(ibin);
151  error = fH1->GetBinError (ibin);
152  low = ax->GetBinLowEdge (ibin);
153  upp = ax->GetBinUpEdge (ibin);
154 
155  }
156  if (!content) continue;
157  wt = content;
158  if ( iter==0 ) {
159  wtot +=wt;
160  fMom[0] += content;
161  fun = center;
162  fMom[1] += fun*content;
163  continue;
164  }
165  if ( iter==1 ) {
166  fun = h*h/12 + TMath::Power(center-fMom[1],2);
167  fMom[2] += fun*content;
168  continue;
169  }
170  if ( iter==2 ) {
171  fun = 0;
172  for (int i=0;i<3;i++){fun += TMath::Power(TMath::Power(low-fMom[1]+i*h/2,2)-fMom[2],2);}
173  fun /=3;
174  fMom[4] += fun*content;
175  continue;
176  }
177 
178  }// end bin loop
179  if (!fNonZeros) fMom[0] = 9.e-99;
180  fMom[(1<<iter)] /=fMom[0];
181  }//end iter loop
182 
183 }
184 double TH1Helper::GetMean () {Aver();return fMom[1]; }
185 double TH1Helper::GetMeanErr () {Aver();return TMath::Sqrt(fMom[2]/fMom[0]);}
186 double TH1Helper::GetRMS () {Aver();return TMath::Sqrt(fMom[2]); }
187 double TH1Helper::GetRMSErr () {Aver();return TMath::Sqrt(fMom[4]/fMom[0]);}
188 int TH1Helper::GetNonZeros() const { return fNonZeros; }
189 double TH1Helper::GetIntegral() {Aver();return fMom[0]; }
190 double TH1Helper::GetIntegErr() {Aver();return TMath::Sqrt(fMom[0]); }