Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ana_starlight.C
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ana_starlight.C
1 #include <iostream>
2 #include <fstream>
3 #include <TLorentzVector.h>
4 #include <TF1.h>
5 #include <TRandom3.h>
6 
7 using namespace std;
8 
9 const double E_MASS = 0.000510998950; // electron mass [Gev]
10 
11 TRandom3 *rand3;
12 
13 // Return the relative resolution dp/p, for a particle with momentum p
14 // The momentum resolution was taken from sPHENIX simulation
15 double get_dpp( double p )
16 {
17  // Parametrization of the relative momentum resolution (dp/p)
18  static TF1 *f_dppfit = new TF1("f_dppfit","[0]*x + [1]/x + [2]",0.3,50.0);
19  f_dppfit->SetParameter(0,0.0010557);
20  f_dppfit->SetParameter(1,0.00262218);
21  f_dppfit->SetParameter(2,0.0090893);
22 
23  // Return dp/p for a particle of momentum p
24  double dpp = f_dppfit->Eval( p );
25  return dpp;
26 }
27 
28 // Return the smeared inv mass, for two truth particles v1 and v2
29 Double_t get_invmass_smeared(TLorentzVector v1, TLorentzVector v2)
30 {
31  // Get total momentum of particles 1 and 2
32  double p1 = v1.P();
33  double p2 = v2.P();
34 
35  // Get the sigma of the momentum resolution for particle 1 (dp1)
36  double sigma_p1 = get_dpp( p1 ) * p1;
37 
38  // Now get random value for momentum deviation (mis-measured momentum)
39  double dp1 = rand3->Gaus( 0, sigma_p1 );
40 
41  // now modify the true momentum to the mis-measured momentum
42  double dpp1 = 1.0 + dp1/p1;
43  double px1 = v1.Px()*dpp1;
44  double py1 = v1.Py()*dpp1;
45  double pz1 = v1.Pz()*dpp1;
46 
47  // Use mis-measured momentum to get mis-measured E, and generate lorentz 4-vector
48  double E1 = sqrt( E_MASS*E_MASS + px1*px1 + py1*py1 + pz1*pz1 );
49  v1.SetPxPyPzE( px1, py1, pz1, E1 );
50 
51  // Now get momentum smearing of 2nd particle, exactly in the same way as the 1st particle
52  double sigma_p2 = get_dpp( p2 ) * p2;
53  double dp2 = rand3->Gaus( 0, sigma_p2 );
54  double dpp2 = 1.0 + dp2/p2;
55 
56  double px2 = v2.Px()*dpp2;
57  double py2 = v2.Py()*dpp2;
58  double pz2 = v2.Pz()*dpp2;
59  double E2 = sqrt( E_MASS*E_MASS + px2*px2 + py2*py2 + pz2*pz2 );
60  v2.SetPxPyPzE( px2, py2, pz2, E2 );
61 
62  // Once we have both tracks with momentum resolution effects included, we sum them to get
63  // measured parent particle 4-vector and return the mass
64  TLorentzVector sum = v1 + v2;
65 
66  return sum.M();
67 }
68 
70 {
71  gStyle->SetOptStat(0);
72  rand3 = new TRandom3(0);
73 
74  const double integ_lumi = 4.5e9; // in inverse barns
75 
76  // Get cross-section of process
77  TString xsection_txt = gSystem->GetFromPipe("tail -1 output.txt | awk '{print $9}'");
78  TString xsection_units_txt = gSystem->GetFromPipe("tail -1 output.txt | awk '{print $10}'");
79  Double_t xsection = xsection_txt.Atof(); // xsection is in barns
80  if ( xsection_units_txt == "mb." )
81  {
82  xsection *= 1e-3;
83  }
84  else if ( xsection_units_txt == "microbarn." )
85  {
86  xsection *= 1e-6;
87  }
88  cout << "xsection (b) and integ lumi (1/b) = " << xsection << "\t" << integ_lumi << endl;
89 
90  // open ASCII file.
91  ifstream in;
92  //in.open(Form("output.txt"));
93  in.open("slight.out");
94 
95  // Check if file is open
96 
97  if (in.is_open())
98  {
99  cout << "File found\n";
100  //in.close();
101  }
102  else
103  {
104  cout << "Error opening file";
105  }
106 
107  // kinematics variables
108 
109  const Int_t kMaxTrack = 1000;
110  Int_t ntrack;
111 
112  Float_t px1; // momentum of first daughter in the x-direction
113  Float_t py1; // momentum of first daughter in the y-direction
114  Float_t pz1; // momentum of first daughter in the z-direction
115  Float_t E1; // energy of the first daughter
116  Float_t p1; // momentum of the first daughter
117  Float_t pt1; // momentum of the first daughter
118  Float_t me1; // mass of the first daughter
119  Float_t rap1; // rapidity of the first daughter
120  Float_t eta1; // pseudorapidity of the first daughter
121 
122  Float_t px2; // kinematic variables for the 2nd daughter...
123  Float_t py2;
124  Float_t pz2;
125  Float_t E2;
126  Float_t p2;
127  Float_t pt2;
128  Float_t me2;
129  Float_t rap2;
130  Float_t eta2;
131 
132  Float_t pxt; // x-direction momentum of the parent particle
133  Float_t pyt; // y-direction momentum of the parent particle
134  Float_t pzt; // z -direction momentum of the parent atom
135  Float_t ptt; // transverse momentum of the parent atom
136  Float_t ptott; // momentum of the parent atom
137  Float_t E; // total energy of the parent atom
138  Float_t rapt; // rapidity
139  Float_t etat; // pseudorapidity
140  Float_t InvMass; // invariant mass
141 
142  Float_t theta; // polar angle
143 
144  Int_t num_of_events;
145 
146  // Create tfile to save results
147  TFile *savefile = new TFile("upc_starlight.root","RECREATE");
148 
150  TTree * tree = new TTree("t", "Analyze.tree");
151  tree->Branch("px",&pxt,"px/F");
152  tree->Branch("py",&pyt,"py/F");
153  tree->Branch("pz",&pzt,"pz/F");
154  tree->Branch("p",&ptott,"p/F");
155  tree->Branch("pt",&ptt,"pt/F");
156  tree->Branch("y",&rapt,"y/F");
157  tree->Branch("eta",&etat,"eta/F");
158  tree->Branch("m", &InvMass, "m/F");
159  tree->Branch("p1", &p1, "p1/F");
160  tree->Branch("pt1", &pt1, "pt1/F");
161  tree->Branch("eta1", &eta1, "eta1/F");
162  tree->Branch("p2", &p2, "p2/F");
163  tree->Branch("pt2", &pt2, "pt2/F");
164  tree->Branch("eta2", &eta2, "eta2/F");
165 
166 
167  //tree->Print();
168 
169 
170  const double MAX_RAP = 4;
171  TH1F *h_rapt = new TH1F("h_rapt", "Rapidity J/#Psi#rightarrow e^{+}e^{-}", 200, -MAX_RAP, MAX_RAP);
172  TH1F *h_rapt_sphenix = new TH1F("h_rapt_sphenix", "Rapidity J/#Psi#rightarrow e^{+}e^{-} in sPHENIX Acceptance", 200, -MAX_RAP, MAX_RAP);
173  TH1F *h_rap1 = new TH1F("h_rap1", "Rapidity Track 1", 200, -MAX_RAP, MAX_RAP);
174  TH1F *h_rap2 = new TH1F("h_rap2", "Rapidity Track 2", 200, -MAX_RAP, MAX_RAP);
175 
176  const double MAX_INVMASS =6;
177  TH1F *h_InvMass = new TH1F("h_InvMass", "Invariant Mass", 200, 0, 6.0);
178  TH1F *h_InvMass_smeared = new TH1F("h_InvMass_smeared", "Invariant Mass", 200, 0, 6.0);
179  TH1F *h_InvMass_sphenix = new TH1F("h_InvMass_sphenix", "Invariant Mass of J/#Psi in sPHENIX Acceptance",200, 0, 6.0);
180  TH1F *h_InvMass_smeared_sphenix = new TH1F("h_InvMass_smeared_sphenix", "Invariant Mass of J/#Psi in sPHENIX Acceptance",200, 0, 6.0);
181 
182  TH1F *h_pt1 = new TH1F("h_pt1", "Transverse Momentum track 1", 200, 0, 2.);
183  TH1F *h_pt2 = new TH1F("h_pt2", "Transverse Momentum track 2", 200, 0, 2.);
184  TH1F *h_pt = new TH1F("h_pt","Transverse Momentum of J/Psi",200, 0, 2.0);
185  TH1F *h_pt_sphenix = new TH1F("h_pt_sphenix", "Transverse Momentum of UPC in sPHENIX Acceptance", 300, 0.0, 2.0);
186  TH1F *h_pz = new TH1F("h_pz", "Z-Axis Momentum of J/Psi", 100,-2,6);
187 
188  const double MAX_ETA = 6;
189  TH1F *h_eta1 = new TH1F("h_eta1", "PseudoRapidity Track 1", 200, -MAX_ETA, MAX_ETA);
190  TH1F *h_eta2 = new TH1F("h_eta2", "PseudoRapidity Track 2", 200, -MAX_ETA, MAX_ETA);
191 
192  // Read in one event from starlight output
193  string label;
194  int nev, ntr, stopv; //nev is the event number; ntr is the number of tracks within the vertex; stopv is the vertex number where the track ends
195  Float_t v0[4]; // 0-2 = x,y,z 3=t
196  int nv, nproc, nparent, ndaughter;//
197  cout << label << "\t" << ndaughter << endl;
198  const int MAXDAUGHTERS = 10; //changing this number does not change the energy or value outputted at the end of the function
199  int gpid[MAXDAUGHTERS], pdgpid[MAXDAUGHTERS]; //gpid is the monte carlo particle id code
200  Float_t mom[MAXDAUGHTERS][3];
201  int nevtrk, stopvtrk, junk[9];//number of event tracks, number of stopping tracks
202  /* for (int idtr=0; idtr<ndaughter; idtr++)
203  {
204  in >> label >> gpid[idtr] >> mom[idtr][0] >> mom[idtr][1] >> mom[idtr][2]
205  >> nevtrk >> ntr >> stopvtrk >> pdgpid[idtr];
206  }
207  */
208  TLorentzVector vp; //parent particle JPsi
209  TLorentzVector v1; //daughter particle 1 electron
210  TLorentzVector v2; //daughter particle 2 electron
211 
212  /* Double_t pxt= vp.pxt(); //truthfully idek if i need this double because I already floated pxt-E and when I run it with this commented out it works.
213  Double_t pyt= vp.pyt(); //but I'm not getting multiple graphs.
214  Double_t pzt= vp.pzt();
215  Double_t E= vp.E();
216 
217 
218  vp.SetPxPyPzE(vp->GetPx(),vp->GetPy(),vp->GetPz(),vp->GetE());
219  v1.SetPxPyPzE(v1->GetPx(),v1->GetPy(),v1->GetPz(),v1->GetE());
220  v2.SetPxPyPzE(v2->GetPx(),v2->GetPy(),v2->GetPz(),v2->GetE()); */
221 
222 
223  Double_t mass = vp.M();// mass of parent
224 
225  Double_t pt = vp.Pt();//parent pT
226 
227  unsigned int nevents = 0; // number of events in file
228 
229  while ( in.good() )
230  {
231 
232  // read the event line
233  in >> label >> nev >> ntr >> stopv;
234  if ( in.eof() ) break; // quit reading if we reached eend of file
235 
236  // read the vertex line
237  in >> label >> v0[0] >> v0[1] >> v0[2] >> v0[3] >> nv >> nproc >> nparent >> ndaughter;
238 
239  // read in daughters
240  in >> label >>gpid[0] >> mom[0][0] >> mom[0][1] >> mom[0][2]
241  >> nevtrk >> ntr >> stopvtrk >> pdgpid[0];
242 
243  in >> label >>gpid[1] >> mom[1][0] >> mom[1][1] >> mom[1][2]
244  >> nevtrk >> ntr >> stopvtrk >> pdgpid[1];
245 
246  // cout << "\n GPID=" << gpid[idtr] << "\n Momentum 0=" << mom[idtr][0] << "\n Momentum 1=" << mom[idtr][1] << "\n Momentum 2=" << mom[idtr][2]
247  // << "\n # of EventTracks=" << nevtrk << "\n # of Tracks w/in Vertex=" << ntr << "\n Vertex # where Track Stops=" << stopvtrk << endl;
248 
249  // Calculate pT
250  // set the values in each track
251 
252  // get momentum from 1st daughter particle
253  px1 = mom[0][0];
254  py1 = mom[0][1];
255  pz1 = mom[0][2];
256  pt1 = TMath::Sqrt( px1*px1 + py1*py1 );
257  p1 = TMath::Sqrt( px1*px1 + py1*py1 + pz1*pz1 );
258 
259  // get momentum from 2nd daughter particle
260  px2 = mom[1][0];
261  py2 = mom[1][1];
262  pz2 = mom[1][2];
263  pt2 = TMath::Sqrt( px2*px2 + py2*py2 );
264  p2 = TMath::Sqrt( px2*px2 + py2*py2 + pz2*pz2 );
265 
266  // total momentum of the daughters
267 
268  pxt = px1 + px2;//momentum of particle one and two in the x direction equals the total momentum in x direction
269  pyt = py1 + py2;
270  pzt = pz1 + pz2;
271  //cout << pzt << endl;
272 
273  //Calculate the tranverse momentum
274  ptt = TMath::Sqrt(pxt*pxt + pyt*pyt); //ptt is total transverse momentum
275  // cout << px1 << "\t" << px2 << endl;
276  Double_t p = TMath::Sqrt(pxt*pxt + pyt*pyt + pzt*pzt); //momentum in the x,y,z plane
277  // Fill histogram
278  h_pt->Fill(ptt);
279 
280  // calculate the invariant mass
281  // cout <<"\n"<<"InvMass = "<< InvMass << "\t" << endl;
282  me1 = me2 = E_MASS;
283 
284  E1 = TMath::Sqrt((me1 *me1) + (px1*px1) + (py1*py1) +(pz1*pz1));
285  E2 = TMath::Sqrt((me2 *me2) + (px2*px2) + (py2*py2) +(pz2*pz2));
286 
287  //cout <<"\n"<<"Energy = "<< E << "\t" << endl;
288 
289  E = E1 + E2;
290 
291  v1.SetPxPyPzE(px1, py1, pz1, E1);
292  v2.SetPxPyPzE(px2, py2, pz2, E2);
293 
294  //mass should always be about 3.1 GeV^2 no matter the frame
295  InvMass =TMath::Sqrt((E * E)- (pxt * pxt) -(pyt * pyt) -(pzt*pzt));
296  Double_t m = TMath::Sqrt(pxt*pxt + pyt*pyt + pzt*pzt);
297 
298  Double_t InvMass_smeared = get_invmass_smeared(v1,v2);
299 
300  //Fill Histogram
301  h_InvMass->Fill( InvMass );
302  h_InvMass_smeared->Fill( InvMass_smeared );
303  // cout <<"\n"<<"InvMass = "<< InvMass << "\t" << endl;
304 
305  //You have to calculate the rapitidy,eta, and transverse momentum for the daughter particles. Eta is pseudorapidity which tells you what "direction" or angle they div ert at, rapidity is the natural unit for speed of the particle in relative spaces, and the transverse momentum tells you.... idrk tbh.
306 
307  // calculate the rapidity
308  rapt = 0.5 * log((E + pzt)/(E - pzt)); //rapidity of parent
309 
310  // Rapidity of daughters
311 
312  rap1 = 0.5 * log((E1 + pz1)/(E1 - pz1));
313  rap2 = 0.5 * log((E2 + pz2)/(E2 - pz2));
314  h_rap1->Fill( rap1 );
315  h_rap2->Fill( rap2 );
316  h_rapt->Fill( rapt );
317 
318  // Pseudorapidity of daughters
319  double theta1 = atan2( pt1, pz1 );
320  eta1 = -log( tan( 0.5*theta1 ) );
321 
322  double theta2 = atan2( pt2, pz2 );
323  eta2 = -log( tan( 0.5*theta2 ) );
324 
325  h_eta1->Fill( eta1 );
326  h_eta2->Fill( eta2 );
327 
328  double thetat = atan2( ptt, pzt );
329  etat = -log( tan(0.5*thetat ) );
330 
331  // Check that both daughters are in sPHENIX acceptance
332  if ( fabs(eta1) < 1.1 && fabs(eta2) < 1.1 && pt1>0.3 && pt2>0.3 )
333  {
334  h_rapt_sphenix->Fill( rapt );
335  h_InvMass_sphenix->Fill(InvMass);
336  h_InvMass_smeared_sphenix->Fill(InvMass_smeared);
337  h_pt_sphenix->Fill( ptt );
338  }
339 
340  nevents++;
341 
342  tree->Fill();
343  }
344 
345  cout << "Processed " << nevents << endl;
346 
347  // Scaling factor for integrated luminosity expected in sPHENIX Run
348  Double_t scale = xsection*integ_lumi/nevents;
349  cout << "Scale factor is " << endl;
350  h_rapt->Sumw2();
351  h_rapt_sphenix->Sumw2();
352  h_pt->Sumw2();
353  h_pt_sphenix->Sumw2();
354  h_InvMass->Sumw2();
355  h_InvMass_sphenix->Sumw2();
356  h_InvMass_smeared->Sumw2();
357  h_InvMass_smeared_sphenix->Sumw2();
358  h_rapt->Scale( scale );
359  h_rapt_sphenix->Scale( scale );
360  h_pt->Scale( scale );
361  h_pt_sphenix->Scale( scale );
362  h_InvMass->Scale( scale );
363  h_InvMass_sphenix->Scale( scale );
364  h_InvMass_smeared->Scale( scale );
365  h_InvMass_smeared_sphenix->Scale( scale );
366 
367  cout << "Scale factor = " << scale << endl;
368  cout << "Total events = " << h_rapt->Integral() << endl;
369  cout << "Total events in sPHENIX acceptance = " << h_rapt_sphenix->Integral() << endl;
370  cout << "Acceptance Factor = " << h_rapt_sphenix->Integral()/h_rapt->Integral() << endl;
371 
372 
373  TCanvas *a = new TCanvas("a","Total Parent Momentum of JPsi",550,425);
374  h_pt->SetLineColor(kBlue);
375  h_pt->SetXTitle("p_{T} (GeV/c)");
376  h_pt->SetYTitle("Counts");
377  h_pt->Draw();
378  a->SaveAs("PTofParent.png");
379 
380  TCanvas *b = new TCanvas("b","Invariant Mass of JPsi",550,425);
381  h_InvMass_smeared->SetLineColor(kBlack);
382  h_InvMass_smeared->SetXTitle("mass (GeV/c^{2})");
383  h_InvMass_smeared->SetYTitle("Counts");
384  h_InvMass_smeared->Draw("ehist");
385  h_InvMass_smeared_sphenix->SetLineColor(kBlue);
386  h_InvMass_smeared_sphenix->SetMarkerColor(kBlue);
387  h_InvMass_smeared_sphenix->SetXTitle("Mass (GeV/c^{2})");
388  h_InvMass_smeared_sphenix->Draw("ehistsame");
389  b->SaveAs("MassofUPCJPsi.png");
390 
391  TCanvas *c = new TCanvas("c","Rapidity of E1 and E2",550,425);
392  h_rap1->SetLineColor(kGreen);
393  h_rap1->SetTitle("Rapidity e^{+},e^{-}");
394  h_rap1->SetXTitle("Rapidity y");
395  h_rap1->SetYTitle("Counts");
396  h_rap1->Draw();
397  h_rap2->SetLineColor(kRed);
398  h_rap2->SetXTitle("Rapidity y");
399  h_rap2->SetYTitle("Counts");
400  h_rap2->Draw("same");
401  c->SaveAs("RapofE1E2.png");
402 
403  TCanvas *d = new TCanvas("d","Rapidity of UPC J/Psi",550,425);
404  h_rapt->SetLineColor(kBlack);
405  h_rapt->SetXTitle("Rapidity y");
406  h_rapt->SetYTitle("Counts");
407  h_rapt->Draw("ehist");
408  h_rapt_sphenix->SetLineColor(kBlue);
409  h_rapt_sphenix->SetMarkerColor(kBlue);
410  h_rapt_sphenix->SetXTitle("Rapidity y");
411  h_rapt_sphenix->Draw("ehistsame");
412  d->SaveAs("RapofUPCJPsi.png");
413 
414  TCanvas *e = new TCanvas("e","PZ",550,425);
415  h_pz->SetLineColor(kBlue);
416  h_pz->SetXTitle("p_{Z} GeV/c");
417  h_pz->SetYTitle("Counts");
418  h_pz->Draw();
419  gPad->SetLogy(1);
420  e->SaveAs("pz.png");
421 
422  // Save histograms and TTree to file
423  savefile->Write();
424 
425 } //closing function