Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Leptoquarks.C
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Leptoquarks.C
1 #include "Leptoquarks.h"
2 #include "TruthTrackerHepMC.h"
3 
4 #include <phool/getClass.h>
7 
9 
10 #include <TLorentzVector.h>
11 #include <TNtuple.h>
12 #include <TFile.h>
13 #include <TString.h>
14 #include <TH2D.h>
15 #include <TDatabasePDG.h>
16 
19 #include <HepMC/GenEvent.h>
20 #include <HepMC/GenVertex.h>
21 
22 using namespace std;
23 
25  SubsysReco("Leptoquarks" ),
26  _foutname(filename),
27  _fout_root(NULL),
28  _tree_event(NULL),
29  _ebeam_E(10),
30  _pbeam_E(250),
31  _embedding_id(1)
32 {
33 
34 }
35 
36 int
38 {
39  _ievent = 0;
40 
41  _fout_root = new TFile(_foutname.c_str(), "RECREATE");
42 
43  _tree_event = new TNtuple("ntp_event","event information from LQ events",
44  "ievent:pt_miss:pt_miss_phi:has_tau:has_uds:tau_eta:tau_phi:tau_e:tau_p:tau_pt:tau_decay_prong:tau_decay_hcharged:tau_decay_lcharged:uds_eta:uds_phi:uds_e:uds_p:uds_pt");
45 
46 
47  return 0;
48 }
49 
50 int
52 {
53  /* Access GenEventMap */
54  PHHepMCGenEventMap * geneventmap = findNode::getClass<PHHepMCGenEventMap>(topNode, "PHHepMCGenEventMap");
55  if (!geneventmap)
56  {
57  std::cout <<PHWHERE<<" - Fatal error - missing node PHHepMCGenEventMap"<<std::endl;
59  }
60 
61  /* Look for leptoquark and tau particle in the event */
62  TruthTrackerHepMC truth;
63  truth.set_hepmc_geneventmap( geneventmap );
64 
65  int pdg_lq = 39; // leptoquark
66  int pdg_tau = 15; // tau lepton
67 
68  /* Search for leptoquark in event */
69  HepMC::GenParticle* particle_lq = truth.FindParticle( pdg_lq );
70 
71  /* Search for lq->tau decay in event */
72  HepMC::GenParticle* particle_tau = truth.FindDaughterParticle( pdg_tau, particle_lq );
73 
74  /* Search for lq->quark decay in event.
75  * Loop over all quark PDG codes until finding a matching quark. */
76  HepMC::GenParticle* particle_quark = NULL;
77  for ( int pdg_quark = 1; pdg_quark < 7; pdg_quark++ )
78  {
79  /* try quark */
80  particle_quark = truth.FindDaughterParticle( pdg_quark, particle_lq );
81  if (particle_quark)
82  break;
83 
84  /* try anti-quark */
85  particle_quark = truth.FindDaughterParticle( -pdg_quark, particle_lq );
86  if (particle_quark)
87  break;
88  }
89 
90  /* extract numbers from truth particles */
91  bool tau_found = false;
92  bool quark_found = false;
93 
94  double tau_eta = 0;
95  double tau_phi = 0;
96  double tau_e = 0;
97  double tau_p = 0;
98  double tau_pt = 0;
99 
100  uint tau_decay_prong = 0;
101  uint tau_decay_hcharged = 0;
102  uint tau_decay_lcharged = 0;
103 
104  double quark_eta = 0;
105  double quark_phi = 0;
106  double quark_e = 0;
107  double quark_p = 0;
108  double quark_pt = 0;
109 
110  float pt_miss = 0;
111  float pt_miss_phi = 0;
112 
113  /* Calculate missing transverse momentum in event */
114  truth.FindMissingPt( pt_miss, pt_miss_phi );
115 
116  /* If TAU in event: update tau information */
117  if( particle_tau )
118  {
119  tau_found = true;
120  tau_eta = particle_tau->momentum().eta();
121  tau_phi = particle_tau->momentum().phi();
122 
123  /* Event record uses 0 < phi < 2Pi, while Fun4All uses -Pi < phi < Pi.
124  * Therefore, correct angle for 'wraparound' at phi == Pi */
125  if(tau_phi>TMath::Pi()) tau_phi = tau_phi-2*TMath::Pi();
126 
127  tau_e = particle_tau->momentum().e();
128  tau_p = sqrt( pow( particle_tau->momentum().px(), 2 ) +
129  pow( particle_tau->momentum().py(), 2 ) +
130  pow( particle_tau->momentum().pz(), 2 ) );
131  tau_pt = particle_tau->momentum().perp();
132 
133  /* Count how many charged particles (hadrons and leptons) the tau particle decays into. */
134  truth.FindDecayParticles( particle_tau, tau_decay_prong, tau_decay_hcharged, tau_decay_lcharged );
135 
136  }
137 
138  /* If QUARK (->jet) in event: Tag the tau candidate (i.e. jet) with smalles delta_R from this quark */
139  /* @TODO: This is a copy from the loop to tag the tau candidate with smallest delta_R w.r.t. final state tau-
140  * instead of copying the code, make a function that can be called for both (GetMinDeltaRElement or similar) */
141  if( particle_quark )
142  {
143  quark_found = true;
144  quark_eta = particle_quark->momentum().eta();
145  quark_phi = particle_quark->momentum().phi();
146 
147  /* Event record uses 0 < phi < 2Pi, while Fun4All uses -Pi < phi < Pi.
148  * Therefore, correct angle for 'wraparound' at phi == Pi */
149  if(quark_phi>TMath::Pi()) quark_phi = quark_phi-2*TMath::Pi();
150 
151  quark_e = particle_quark->momentum().e();
152  quark_p = sqrt( pow( particle_quark->momentum().px(), 2 ) +
153  pow( particle_quark->momentum().py(), 2 ) +
154  pow( particle_quark->momentum().pz(), 2 ) );
155  quark_pt = particle_quark->momentum().perp();
156 
157  }
158 
159  /* Fill event information to ntupple */
160  float event_data[18] = { (float) _ievent,
161  (float) pt_miss,
162  (float) pt_miss_phi,
163  (float) tau_found,
164  (float) quark_found,
165  (float) tau_eta,
166  (float) tau_phi,
167  (float) tau_e,
168  (float) tau_p,
169  (float) tau_pt,
170  (float) tau_decay_prong,
171  (float) tau_decay_hcharged,
172  (float) tau_decay_lcharged,
173  (float) quark_eta,
174  (float) quark_phi,
175  (float) quark_e,
176  (float) quark_p,
177  (float) quark_pt
178  };
179 
180  _tree_event->Fill( event_data );
181 
182  /* count up event number */
183  _ievent ++;
184 
185  return 0;
186 }
187 
188 int
190 {
191  _fout_root->cd();
192  _tree_event->Write();
193  _fout_root->Close();
194 
195  return 0;
196 }
197 
198 
199 void
201 {
202  bool final_state = false;
203  while ( !final_state )
204  {
205  /* Loop over all children at the end vertex of this particle */
206  for ( HepMC::GenVertex::particle_iterator child
207  = particle->end_vertex()->particles_begin(HepMC::children);
208  child != particle->end_vertex()->particles_end(HepMC::children);
209  ++child )
210  {
211  /* If there is a child of same particle ID, this was not the final state particle- update pointer to particle and repeat */
212  if ( (*child)->pdg_id() == particle->pdg_id() )
213  {
214  particle = (*child);
215  break;
216  }
217  final_state = true;
218  }
219  }
220  return;
221 }