StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
mip_histogram_fitter.C
1 /*
2  * mip_histogram_fitter.C
3  * Original Author: Matt Walker
4  * Update Author: J. Kevin Adkins, University of Kentucky
5  * Updates: Remove old and obsolete functions and code,
6  * make code more modular so it's easier to make changes
7  * to fits independent of drawing tower fits, etc.
8  * Fitting algorithm completely overhauled to now calculate
9  * the mean of the fit over the range [0,100]. This is the value
10  * we calculate the MIP relative gains with. Also, now using fit
11  * to calculate RMS, and subsequently the error on the mean
12  * Most recent update: Feb. 25, 2015
13  */
14 
15 #include <iostream>
16 #include <fstream>
17 using namespace std;
18 
19 #include "TFile.h"
20 #include "TMath.h"
21 #include "TH1.h"
22 #include "TF1.h"
23 #include "TPostScript.h"
24 #include "TCanvas.h"
25 #include "TStyle.h"
26 #include "TLatex.h"
27 #include "TString.h"
28 #include "TLine.h"
29 
30 void drawTower(TH1D*, Int_t, Int_t, Float_t, Float_t);
31 Bool_t isBadTower(Int_t);
32 
33 void mip_histogram_fitter(const Char_t* mipRootfile = "combinedMips.root", const Char_t* psName = "mip.ps", const Char_t* rootFilename = "towerMipFits.root", const Char_t* mipOutputName = "mip.gains")
34 {
35  // Load StEmcGeom for tower eta & phi
36  gROOT->Macro("loadMuDst.C");
37  StEmcGeom *mEmcGeom = StEmcGeom::instance("bemc");
38 
39  const Int_t nTowers = 4800;
40  Int_t towerStatus[nTowers];
41  Double_t fitMean[nTowers], fitMeanError[nTowers];
42 
43  cout << "Input Filename: " << mipRootfile << endl;
44  cout << "Plot Filename: " << psName << endl;
45  cout << "Gain Filename: " << mipOutputName << endl;
46 
47  gStyle->SetCanvasColor(10);
48  gStyle->SetCanvasBorderMode(0);
49  gStyle->SetStatColor(10);
50  gStyle->SetOptTitle(0);
51  gStyle->SetOptDate(0);
52  gStyle->SetOptFit(111);
53  gStyle->SetOptStat("e");
54  gStyle->SetPalette(1);
55 
56  /* Declare pointers for histograms before output file. Instantiate after,
57  this allows us to use outfile->Write() to write everything at once */
58  TH1D *towerHisto[nTowers];
59  TH2F *etaPhiMean, *etaPhiStatus, *etaPhiRatio;
60 
61  TFile* outfile = new TFile(rootFilename,"RECREATE");
62  Float_t pi = TMath::Pi();
63 
64  // Instantiate histograms
65  etaPhiMean = new TH2F("etaPhiMean","Fit Means", 40, -1., 1., 120, -pi, pi);
66  etaPhiStatus = new TH2F("etaPhiStatus","Status Codes", 40, -1., 1., 120, -pi, pi);
67  etaPhiRatio = new TH2F("etaPhiMeanRatio","Mean Ratios", 40, -1., 1., 120, -pi, pi);
68  for (Int_t i = 0; i < nTowers; ++i)
69  towerHisto[i] = new TH1D(Form("towerHisto_%i",i),Form("Tower %i",i),250,-50.5,199.5);
70 
71  TFile *rootfile = new TFile(mipRootfile);
72  for(Int_t y = 0; y < nTowers; ++y)
73  towerHisto[y]->Add((TH1D*)rootfile->Get(Form("tower_histo_%i",y+1)));
74 
75  rootfile->Close();
76  if(rootfile) delete rootfile;
77 
78  /****************** Begin MIP Fitting for each Tower ******************/
79  TF1 *towerFit[nTowers];
80  Char_t fitName[100];
81 
82  for(Int_t iTow = 0; iTow < nTowers; ++iTow){
83  Int_t softId = iTow+1;
84  Float_t mTowerEta = 0., mTowerPhi = 0.;
85  mEmcGeom->getEta(softId,mTowerEta);
86  mEmcGeom->getPhi(softId,mTowerPhi);
87 
88  towerStatus[iTow] = 0;
89  fitMean[iTow] = 0.;
90  fitMeanError[iTow] = 0.;
91  towerHisto[iTow]->GetXaxis()->SetRangeUser(6.,100.);
92 
93  if(softId%200 == 0) cout << "Now fitting softId: " << softId << endl;
94 
95  sprintf(fitName,"towerFit_%i",softId);
96  Double_t fitLow = towerHisto[iTow]->GetMean() - towerHisto[iTow]->GetRMS();
97  Double_t fitHigh = towerHisto[iTow]->GetMean() + towerHisto[iTow]->GetRMS()/2.;
98  towerFit[iTow] = new TF1(fitName,"[0]*Gaus(x,[1],[2])*Landau(x,[3],[4])",fitLow,fitHigh);
99 
100  // Fit Parameters
101  towerFit[iTow]->SetParameter(0,towerHisto[iTow]->GetBinContent(towerHisto[iTow]->GetMaximumBin()));
102  towerFit[iTow]->SetParameter(1,towerHisto[iTow]->GetMean());
103  towerFit[iTow]->SetParameter(2,towerHisto[iTow]->GetRMS());
104  towerFit[iTow]->SetParameter(3,towerHisto[iTow]->GetBinCenter(towerHisto[iTow]->GetMaximumBin()));
105  towerFit[iTow]->SetParameter(4,towerHisto[iTow]->GetRMS());
106  towerFit[iTow]->SetLineColor(kBlue);
107  towerFit[iTow]->SetLineWidth(1.5);
108 
109  // If entries less than 25 we can't fit the tower, so we skip it
110  if(towerHisto[iTow]->Integral(56,156) < 25){
111  towerStatus[iTow] = 13;
112  etaPhiStatus->Fill(mTowerEta,mTowerPhi,towerStatus[iTow]);
113  continue;
114  }
115 
116  towerHisto[iTow]->Fit(towerFit[iTow],"RQ");
117  towerStatus[iTow]+=1;
118  fitMean[iTow] = towerFit[iTow]->Mean(0.,100.);
119 
120  // Get the fit parameters in an array
121  Double_t fitParams[5] = {0.,0.,0.,0.,0.};
122  fitParams[0] = towerFit[iTow]->GetParameter(0);
123  fitParams[1] = towerFit[iTow]->GetParameter(1);
124  fitParams[2] = towerFit[iTow]->GetParameter(2);
125  fitParams[3] = towerFit[iTow]->GetParameter(3);
126  fitParams[4] = towerFit[iTow]->GetParameter(4);
127 
128  //Calculate the variance of the fit
129  Double_t fitVariance = towerFit[iTow]->Variance(0., 100., fitParams);
130  Double_t fitSigma = sqrt(fitVariance);
131  Double_t entriesInFit = towerHisto[iTow]->Integral(51,151); // Bin 51 centered over zero
132 
133  //Set the status codes of the towers
134  if(fitMean[iTow] < 6) towerStatus[iTow] += 10; //Bad mean
135  if((softId)%20==0){
136  if (abs(fitMean[iTow]-towerHisto[iTow]->GetMean()) > 15)
137  towerStatus[iTow]+=8;
138  }
139  else{
140  if(abs(fitMean[iTow]-towerHisto[iTow]->GetMean()) > 10)
141  towerStatus[iTow]+=8;
142  }
143 
144  //Check for hard coded bad towers
145  if(isBadTower(softId))
146  towerStatus[iTow] = 7;
147 
148  //Calculate error on mean for good statuses
149  if (towerStatus[iTow] == 1)
150  fitMeanError[iTow] = fitSigma/sqrt(entriesInFit);
151 
152  // Fill eta/phi for good statuses
153  if (towerStatus[iTow] == 1){
154  etaPhiMean->Fill(mTowerEta,mTowerPhi,fitMean[iTow]);
155  etaPhiRatio->Fill(mTowerEta,mTowerPhi,fitMean[iTow]/towerHisto[iTow]->GetMean());
156  }
157  etaPhiStatus->Fill(mTowerEta,mTowerPhi,towerStatus[iTow]);
158  }// Towers loop
159  /******************** End MIP Fitting for each Tower ********************/
160 
161  /******************* Begin Drawing the Fitted Spectra *******************/
162  TPostScript *ps = new TPostScript(psName);
163  TCanvas *canvas = new TCanvas("can","can1",100,100,600.,800.);
164  Int_t pad;
165 
166  cout << endl << "Begin Tower Drawing Loop" << endl;
167  for (Int_t iTow = 0; iTow < nTowers; ++iTow){
168  Int_t softId = iTow + 1;
169  Float_t mTowerEta = 0., mTowerPhi = 0.;
170  mEmcGeom->getEta(softId,mTowerEta);
171  mEmcGeom->getPhi(softId,mTowerPhi);
172 
173  if (softId%400 == 0) cout << "Drawing tower " << softId << endl;
174  if(iTow%20 == 0){
175  canvas->Update();
176  ps->NewPage();
177  canvas->Clear();
178  canvas->Divide(4,5);
179  pad = 1;
180  }
181 
182  canvas->cd(pad);
183  if(towerStatus[iTow] > 1)
184  towerHisto[iTow]->SetLineColor(kRed);
185 
186  // Draw the tower onto the pad
187  drawTower(towerHisto[iTow],softId,towerStatus[iTow],mTowerEta,mTowerPhi);
188 
189  Double_t lineMax = towerHisto[iTow]->GetBinContent(towerHisto[iTow]->GetMaximumBin()) + 30;
190  if(towerStatus[iTow] == 1){
191  TLine *avgValueLine = new TLine(fitMean[iTow],0.,fitMean[iTow],lineMax);
192  avgValueLine->SetLineColor(kBlue);
193  avgValueLine->SetLineWidth(1.25);
194  avgValueLine->Draw("same");
195  }
196  pad++;
197  }//End tower draw loop
198 
199  canvas->Update();
200  ps->NewPage();
201  canvas->Clear();
202  canvas->Divide(1,2);
203  canvas->cd(1);
204  etaPhiMean->GetXaxis()->SetTitle("#eta");
205  etaPhiMean->GetXaxis()->CenterTitle();
206  etaPhiMean->GetYaxis()->SetTitle("#phi");
207  etaPhiMean->GetYaxis()->CenterTitle();
208  etaPhiMean->Draw("colz");
209  canvas->cd(2);
210  etaPhiStatus->GetZaxis()->SetRangeUser(0,20);
211  etaPhiStatus->GetXaxis()->SetTitle("#eta");
212  etaPhiStatus->GetXaxis()->CenterTitle();
213  etaPhiStatus->GetYaxis()->SetTitle("#phi");
214  etaPhiStatus->GetYaxis()->CenterTitle();
215  etaPhiStatus->Draw("colz");
216 
217  canvas->Update();
218  ps->NewPage();
219  canvas->Clear();
220  canvas->Divide(1,2);
221  canvas->cd(1);
222  etaPhiRatio->GetXaxis()->SetTitle("#eta");
223  etaPhiRatio->GetXaxis()->CenterTitle();
224  etaPhiRatio->GetYaxis()->SetTitle("#phi");
225  etaPhiRatio->GetYaxis()->CenterTitle();
226  etaPhiRatio->Draw("colz");
227  canvas->cd(2);
228  TH2F *ratioClone = (TH2F*)etaPhiRatio->Clone();
229  ratioClone->GetZaxis()->SetRangeUser(0.7,1.);
230  ratioClone->GetXaxis()->SetTitle("#eta");
231  ratioClone->GetXaxis()->CenterTitle();
232  ratioClone->GetYaxis()->SetTitle("#phi");
233  ratioClone->GetYaxis()->CenterTitle();
234  ratioClone->Draw("colz");
235  ps->Close();
236 
237 
238  cout << "Tower Drawing Loop Complete" << endl;
239  /******************** End Drawing the Fitted Spectra ********************/
240 
241  /******************** Begin Output of MIP Fit Data ********************/
242  ofstream mipOutput(mipOutputName);
243 
244  Int_t nGood = 0;
245  Int_t nZero = 0;
246 
247  for(Int_t iTow = 0; iTow < nTowers; ++iTow){
248  Int_t softId = iTow + +1;
249  Double_t mipAdc = fitMean[iTow];
250  Double_t mipError = fitMeanError[iTow];
251  mipOutput << softId << " " << mipAdc << " " << mipError << " " << towerStatus[iTow] << endl;
252 
253  if(towerStatus[iTow]==1)nGood++;
254  if(towerStatus[iTow]==0)nZero++;
255  }
256  mipOutput.close();
257  /********************* End Output of MIP Fit Data *********************/
258 
259  outfile->Write();
260  outfile->Close();
261 
262  cout << "Finished tower fits" << endl << endl;
263  cout << "Number of Good Statuses = " << nGood << endl;
264  cout << "Number of Bad Statuses = " << 4800-nGood << endl;
265  cout << "Number of Empty Towers = " << nZero << endl;
266 
267  // Delete geometry pointer
268  if (mEmcGeom) delete mEmcGeom;
269 } // End of main routine
270 
271 void drawTower(TH1D* histo, Int_t id, Int_t status, Float_t towerEta, Float_t towerPhi)
272 {
273  // Set histogram options
274  histo->GetXaxis()->SetTitle("ADC");
275  histo->GetXaxis()->CenterTitle();
276  histo->Draw(); // Used Sumw2() in histogram maker to calculate errors
277 
278  // Write softId and status code on plot
279  Char_t towerTitle[100];
280  Char_t etaTitle[100];
281  Char_t phiTitle[100];
282  sprintf(etaTitle,"e:%1.2f",towerEta);
283  sprintf(phiTitle,"p:%1.2f",towerPhi);
284  TLatex etaLatex;
285  TLatex phiLatex;
286  etaLatex.SetTextSize(0.1);
287  phiLatex.SetTextSize(0.1);
288  sprintf(towerTitle,"%i",id);
289  TLatex titleLatex;
290  titleLatex.SetTextSize(0.15);
291  if(status!=1) titleLatex.SetTextColor(kRed);
292  phiLatex.DrawTextNDC(0.55,0.2,phiTitle);
293  etaLatex.DrawTextNDC(0.55,0.33,etaTitle);
294  titleLatex.DrawTextNDC(0.55,0.45,towerTitle);
295  if(status!=1){
296  Char_t towerCode[100];
297  sprintf(towerCode,"%i",status);
298  TLatex statusLatex;
299  statusLatex.SetTextSize(0.15);
300  statusLatex.SetTextColor(kRed);
301  statusLatex.DrawTextNDC(0.47,0.78,towerCode);
302  }
303 }
304 
305 Bool_t isBadTower(Int_t id)
306 {
307  // First pass
308  if (id == 34 || id == 106 || id == 266 || id == 267 || id == 282 || id == 286 || id == 287 || id == 410 || id == 504 || id == 533 ||
309  id == 561 || id == 615 || id == 616 || id == 633 || id == 637 || id == 638 || id == 650 || id == 653 || id == 657 || id == 673 ||
310  id == 789 || id == 806 || id == 809 || id == 812 || id == 813 || id == 814 || id == 821 || id == 822 || id == 823 || id == 824 ||
311  id == 829 || id == 830 || id == 831 || id == 832 || id == 837 || id == 841 || id == 842 || id == 843 || id == 844 || id == 849 ||
312  id == 850 || id == 851 || id == 852 || id == 857 || id == 875 || id == 899 || id == 939 || id == 953 || id == 954 || id == 993 ||
313  id == 1026 || id == 1046 || id == 1048 || id == 1080 || id == 1100 || id == 1199 || id == 1200 || id == 1207 || id == 1218 || id == 1219 ||
314  id == 1222 || id == 1223 || id == 1224 || id == 1198 || id == 1237 || id == 1241 || id == 1242 || id == 1243 || id == 1244 || id == 1257 ||
315  id == 1260 || id == 1312 || id == 1348 || id == 1353 || id == 1354 || id == 1388 || id == 1407 || id == 1409 || id == 1434 || id == 1448 ||
316  id == 1574 || id == 1597 || id == 1612 || id == 1654 || id == 1713 || id == 1765 || id == 1766 || id == 1877 || id == 1878 || id == 2073 ||
317  id == 2077 || id == 2092 || id == 2093 || id == 2097 || id == 2409 || id == 2589 || id == 2590 || id == 2969 || id == 3070 || id == 3071 ||
318  id == 3494 || id == 3495 || id == 3588 || id == 3668 || id == 3678 || id == 3679 || id == 4018 || id == 4019 || id == 4059 || id == 4331 ||
319  id == 4357 || id == 4500 || id == 4677 || id == 4678 || id == 4684)
320  return true;
321 
322  return false;
323 }