Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ExclusiveReco.C
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ExclusiveReco.C
1 #include "ExclusiveReco.h"
2 #include "TruthTrackerHepMC.h"
4 #include "DVMPHelper.h"
5 /* STL includes */
6 #include <cassert>
7 
8 /* Fun4All includes */
10 
11 #include <phool/getClass.h>
12 
14 
15 #include <calobase/RawTowerGeomContainer.h>
16 #include <calobase/RawTowerContainer.h>
17 #include <calobase/RawTowerGeom.h>
18 #include <calobase/RawTowerv1.h>
19 #include <calobase/RawTowerDefs.h>
20 
21 #include <calobase/RawClusterContainer.h>
22 #include <calobase/RawCluster.h>
23 
24 #include <g4eval/CaloEvalStack.h>
25 
26 #include <g4main/PHG4Particle.h>
27 
28 
29 /* ROOT includes */
30 #include <TString.h>
31 #include <TTree.h>
32 #include <TFile.h>
33 
34 using namespace std;
35 
37  SubsysReco("ExclusiveReco" ),
38  _mproton( 0.938272 ),
39  _save_towers(false),
40  _save_tracks(false),
41  _ievent(0),
42  _filename(filename),
43  _tfile(nullptr),
44  _tree_invariant_mass(nullptr),
45  _tree_event_reco(nullptr),
46  _tree_event_truth(nullptr),
47  _beam_electron_ptotal(10),
48  _beam_hadron_ptotal(250),
49  _trackproj(nullptr)
50 {
51 
52 }
53 
54 int
56 {
57  _topNode = topNode;
58 
59  _ievent = 0;
60 
61  _tfile = new TFile(_filename.c_str(), "RECREATE");
62 
63  /* Create tree for information about full event */
64  _tree_invariant_mass = new TTree("event_exclusive", "A tree with exclusive event information");
65  _tree_invariant_mass->Branch("event", &_ievent, "event/I");
66 
67  _tree_invariant_mass->Branch("reco_inv", &_vect1);
68  _tree_invariant_mass->Branch("true_inv", &_vect2);
69  _tree_invariant_mass->Branch("reco_inv_decay", &_vect3);
70  _tree_invariant_mass->Branch("reco_inv_scatter", &_vect4);
71  _tree_invariant_mass->Branch("true_inv_decay", &_vect5);
72  _tree_invariant_mass->Branch("true_inv_scatter", &_vect6);
73 
74  /* Create tree for information about reco event */
75  _tree_event_reco = new TTree("event_reco", "A tree with reco particle information");
76  _tree_event_reco->Branch("event", &_ievent, "event/I");
77  _tree_event_reco->Branch("eta", &reco_eta);
78  _tree_event_reco->Branch("phi", &reco_phi);
79  _tree_event_reco->Branch("ptotal", &reco_ptotal);
80  _tree_event_reco->Branch("charge", &reco_charge);
81  _tree_event_reco->Branch("cluster_e", &reco_cluster_e);
82  _tree_event_reco->Branch("is_scattered_lepton", &reco_is_scattered_lepton);
83 
84 
85  /* Create tree for information about reco event */
86  _tree_event_truth = new TTree("event_truth", "A tree with truth particle information");
87  _tree_event_truth->Branch("event", &_ievent, "event/I");
88  _tree_event_truth->Branch("geta", &true_eta);
89  _tree_event_truth->Branch("gphi", &true_phi);
90  _tree_event_truth->Branch("gptotal", &true_ptotal);
91  _tree_event_truth->Branch("pid",&true_pid);
92  _tree_event_truth->Branch("is_scattered_lepton",&is_scattered_lepton);
93 
94  return 0;
95 }
96 
97 int
99 {
100  _trackproj=new TrackProjectorPlaneECAL( topNode );
101  return 0;
102 }
103 
104 int
106 {
107  /* Calculate invariant mass of a DVMP event */
108  if ( _do_process_dvmp )
109  {
111  }
112  /* count up event number */
113  _ievent ++;
114 
115  return 0;
116 }
117 
118 int
120 {
121  /* First, add truth particle information */
122  // ------------------------------------------------------------------------//
123  //true vectors are defined in header file
124  true_eta.clear(); true_phi.clear(); true_ptotal.clear(); true_pid.clear(); is_scattered_lepton.clear();
125  // -----------------------------------------------------------------------//
126  /* Get collection of truth particles from event generator */
127  PHHepMCGenEventMap *geneventmap = findNode::getClass<PHHepMCGenEventMap>(_topNode,"PHHepMCGenEventMap");
128  if (!geneventmap) {
129  std::cout << PHWHERE << " WARNING: Can't find requested PHHepMCGenEventMap" << endl;
130  return -1;
131  }
132 
133  /* Add truth kinematics */
134  int embedding_id = 1;
135  PHHepMCGenEvent *genevt = geneventmap->get(embedding_id);
136  if (!genevt)
137  {
138  std::cout << PHWHERE << "WARNING: Node PHHepMCGenEventMap missing subevent with embedding ID "<< embedding_id;
139  std::cout <<". Print PHHepMCGenEventMap:";
140  geneventmap->identify();
141  return -1;
142  }
143 
144  HepMC::GenEvent* theEvent = genevt->getEvent();
145 
146  if ( !theEvent )
147  {
148  std::cout << PHWHERE << "WARNING: Missing requested GenEvent!" << endl;
149  return -1;
150  }
151 
152  /* Look for scattered lepton */
153  TruthTrackerHepMC truth;
154  truth.set_hepmc_geneventmap( geneventmap );
155  HepMC::GenParticle* particle_scattered_l = truth.FindScatteredLepton();
156  /* loop over all particles */
157  for (HepMC::GenEvent::particle_const_iterator p = theEvent->particles_begin();
158  p != theEvent->particles_end(); ++p)
159  {
160  /* skip particles that are not stable final state particles (status 1) */
161  if ( (*p)->status() != 1 )
162  continue;
163 
164  float mom_eta = -1 * log ( tan( (*p)->momentum().theta() / 2.0 ) );
165 
166  true_eta.push_back(mom_eta);
167  true_phi.push_back( (*p)->momentum().phi() );
168  true_ptotal.push_back( (*p)->momentum().e() );
169  true_pid.push_back( (*p)->pdg_id() );
170 
171  if ( particle_scattered_l &&
172  (*p) == particle_scattered_l )
173  is_scattered_lepton.push_back(true);
174  else
175  is_scattered_lepton.push_back(false);
176  }
177  /* Second, add reconstructed particle information */
178  // --------------------------------------------------------------------------
179  //reco vectors are defined in header file
180  reco_eta.clear(); reco_phi.clear(); reco_ptotal.clear(); reco_cluster_e.clear(); reco_charge.clear(); reco_is_scattered_lepton.clear();
181  // --------------------------------------------------------------------------
182  vector< string > v_ecals;
183  v_ecals.push_back("EEMC");
184  v_ecals.push_back("CEMC");
185  v_ecals.push_back("FEMC");
186  for ( unsigned idx = 0; idx < v_ecals.size(); idx++ )
187  {
188  string clusternodename = "CLUSTER_" + v_ecals.at( idx );
189  RawClusterContainer *clusterList = findNode::getClass<RawClusterContainer>(_topNode,clusternodename.c_str());
190  SvtxTrackMap *trackmap = findNode::getClass<SvtxTrackMap>(_topNode,"SvtxTrackMap");
191  if (!clusterList) {
192  cerr << PHWHERE << " ERROR: Can't find node " << clusternodename << endl;
193  return false;
194  }
195  if(!trackmap) {
196  cerr << PHWHERE << " ERROR: Can't find node SvtxTrackMap" << endl;
197  return false;
198  }
199 
200  for (unsigned int k = 0; k < clusterList->size(); ++k)
201  {
202  RawCluster *cluster = clusterList->getCluster(k);
203  /* Check if cluster energy is below threshold */
204  float e_cluster_threshold = 0.3;
205  if ( cluster->get_energy() < e_cluster_threshold )
206  continue;
207 
209 
210  SvtxTrack *best_track = _trackproj->get_best_track(trackmap,cluster);
211  if(best_track!=NULL)
212  {
213  reco_eta.push_back(best_track->get_eta());
214  reco_phi.push_back(best_track->get_phi());
215  // See if particle is in EEMC, if so, swap ptotal with cluster e
216  RawCluster::TowerConstIterator rtiter = cluster->get_towers().first;
217  const char * cc = RawTowerDefs::convert_caloid_to_name( RawTowerDefs::decode_caloid( rtiter->first )).c_str();
218  if(strcmp(cc,"EEMC")==0)
219  {
220  reco_ptotal.push_back(cluster->get_energy());
221  }
222  else
223  {
224  reco_ptotal.push_back(best_track->get_p());
225  }
226  reco_charge.push_back(best_track->get_charge());
227  reco_cluster_e.push_back(cluster->get_energy());
228 
229  // Look at every truth particle
230  for(unsigned i = 0 ; i < true_eta.size() ; i++)
231  {
232  // Compute difference in reco particle eta and phi w/ true
233  float eta_diff = abs(best_track->get_eta()-true_eta.at(i));
234  float phi_diff = abs(best_track->get_phi()-true_phi.at(i));
235 
236  // If the differences in these values is very small
237  if(eta_diff<0.1&&phi_diff<0.1)
238  {
239  bool b = is_scattered_lepton.at(i)&&best_track->get_charge()==-1;
240  if(b)
241  reco_is_scattered_lepton.push_back(true);
242  else
243  reco_is_scattered_lepton.push_back(false);
244  }
245  else
246  {
247  reco_is_scattered_lepton.push_back(false);
248  }
249  }
250  }
251  else
252  {
253  reco_eta.push_back(NAN);
254  reco_phi.push_back(NAN);
255  reco_ptotal.push_back(NAN);
256  reco_charge.push_back(0);
257  reco_cluster_e.push_back(NAN);
258  reco_is_scattered_lepton.push_back(false);
259  }
260  }
261  }
262 
263  // At this point, we have all the truth and reco event information we need to fiddle around with measuring the invariant mass //
265 
266  // 1) Invariant Mass of all reconstructed e- e+ pairs
267  // 2) Invariant Mass of all truth e- e+ pairs
268  // 3) Invariant Mass of reco decay e- e+ pairs (**USES TRUTH INFO**)
269  // 4) Invariant Mass of reco scattered e- e+ pairs (**USES TRUTH INFO**)
270  // 5) Invariant Mass of truth decay e- e+ pairs
271  // 6) Invariant Mass of truth scattered e- e+ pairs
272 
279 
280  _tree_event_reco->Fill();
281  _tree_event_truth->Fill();
282  _tree_invariant_mass->Fill();
283  return 0;
284 }
285 
286 int
288 {
289  _tfile->cd();
290 
291  if ( _tree_invariant_mass )
292  {
293  _tree_event_reco->Write();
294  _tree_event_truth->Write();
295  _tree_invariant_mass->Write();
296  }
297 
298  _tfile->Close();
299 
300  return 0;
301 }