Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
fjetResol.C
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file fjetResol.C
1 /*
2  Auther: Chong Kim (ckim.phenix@gmail.com)
3 
4  - Target: study resolution of 1st/2nd leading jets reconstructed in fsPHENIX calorimeter
5  - Environments:
6  a. Requires root file contains reconstructed forward jets, which is results of
7  /macros/macros/g4simulations/Fun4All_G4_fsPHENIX.C
8  * modified Fun4All_G4_fsPHENIX.C used for this code can be found at:
9  /gpfs/mnt/gpfs04/sphenix/user/ckim/fjets/Fun4All_G4_fsPHENIX.C
10  b. Uses root branch "ntp_truthjet"
11 
12  - How code works:
13  a. List up 1st/2nd leading jets using true pT (gpt) which satisfying min pT cut (cutPT)
14  (function searchLeadingJets)
15  b. Study target variable (ex. energy) using collected 1st/2nd leading jets in each event
16  For now only energy is checked but any variable in "ntp_truthjet" can be studied
17  c. Loop through multiple events and root files
18 
19  - Parameters (ex. Pythia version, beam energy, Anti_kT radius, etc) can be arranged via arrays in top
20  - Tested by using output files in "/gpfs/mnt/gpfs04/sphenix/user/ckim/fjets/Ana/results_1121" at Mar.2, 2017
21 */
22 
23 #include <TCanvas.h>
24 #include <TFile.h>
25 #include <TF1.h>
26 #include <TGraph.h>
27 #include <TGraphErrors.h>
28 #include <TH1.h>
29 #include <TH2.h>
30 #include <TLatex.h>
31 #include <TLegend.h>
32 #include <TNtuple.h>
33 #include <TString.h>
34 #include <TStyle.h>
35 #include <iostream>
36 using namespace std;
37 
38 std::vector<int> searchLeadingJets(TNtuple *T, float cutPT, const char *targetV = "gpt");
39 
40 //=========================================================
41 void fjetResol(
42  const char* path = "/gpfs/mnt/gpfs04/sphenix/user/ckim/fjets/Ana/results_1121",
43  const char* var = "e",
44  const char* suffix = "",
45  bool print = true
46  )
47 {
48 
49  //Parameters
50  const int setPy[] = {8/*, 6*/}; //Pythia8 or 6
51  const int setBeamE[] = {200/*, 510*/};
52  const int setR[] = {4, 6}; //Anti-kT radius
53  const int setMinPT[] = {/*3, 4,*/ 5, 10, 15}; //Minimum parton pT in pythia cfg
54  const float setEta[] = {1.2, 1.6, 2.0, 2.4, 2.8, 3.2, 3.6};
55  const float setE[] = {20,25,30,35,40,45,50, 60,70,80,90,100,110,120,130,140,150,160, 180,200}; //True jet E
56 
57  const int nsetPy = sizeof(setPy) /sizeof(setPy[0]);
58  const int nsetBeamE = sizeof(setBeamE)/sizeof(setBeamE[0]);
59  const int nsetR = sizeof(setR) /sizeof(setR[0]);
60  const int nsetMinPT = sizeof(setMinPT)/sizeof(setMinPT[0]);
61  const int nsetEta = sizeof(setEta) /sizeof(setEta[0]) - 1;
62  const int nsetE = sizeof(setE) /sizeof(setE[0]) - 1;
63 
64  //----------------------------------------------
65 
66  //Histograms to be filled
67  TH2F *h2[nsetPy][nsetBeamE][nsetR][nsetEta];
68  TH1F *h1[nsetPy][nsetBeamE][nsetR][nsetEta][nsetE];
69  for (int a=0; a<nsetPy; a++)
70  for (int b=0; b<nsetBeamE; b++)
71  for (int c=0; c<nsetR; c++)
72  for (int x=0; x<nsetEta; x++)
73  {
74  const char* h2Name = Form("sanity_py%i_%i_r0%i_eta%i", setPy[a],setBeamE[b],setR[c],x);
75  h2[a][b][c][x] = new TH2F(h2Name, "", 100,0,b==0?100:200, 60,0,2);
76  for (int y=0; y<nsetE; y++)
77  {
78  const char* h1Name = Form("h1_%s_py%i_%i_r0%i_eta%i_e%i", var,setPy[a],setBeamE[b],setR[c],x,y);
79  h1[a][b][c][x][y] = new TH1F(h1Name, "", 150,-1.5,1.5);
80  }
81  }
82 
83  //----------------------------------------------
84 
85  //Iterate through each file and tree
86  for (int a=0; a<nsetPy; a++)
87  for (int b=0; b<nsetBeamE; b++)
88  for (int c=0; c<nsetR; c++)
89  for (int d=0; d<nsetMinPT; d++)
90  {
91  //Link input
92  const char *finName = Form("%s/pythia%i_%i_r0%i_pT%i.root", path,setPy[a],setBeamE[b],setR[c],setMinPT[d]);
93  TFile *F = TFile::Open(finName);
94  TNtuple *T = (TNtuple*)F->Get("ntp_truthjet");
95  cout <<Form("Open %s from %s...", T->GetName(), F->GetName()) <<endl;
96 
97  //Search 1st/2nd leading jets in this file
98  std::vector<int> jetList = searchLeadingJets(T, (float)setMinPT[d]);
99  //for (unsigned int i=0; i<jetList.size(); i++) cout <<i <<" " <<jetList[i] <<endl;
100 
101  //Link branches
102  float event, geta, gphi, ge, eta, phi, e;
103  T->SetBranchAddress("event", &event);
104  T->SetBranchAddress("geta", &geta);
105  T->SetBranchAddress("gphi", &gphi);
106  T->SetBranchAddress("ge", &ge);
107  T->SetBranchAddress("eta", &eta);
108  T->SetBranchAddress("phi", &phi);
109  T->SetBranchAddress("e", &e);
110 
111  //Iterate through for leading jets found
112  for (unsigned int i=0; i<jetList.size(); i++)
113  {
114  T->GetEntry(jetList[i]);
115 
116  int id_eta = -1;
117  for (int x=0; x<nsetEta; x++) { if (geta > setEta[x] && geta < setEta[x+1]) id_eta = x; }
118  if (id_eta == -1) continue;
119 
120  h2[a][b][c][id_eta]->Fill(ge, e/ge); //Sanity plots
121 
122  int id_e = -1;
123  for (int y=0; y<nsetE; y++) { if (ge > setE[y] && ge < setE[y+1]) id_e = y; }
124  if (id_e == -1) continue;
125 
126  if (!strcmp(var, "e")) h1[a][b][c][id_eta][id_e]->Fill(e/ge);
127  }//i, leading jets
128 
129  //Cleanup
130  T->ResetBranchAddresses();
131  T->Delete();
132  F->Delete();
133  }//d, c, b, a
134 
135  //----------------------------------------------
136 
137  gStyle->SetOptStat("e");
138 
139  //Sanity check plots
140  TCanvas *c1[nsetPy][nsetBeamE][nsetR];
141  for (int a=0; a<nsetPy; a++)
142  for (int b=0; b<nsetBeamE; b++)
143  for (int c=0; c<nsetR; c++)
144  {
145  const char* c1Name = Form("sanity_py%i_%i_r0%i", setPy[a],setBeamE[b],setR[c]);
146  c1[a][b][c] = new TCanvas(c1Name, c1Name, 1280, 800);
147  c1[a][b][c]->Divide(nsetEta/2, 2, 0.015, 0.015, 10);
148  for (int x=0; x<nsetEta; x++)
149  {
150  c1[a][b][c]->cd(x+1)->SetGrid();
151  h2[a][b][c][x]->SetTitle(Form("%2.1f < #eta < %2.1f;True e;Reco e/True e", setEta[x], setEta[x+1]));
152  h2[a][b][c][x]->GetYaxis()->SetTitleOffset(1.45);
153  h2[a][b][c][x]->Draw("colz");
154  }
155  if (print) c1[a][b][c]->Print(Form("%s%s.png", c1[a][b][c]->GetName(),suffix));
156  }//c, b, a
157 
158  //Get resolutions
159  TCanvas *c2 = new TCanvas(Form("resol_%s", var), var, 1280, 800);
160  c2->Divide(nsetEta/2, 2, 0.015, 0.015, 10);
161  TF1 *f1Gaus = new TF1("f1Gaus", "[0]*TMath::Gaus(x, [1], [2])", -0.2, 0.2);
162  TLegend *leg1 = new TLegend(0.4, 0.6/*0.9 - 0.15*nsetPy*/, 0.9, 0.9);
163  for (int a=0; a<nsetPy; a++)
164  for (int b=0; b<nsetBeamE; b++)
165  for (int c=0; c<nsetR; c++)
166  for (int x=0; x<nsetEta; x++)
167  {
168  TGraphErrors *g1 = new TGraphErrors();
169  g1->SetName(Form("g1_%s_py%i_%i_r0%i_eta%i_e%i", var,setPy[a],setBeamE[b],setR[c],x));
170  g1->SetLineColor(2 * (b+1));
171  g1->SetMarkerColor(2 * (b+1));
172  g1->SetMarkerSize(1.);
173  g1->SetMarkerStyle(20 + 4*c);
174 
175  for (int y=0; y<nsetE; y++)
176  {
177  if (h1[a][b][c][x][y]->GetEntries() < 50)
178  {
179  h1[a][b][c][x][y]->Delete();
180  continue;
181  }
182  f1Gaus->SetParameters(
183  h1[a][b][c][x][y]->GetMaximum(),
184  h1[a][b][c][x][y]->GetMean(),
185  h1[a][b][c][x][y]->GetRMS()
186  );
187  h1[a][b][c][x][y]->Fit(
188  f1Gaus->GetName(), "QR0", "",
189  h1[a][b][c][x][y]->GetMean() - h1[a][b][c][x][y]->GetRMS() * 3,
190  h1[a][b][c][x][y]->GetMean() + h1[a][b][c][x][y]->GetRMS() * 3
191  );
192  g1->SetPoint(g1->GetN(), (setE[y]+setE[y+1])/2, f1Gaus->GetParameter(2));
193  g1->SetPointError(g1->GetN()-1, 0, f1Gaus->GetParError(2));
194  }//y (energy)
195 
196  c2->cd(x+1)->SetGrid();
197  if (a==0 && b==0 && c==0)
198  {
199  const char *yTitle = "#sigma (Reco e / True e)";
200  const char *gTitle = Form("%2.1f < #eta < %2.1f;True e;%s", setEta[x],setEta[x+1], yTitle);
201  gPad->DrawFrame(20-5, 0.05, 200+5, 0.3, gTitle);
202  gPad->Modified();
203  }
204  if (a==0 && x==0)
205  {
206  leg1->AddEntry(g1, Form("PYTHIA%i, #sqrt{s} = %i, R = 0.%i", setPy[a], setBeamE[b], setR[c]), "p");
207  }
208  g1->Draw("pe same");
209  if (a==(nsetPy-1) && b==(nsetBeamE-1) && c==(nsetR-1) && x==0) leg1->Draw("same");
210  }//x (eta), c, b, a
211  if (print) c2->Print(Form("%s%s.png", c2->GetName(),suffix));
212 
213  return;
214 }//Main
215 
216 //==============================================================================
217 std::vector<int> searchLeadingJets(TNtuple *T, float cutPT, const char *targetV)
218 {
219  std::vector<int> jetList; //Return (event # of target jets)
220 
221  float event, gpt, var;
222  T->SetBranchAddress("event", &event);
223  if (strcmp("gpt", targetV))
224  {
225  T->SetBranchAddress("gpt", &gpt);
226  cout <<"Search leading jets by using " <<targetV <<endl;
227  }
228  T->SetBranchAddress(targetV, &var); //gpt or ge (truth info)
229 
230  //Note: high1_v should always higher than high2_v
231  int evtCheck = -1;
232  int high1_n = -1; //1st leading jet's entry # in the tree
233  int high2_n = -1;
234  float high1_v = -1; //1st leading jet's value
235  float high2_v = -2;
236 
237  const int allEntries = T->GetEntries();
238  for (int a=0; a<allEntries; a++)
239  {
240  /*
241  Iterate through all entries with same event number,
242  find 1st and 2nd leading jets of the event,
243  then save them when next event (different event #) found
244  */
245 
246  T->GetEntry(a);
247 
248  //pT cut
249  float tempPT = (strcmp("gpt", targetV))?gpt:var;
250  if (tempPT < cutPT) continue;
251 
252  if (evtCheck != event || a == allEntries) //Save jet entries
253  {
254  if (high1_n != -1 && high2_n != -1)
255  {
256  if (high1_n < high2_n)
257  {
258  jetList.push_back(high1_n);
259  jetList.push_back(high2_n);
260  }
261  else
262  {
263  jetList.push_back(high2_n);
264  jetList.push_back(high1_n);
265  }
266  }
267 
268  //Update dummy indices for next iteration
269  evtCheck = event;
270  high1_n = a;
271  high2_n = -1;
272  high1_v = var;
273  high2_v = -1;
274  }
275  else //Iterate & Update
276  {
277  if (var > high1_v)
278  {
279  high2_n = high1_n;
280  high2_v = high1_v;
281  high1_n = a;
282  high1_v = var;
283  }
284  else if (var > high2_v)
285  {
286  high2_n = a;
287  high2_v = var;
288  }
289  }
290  }//a, nEvents
291 
292  T->ResetBranchAddresses();
293  return jetList;
294 }//searchLeadingJets