Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
chebyshev_fit.C
Go to the documentation of this file.
1 
2 // Chebyshev polynomial functions
3 Double_t T0(Double_t x){return 1;}
4 Double_t T1(Double_t x){return x;}
5 Double_t T2(Double_t x){return 2*pow(x,2)-1;}
6 Double_t T3(Double_t x){return 4*pow(x,3)-3*x;}
7 Double_t T4(Double_t x){return 8*pow(x,4)-8*pow(x,2)+1;}
8 Double_t T5(Double_t x){return 16*pow(x,5)-20*pow(x,3)+5*x;}
9 Double_t T6(Double_t x){return 32*pow(x,6)-48*pow(x,4)+18*pow(x,2)-1;}
10 Double_t T7(Double_t x){return 64*pow(x,7)-112*pow(x,5)+56*pow(x,3)-7*x;}
11 Double_t T8(Double_t x){return 128*pow(x,8)-256*pow(x,6)+160*pow(x,4)-32*pow(x,2)+1;}
12 Double_t T9(Double_t x){return 256*pow(x,9)-576*pow(x,7)+432*pow(x,5)-120*pow(x,3)+9*x;}
13 
14 
15 //---------------------
16 // chebyshev_fit
17 //---------------------
18 void chebyshev_fit(void)
19 {
20  gROOT->Reset();
21  TColor::CreateColorWheel();
22 
24 }
25 
26 //---------------------
27 // ChebyshevTestFit
28 //---------------------
30 {
31  TCanvas *c1 = new TCanvas("c1");
32  c1->SetGrid();
33  c1->SetTicks();
34 
35  TH1D *h = new TH1D("h","A test histogram", 1000, -1.0, 1.0);
36  h->FillRandom("gaus", 1000000);
37 
38  TF1 *f = chebyshev_FindBestFunction(h);
39 
40  h->Draw();
41  f->SetLineColor(kRed);
42  f->Draw("same");
43 
44  UInt_t order = f->GetNpar() - 1;
45  cout<<"Chebyshev polynomial fit to data of order: "<<order<<endl;
46 }
47 
48 //---------------------
49 // chebyshev_Fit
50 //---------------------
51 TF1* chebyshev_Fit(TH1D *h, UInt_t order=9)
52 {
53  double xmin = h->GetXaxis()->GetXmin();
54  double xmax = h->GetXaxis()->GetXmax();
55  TF1 *f = chebyshev_MakeTF1(xmin, xmax, order);
56 
57  h->Fit(f, "0Q");
58  return f;
59 }
60 
61 //---------------------
62 // chebyshev_FindBestFunction
63 //---------------------
64 TF1* chebyshev_FindBestFunction(TH1D *h, UInt_t max_order=9)
65 {
66  // Verify histogram limits
67  if(h->GetXaxis()->GetXmin()!=-1.0 || h->GetXaxis()->GetXmax()!=+1.0){
68  cerr<<"-- ERROR! The limits of the histo passed to chebyshev_FindBestFunction"<<endl;
69  cerr<<"-- ERROR! MUST be -1.0 to +1.0 ("<<h->GetXaxis()->GetXmin()<<" and "<<h->GetXaxis()->GetXmax()<<" passed)"<<endl;
70  }
71 
72  // Loop over all orders keeping track of the one with the best chisq
73  UInt_t best_order = 0;
74  Double_t best_chisq_per_dof = 1.0E6;
75  for(UInt_t order=0; order<=max_order; order++){
76  TF1 *f = chebyshev_MakeTF1(order);
77  h->Fit(f, "0Q");
78  Double_t chisq_per_dof = f->GetChisquare()/(double)f->GetNDF();
79  cout<<"order "<<order<<": chisq="<<f->GetChisquare()<<" NDF="<<f->GetNDF()<<" chisq/NDF="<<chisq_per_dof<<endl;
80  if(chisq_per_dof<best_chisq_per_dof){
81  best_chisq_per_dof = chisq_per_dof;
82  best_order = order;
83  }
84  }
85 
86  // Regenerate and fit with best function
87  TF1 *best_func = chebyshev_MakeTF1(best_order);
88  h->Fit(best_func, "0Q");
89 
90  return best_func;
91 }
92 
93 //---------------------
94 // chebyshev_MakeTF1
95 //---------------------
96 TF1* chebyshev_MakeTF1(Double_t xmin, Double_t xmax, UInt_t order)
97 {
98  // ROOT gives a "Too many operators !" error when we try and define
99  // past order 9. Truncate it with a warning if too high of an order
100  // is specified.
101  if(order>9){
102  cerr<<"--WARNING! The maximum order that can be used is 9"<<endl;
103  cerr<<"--WARNING! order="<<order<<" will be reduced to 9"<<endl;
104  order = 9;
105  }
106 
107  // Build function string of given order
108  stringstream func_str;
109  for(UInt_t i=0; i<=order; i++){
110  if(i!=0)func_str<<"+";
111  func_str<<"["<<i+2<<"]*T"<<i<<"((x-[0])/[1])";
112  }
113 
114  // Create Function
115  stringstream funcname;
116  funcname<<"polT"<<order;
117  TF1 *myfunc = new TF1(funcname.str().c_str(), func_str.str().c_str(), xmin, xmax);
118 
119  // Parmeters used to convert x to -1 to 1 coordinates
120  double xmid = (xmax+xmin)/2.0;
121  double xnorm = (xmax-xmin)/2.0;
122 
123  // Set initial parameter values and parameter names
124  myfunc->SetParName(0, "xmid");
125  myfunc->SetParName(1, "xnorm");
126  myfunc->FixParameter(0, xmid);
127  myfunc->FixParameter(1, xnorm);
128  for(UInt_t i=0; i<=order; i++){
129  stringstream fname;
130  fname<<"T"<<i;
131  myfunc->SetParName(i+2, fname.str().c_str());
132  myfunc->SetParameter(i+2, 1.0);
133  }
134 
135  return myfunc;
136 }
137 
138 
void chebyshev_fit(void)
Definition: chebyshev_fit.C:18
Double_t T5(Double_t x)
Definition: chebyshev_fit.C:8
Double_t T1(Double_t x)
Definition: chebyshev_fit.C:4
Double_t x[NCHANNELS]
Definition: st_tw_resols.C:39
Double_t T6(Double_t x)
Definition: chebyshev_fit.C:9
Double_t T2(Double_t x)
Definition: chebyshev_fit.C:5
Double_t c1[2][NMODULES]
Definition: tw_corr.C:68
void ChebyshevTestFit()
Definition: chebyshev_fit.C:29
TF1 * f
Definition: FitGains.C:21
Double_t T3(Double_t x)
Definition: chebyshev_fit.C:6
Double_t T0(Double_t x)
Definition: chebyshev_fit.C:3
TF1 * chebyshev_FindBestFunction(TH1D *h, UInt_t max_order=9)
Definition: chebyshev_fit.C:64
Double_t T8(Double_t x)
Definition: chebyshev_fit.C:11
Double_t T9(Double_t x)
Definition: chebyshev_fit.C:12
TF1 * chebyshev_MakeTF1(Double_t xmin, Double_t xmax, UInt_t order)
Definition: chebyshev_fit.C:96
Double_t T4(Double_t x)
Definition: chebyshev_fit.C:7
TF1 * chebyshev_Fit(TH1D *h, UInt_t order=9)
Definition: chebyshev_fit.C:51
Double_t T7(Double_t x)
Definition: chebyshev_fit.C:10