Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
fit_channel_hist.C
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file fit_channel_hist.C
1 #include <TH1.h>
2 #include <TStyle.h>
3 #include <TCanvas.h>
4 #include <TMath.h>
5 #include <TF1.h>
6 #include "TROOT.h"
7 #include <iostream>
8 #include <string>
9 #include <fstream>
10 #include <TAxis.h>
11 #include <TGraph.h>
12 #include <TSpectrum.h>
13 
14 double gamma_function(double *x, double *par) {
15  double peak = par[0];
16  double shift = par[1];
17  double scale = par[2];
18  double N = par[3];
19 
20  double arg_para = (x[0] - shift) / scale;
21  double peak_para = (peak - shift) / scale;
22  double numerator = N * pow(arg_para, peak_para) * TMath::Exp(-arg_para);
23  double denominator = ROOT::Math::tgamma(peak_para + 1) * scale;
24 
25  if (denominator != 0) return (double)(numerator / denominator);
26  else return 0;
27 }
28 
29 float get_temp_shift(TH1F* hist, float y) {
30  float shift = 0.;
31  for (int i = 1; i <= hist->GetNbinsX(); i++) {
32  if (hist->GetBinContent(i) > y/10.) {
33  shift = hist->GetBinCenter(i);
34  break;
35  }
36  }
37  return shift;
38 }
39 
40 float get_temp_scale(TH1F* hist, float x) {
41  float scale = (hist->GetMean() - x);
42  return scale;
43 }
44 
45 float get_temp_N(float x, float y, float shift, float scale) {
46  float temp_par0 = (x - shift) / scale;
47  float temp_par1 = pow(temp_par0, temp_par0) * TMath::Exp(-temp_par0);
48  float temp_par2 = ROOT::Math::tgamma(temp_par0 + 1) * scale * y;
49  float temp_N = temp_par2 / temp_par1;
50  return temp_N;
51 }
52 
53 float get_fit_min(TH1F* hist, float y) {
54  float min = 0.;
55  for (int i = 1; i <= hist->GetNbinsX(); i++) {
56  if (hist->GetBinContent(i) > 2*y/3.) {
57  min = hist->GetBinCenter(i);
58  if (hist->GetBinContent(i) > 3*y/4.) {
59  min = hist->GetBinCenter(i-1);
60  }
61  break;
62  }
63  }
64  return min;
65 }
66 
67 float get_fit_max(TH1F* hist, float y) {
68  float max = 0.;
69  for (int i = hist->GetNbinsX(); i >= 1; i--) {
70  if (hist->GetBinContent(i) > y/5.) {
71  max = hist->GetBinCenter(i);
72  break;
73  }
74  }
75  return max;
76 }
77 
78 void do_peak_finder(TH1F* hist, float& x, float& y, float& shift, float& scale, float& N, float& min, float& max) {
79  TH1F *h_peakfinder = (TH1F*)hist->Clone("h_peakfinder");
80  h_peakfinder->Smooth(2);
81  TSpectrum *s = new TSpectrum(10);
82  int nfound = 0;
83  nfound = s->Search(h_peakfinder, 2, "nobackground new", 0.6);
84  if (nfound == 0) {
85  int index = hist->GetMaximumBin();
86  x = hist->GetBinCenter(index);
87  y = hist->GetBinContent(index);
88  } else {
89  double *xtemp = s->GetPositionX();
90  double *ytemp = s->GetPositionY();
91  x = xtemp[0];
92  y = ytemp[0];
93  }
94  shift = get_temp_shift(h_peakfinder, y);
95  scale = get_temp_scale(hist, x);
96  N = get_temp_N(x, y, shift, scale);
97  min = get_fit_min(h_peakfinder, y);
98  max = get_fit_max(h_peakfinder, y);
99  delete h_peakfinder;
100  delete s;
101 }
102 
103 void do_peak_fit(TH1F* hist, TF1* func) {
104  float peak_position_finder, peak_value_finder, shift_finder, scale_finder, N_finder, min_finder, max_finder;
105  do_peak_finder(hist, peak_position_finder, peak_value_finder, shift_finder, scale_finder, N_finder, min_finder, max_finder);
106  func->SetParameter(0, peak_position_finder);
107  func->SetParameter(1, shift_finder);
108  func->SetParameter(2, scale_finder);
109  func->SetParameter(3, N_finder);
110  hist->Fit(func, "", "", min_finder, max_finder);
111 }
112 
114  // Constant
115  static const int n_etabin = 24;
116  static const int n_phibin = 64;
117 
118  // File
119  TFile *ohcal_input = new TFile("../macro/ohcal_hist.root","READ");
120  TFile *ihcal_input = new TFile("../macro/ihcal_hist.root","READ");
121  std::ofstream total_mpvinfo("total_mpvinfo.txt",ios::trunc);
122  TFile *ohcal_output = new TFile("ohcal_fitresult.root","recreate");
123  std::ofstream ohcal_mpvinfo("ohcal_mpvinfo.txt",ios::trunc);
124  std::ofstream ohcal_calibinfo("ohcal_calibinfo.txt",ios::trunc);
125  TFile *ihcal_output = new TFile("ihcal_fitresult.root","recreate");
126  std::ofstream ihcal_mpvinfo("ihcal_mpvinfo.txt",ios::trunc);
127  std::ofstream ihcal_calibinfo("ihcal_calibinfo.txt",ios::trunc);
128 
129  // oHCal setup
130  TH2F *h_2Dohcal_hit = new TH2F("h_2Dohcal_hit", "", n_etabin, 0, n_etabin, n_phibin, 0, n_phibin);
131  h_2Dohcal_hit->GetXaxis()->SetTitle("ieta");
132  h_2Dohcal_hit->GetYaxis()->SetTitle("iphi");
133  TH1F *h_ohcal_total;
134  h_ohcal_total = new TH1F("h_ohcal_total","",200,0,10000);
135  h_ohcal_total->GetXaxis()->SetTitle("ADC");
136  h_ohcal_total->GetYaxis()->SetTitle("Counts");
137  TH1F *h_ohcal_channel[n_etabin][n_phibin];
138  for (int ieta = 0; ieta < n_etabin; ++ieta) {
139  for (int iphi = 0; iphi < n_phibin; ++iphi) {
140  std::ostringstream h_ohcal_channelname;
141  h_ohcal_channelname << "h_ohcal_channel_" << ieta << "_" << iphi;
142  h_ohcal_channel[ieta][iphi] = new TH1F(h_ohcal_channelname.str().c_str(), "", 200, 0, 10000);
143  h_ohcal_channel[ieta][iphi]->GetXaxis()->SetTitle("ADC");
144  h_ohcal_channel[ieta][iphi]->GetYaxis()->SetTitle("Counts");
145  }
146  }
147  TH1F *h_ohcal_chindf = new TH1F("h_ohcal_chindf","",50,0,10);
148  h_ohcal_chindf->GetXaxis()->SetTitle("Chi^2/NDF");
149  h_ohcal_chindf->GetYaxis()->SetTitle("Counts");
150 
151  // iHCal setup
152  TH2F *h_2Dihcal_hit = new TH2F("h_2Dihcal_hit", "", n_etabin, 0, n_etabin, n_phibin, 0, n_phibin);
153  h_2Dihcal_hit->GetXaxis()->SetTitle("ieta");
154  h_2Dihcal_hit->GetYaxis()->SetTitle("iphi");
155  TH1F *h_ihcal_total;
156  h_ihcal_total = new TH1F("h_ihcal_total","",200,0,10000);
157  h_ihcal_total->GetXaxis()->SetTitle("ADC");
158  h_ihcal_total->GetYaxis()->SetTitle("Counts");
159  TH1F *h_ihcal_channel[n_etabin][n_phibin];
160  for (int ieta = 0; ieta < n_etabin; ++ieta) {
161  for (int iphi = 0; iphi < n_phibin; ++iphi) {
162  std::ostringstream h_ihcal_channelname;
163  h_ihcal_channelname << "h_ihcal_channel_" << ieta << "_" << iphi;
164  h_ihcal_channel[ieta][iphi] = new TH1F(h_ihcal_channelname.str().c_str(), "", 200, 0, 10000);
165  h_ihcal_channel[ieta][iphi]->GetXaxis()->SetTitle("ADC");
166  h_ihcal_channel[ieta][iphi]->GetYaxis()->SetTitle("Counts");
167  }
168  }
169  TH1F *h_ihcal_chindf = new TH1F("h_ihcal_chindf","",50,0,10);
170  h_ihcal_chindf->GetXaxis()->SetTitle("Chi^2/NDF");
171  h_ihcal_chindf->GetYaxis()->SetTitle("Counts");
172 
173  // Read hist
174  TH1F *h_temp_channel;
175  for (int ieta = 0; ieta < n_etabin; ++ieta) {
176  for (int iphi = 0; iphi < n_phibin; ++iphi) {
177  std::ostringstream h_temp_channelname;
178  h_temp_channelname << "h_channel_" << ieta << "_" << iphi;
179  h_temp_channel = (TH1F*)ohcal_input->Get(h_temp_channelname.str().c_str());
180  h_ohcal_channel[ieta][iphi]->Add(h_temp_channel);
181  h_ohcal_total->Add(h_temp_channel);
182  h_temp_channel = (TH1F*)ihcal_input->Get(h_temp_channelname.str().c_str());
183  h_ihcal_channel[ieta][iphi]->Add(h_temp_channel);
184  h_ihcal_total->Add(h_temp_channel);
185  }
186  }
187  ohcal_input->Close();
188  ihcal_input->Close();
189 
190  // Fit hist.
191  float peak_ohcal_total, peak_ihcal_total, chindf_ohcal_total, chindf_ihcal_total;
192  float peak_ohcal[n_etabin][n_phibin], peak_ihcal[n_etabin][n_phibin];
193  float chindf_ohcal[n_etabin][n_phibin], chindf_ihcal[n_etabin][n_phibin];
194  TF1 *f_gamma = new TF1("f_gamma", gamma_function, 0, 10000, 4);
195  f_gamma->SetParName(0,"Peak(ADC)");
196  f_gamma->SetParName(1,"Shift");
197  f_gamma->SetParName(2,"Scale");
198  f_gamma->SetParName(3,"N");
199 
200  do_peak_fit(h_ohcal_total, f_gamma);
201  peak_ohcal_total = f_gamma->GetParameter(0);
202  chindf_ohcal_total = f_gamma->GetChisquare() / (float)f_gamma->GetNDF();
203 
204  do_peak_fit(h_ihcal_total, f_gamma);
205  peak_ihcal_total = f_gamma->GetParameter(0);
206  chindf_ihcal_total = f_gamma->GetChisquare() / (float)f_gamma->GetNDF();
207  for (int ieta = 0; ieta < n_etabin; ++ieta) {
208  for (int iphi = 0; iphi < n_phibin; ++iphi) {
209  do_peak_fit(h_ohcal_channel[ieta][iphi], f_gamma);
210  peak_ohcal[ieta][iphi] = f_gamma->GetParameter(0);
211  chindf_ohcal[ieta][iphi] = f_gamma->GetChisquare() / (float)f_gamma->GetNDF();
212  h_ohcal_chindf->Fill(chindf_ohcal[ieta][iphi]);
213  do_peak_fit(h_ihcal_channel[ieta][iphi], f_gamma);
214  peak_ihcal[ieta][iphi] = f_gamma->GetParameter(0);
215  chindf_ihcal[ieta][iphi] = f_gamma->GetChisquare() / (float)f_gamma->GetNDF();
216  h_ihcal_chindf->Fill(chindf_ihcal[ieta][iphi]);
217 
218  h_2Dohcal_hit->SetBinContent(ieta+1, iphi+1, h_ohcal_channel[ieta][iphi]->GetEntries());
219  h_2Dihcal_hit->SetBinContent(ieta+1, iphi+1, h_ihcal_channel[ieta][iphi]->GetEntries());
220  }
221  }
222  delete f_gamma;
223 
224  // Output.
225  // Get Calib info.
226  float ihcal_samplingfraction = 0.162166;
227  float ohcal_samplingfraction = 3.38021e-02;
228  float ihcal_mipcalib, ohcal_mipcalib, ihcal_abscalib, ohcal_abscalib;
229  for (int ieta = 0; ieta < n_etabin; ++ieta) {
230  for (int iphi = 0; iphi < n_phibin; ++iphi) {
231  ihcal_mipcalib = peak_ihcal[ieta][iphi] / 32.;
232  ohcal_mipcalib = peak_ohcal[ieta][iphi] / 32.;
233  ihcal_abscalib = 1. / ihcal_mipcalib / ihcal_samplingfraction; // abs calib in GeV per ADC
234  ohcal_abscalib = 1. / ohcal_mipcalib / ohcal_samplingfraction; // abs calib in GeV per ADC
235  ihcal_calibinfo << ieta << "\t" << iphi << "\t" << ihcal_abscalib << std::endl;
236  ohcal_calibinfo << ieta << "\t" << iphi << "\t" << ohcal_abscalib << std::endl;
237  }
238  }
239 
240  total_mpvinfo << "oHCal: MPV = " << peak_ohcal_total << ", Chi^2/NDF = " << chindf_ohcal_total << std::endl;
241  total_mpvinfo << "iHCal: MPV = " << peak_ihcal_total << ", Chi^2/NDF = " << chindf_ihcal_total << std::endl;
242  total_mpvinfo << std::endl << "Channel-by-channel Chi^2/NDF value: " << std::endl << " oHCal:" << h_ohcal_chindf->GetMean() << std::endl << " iHCal:" << h_ihcal_chindf->GetMean() << std::endl;
243  std::vector<int> badfit_eta_ohcal, badfit_phi_ohcal, badfit_eta_ihcal, badfit_phi_ihcal;
244  for (int ieta = 0; ieta < n_etabin; ++ieta) {
245  for (int iphi = 0; iphi < n_phibin; ++iphi) {
246  if (chindf_ohcal[ieta][iphi] > 2) {
247  badfit_eta_ohcal.push_back(ieta);
248  badfit_phi_ohcal.push_back(iphi);
249  }
250  if (chindf_ihcal[ieta][iphi] > 2) {
251  badfit_eta_ihcal.push_back(ieta);
252  badfit_phi_ihcal.push_back(iphi);
253  }
254  ohcal_output->cd();
255  h_ohcal_channel[ieta][iphi]->Write();
256  delete h_ohcal_channel[ieta][iphi];
257  ihcal_output->cd();
258  h_ihcal_channel[ieta][iphi]->Write();
259  delete h_ihcal_channel[ieta][iphi];
260  ohcal_mpvinfo << ieta << "\t" << iphi << "\t" << peak_ohcal[ieta][iphi] << "\t" << chindf_ohcal[ieta][iphi] << std::endl;
261  ihcal_mpvinfo << ieta << "\t" << iphi << "\t" << peak_ihcal[ieta][iphi] << "\t" << chindf_ihcal[ieta][iphi] << std::endl;
262  }
263  }
264  ohcal_mpvinfo.close();
265  ihcal_mpvinfo.close();
266 
267  total_mpvinfo << std::endl << "oHCal bad fit channel:" << std::endl;
268  for (int n_bad = 0; n_bad < badfit_eta_ohcal.size(); ++n_bad) {
269  total_mpvinfo << badfit_eta_ohcal[n_bad] << "\t" << badfit_phi_ohcal[n_bad] << "\t" << chindf_ohcal[badfit_eta_ohcal[n_bad]][badfit_phi_ohcal[n_bad]];
270  }
271  total_mpvinfo << std::endl << "iHCal bad fit channel:" << std::endl;
272  for (int n_bad = 0; n_bad < badfit_eta_ihcal.size(); ++n_bad) {
273  total_mpvinfo << badfit_eta_ihcal[n_bad] << "\t" << badfit_phi_ihcal[n_bad] << "\t" << chindf_ihcal[badfit_eta_ihcal[n_bad]][badfit_phi_ihcal[n_bad]];
274  }
275  total_mpvinfo.close();
276 
277  ohcal_output->cd();
278  h_ohcal_total->Write();
279  h_ohcal_chindf->Write();
280  h_2Dohcal_hit->Write();
281  delete h_ohcal_total;
282  delete h_ohcal_chindf;
283  ohcal_output->Close();
284 
285  ihcal_output->cd();
286  h_ihcal_total->Write();
287  h_ihcal_chindf->Write();
288  h_2Dihcal_hit->Write();
289  delete h_ihcal_total;
290  delete h_ihcal_chindf;
291  ihcal_output->Close();
292 }