Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pythiaEMCalAna.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file pythiaEMCalAna.cc
1 
2 //____________________________________________________________________________..
3 
4 //our base code
5 #include "pythiaEMCalAna.h"
6 
8 
10 
11 //Fun4all stuff
13 #include <fun4all/Fun4AllServer.h>
15 #include <phool/PHCompositeNode.h>
16 #include <phool/getClass.h>
17 #include <phool/phool.h>
18 #include <ffaobjects/EventHeader.h>
19 
20 //ROOT stuff
21 #include <TH1F.h>
22 #include <TH2F.h>
23 #include <TH3F.h>
24 #include <TFile.h>
25 #include <TLorentzVector.h>
26 #include <TTree.h>
27 
28 //for emc clusters
29 #include <calobase/RawCluster.h>
30 #include <calobase/RawClusterContainer.h>
31 #include <calobase/RawClusterUtility.h>
32 #include <calobase/RawTowerGeomContainer.h>
33 #include <calobase/RawTower.h>
34 #include <calobase/RawTowerContainer.h>
35 
36 //caloEvalStack for cluster to truth matching
37 #include <g4eval/CaloEvalStack.h>
38 /* #include <g4eval/CaloRawClusterEval.h> */
39 
40 //for vertex information
43 /* #include <g4vertex/GlobalVertex.h> */
44 /* #include <g4vertex/GlobalVertexMap.h> */
45 
46 //tracking
49 /* #include <trackbase_historic/SvtxVertex.h> */
50 /* #include <trackbase_historic/SvtxVertexMap.h> */
51 
52 //truth information
54 #include <g4main/PHG4Particle.h>
55 #include <g4main/PHG4VtxPoint.h>
58 #pragma GCC diagnostic push
59 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
60 #include <HepMC/GenEvent.h>
61 #include <HepMC/GenParticle.h>
62 #include <HepMC/GenVertex.h>
63 #include <HepMC/IteratorRange.h>
64 #include <HepMC/SimpleVector.h>
65 #include <HepMC/GenParticle.h>
66 #pragma GCC diagnostic pop
67 
68 //____________________________________________________________________________..
69 pythiaEMCalAna::pythiaEMCalAna(const std::string &name, const std::string &oname, bool isMC, bool hasPythia):
70 SubsysReco(name),
71  clusters_Towers(nullptr),
72  truth_particles(nullptr),
73  m_tower_energy(0),
74  m_eta_center(0),
75  m_phi_center(0),
76  m_cluster_ID(0),
77  m_cluster_e(0),
78  m_cluster_eta(0),
79  m_cluster_phi(0),
80  m_cluster_ecore(0),
81  m_cluster_chi2(0),
82  m_cluster_prob(0),
83  m_cluster_nTowers(0),
84  m_cluster_maxE_trackID(0),
85  m_cluster_maxE_PID(0),
86  m_cluster_all_trackIDs(0),
87  /* m_truthBarcode(0), */
88  /* m_truthParentBarcode(0), */
89  m_truthIsPrimary(0),
90  m_truthTrackID(0),
91  m_truthPid(0),
92  m_truthE(0),
93  m_truthEta(0),
94  m_truthPhi(0),
95  m_truthPt(0),
96  m_truthMass(0),
97  m_truthEndVtx_x(0),
98  m_truthEndVtx_y(0),
99  m_truthEndVtx_z(0),
100  m_truthEndVtx_t(0),
101  m_truthEndVtx_r(0),
102  m_truth_all_clusterIDs(0),
103  fout(NULL),
104  outname(oname),
105  getEvent(-9999),
106  /* hasHIJING(isAuAu), */
107  isMonteCarlo(isMC),
108  hasPYTHIA(hasPythia),
109  n_primaries(0),
110  n_primary_photons(0),
111  n_direct_photons(0),
112  n_leptons(0),
113  n_neutral_hadrons(0),
114  n_neutral_hadrons_geant(0),
115  n_neutral_hadrons_pythia(0),
116  n_charged_hadrons(0),
117  n_charged_hadrons_geant(0),
118  n_charged_hadrons_pythia(0),
119  n_pythia_decayed_hadrons(0),
120  allTrackIDs(),
121  pythiaBarcodes()
122  /* n_direct_photons_in_acceptance(0), */
123  /* n_pythia_direct_photons(0), */
124  /* n_decay_photons(0), */
125  /* n_decay_photons_in_acceptance(0), */
126  /* n_pythia_decays(0), */
127  /* n_pythia_decays_in_acceptance(0), */
128  /* n_geant_decays(0), */
129  /* n_geant_decays_in_acceptance(0), */
130  /* n_primary_in_acceptance(0), */
131  /* n_pythia_decay_photons(0), */
132  /* n_pythia_decay_photons_in_acceptance(0), */
133  /* n_pythia_decayed_pi0s(0), */
134  /* n_pythia_decayed_pi0s_in_acceptance(0), */
135  /* n_pythia_nondecayed_hadrons(0), */
136  /* n_pythia_nondecayed_hadrons_in_acceptance(0), */
137  /* n_pythia_nondecayed_pi0s(0), */
138  /* n_pythia_nondecayed_pi0s_in_acceptance(0), */
139  /* n_geant_decay_photons(0), */
140  /* n_geant_decay_photons_in_acceptance(0), */
141  /* n_geant_primary_hadrons(0), */
142  /* n_geant_primary_hadrons_in_acceptance(0), */
143  /* n_geant_primary_pi0s(0), */
144  /* n_geant_primary_pi0s_in_acceptance(0), */
145  /* pythia_primary_barcodes(0), */
146  /* primaryBarcodes(0), */
147  /* secondaryBarcodes(0) */
148 {
149 std::cout << "pythiaEMCalAna::pythiaEMCalAna(const std::string &name) Calling ctor" << std::endl;
150 }
151 //____________________________________________________________________________..
153 {
154  std::cout << "pythiaEMCalAna::~pythiaEMCalAna() Calling dtor" << std::endl;
155 }
156 
157 //____________________________________________________________________________..
159 {
160  std::cout << "pythiaEMCalAna::Init(PHCompositeNode *topNode) Initializing" << std::endl;
161 
162  fout = new TFile(outname.c_str(),"RECREATE");
163 
164  clusters_Towers = new TTree("TreeClusterTower","Tree for cluster and tower information");
165  clusters_Towers -> Branch("towerEnergy",&m_tower_energy);
166  clusters_Towers -> Branch("towerEtaCenter",&m_eta_center);
167  clusters_Towers -> Branch("towerPhiCenter",& m_phi_center);
168  clusters_Towers -> Branch("clusterID",&m_cluster_ID);
169  clusters_Towers -> Branch("clusterE",&m_cluster_e);
170  clusters_Towers -> Branch("clusterEta",&m_cluster_eta);
171  clusters_Towers -> Branch("clusterPhi", &m_cluster_phi);
172  clusters_Towers -> Branch("clusterEcore",&m_cluster_ecore);
173  clusters_Towers -> Branch("clusterChi2",&m_cluster_chi2);
174  clusters_Towers -> Branch("clusterProb",&m_cluster_prob);
175  clusters_Towers -> Branch("clusterNTowers",&m_cluster_nTowers);
176  if (isMonteCarlo) {
177  clusters_Towers -> Branch("clusterMaxE_trackID",&m_cluster_maxE_trackID);
178  clusters_Towers -> Branch("clusterMaxE_PID",&m_cluster_maxE_PID);
179  clusters_Towers -> Branch("clusterAll_trackIDs",&m_cluster_all_trackIDs, 32000, 0);
180  }
181 
182  if (isMonteCarlo) {
183  truth_particles = new TTree("TreeTruthParticles", "Tree for Truth Particles");
184  /* truth_particles->Branch("truthBarcode",&m_truthBarcode, 32000, 0); */
185  /* truth_particles->Branch("truthParentBarcode",&m_truthParentBarcode, 32000, 0); */
186  truth_particles->Branch("truthIsPrimary",&m_truthIsPrimary);
187  truth_particles->Branch("truthTrackID",&m_truthTrackID);
188  truth_particles->Branch("truthPid",&m_truthPid);
189  truth_particles->Branch("truthE",&m_truthE);
190  truth_particles->Branch("truthEta",&m_truthEta);
191  truth_particles->Branch("truthPhi",&m_truthPhi);
192  truth_particles->Branch("truthPt",&m_truthPt);
193  truth_particles->Branch("truthMass",&m_truthMass);
194  truth_particles->Branch("truthEndVtx_x",&m_truthEndVtx_x);
195  truth_particles->Branch("truthEndVtx_y",&m_truthEndVtx_y);
196  truth_particles->Branch("truthEndVtx_z",&m_truthEndVtx_z);
197  truth_particles->Branch("truthEndVtx_t",&m_truthEndVtx_t);
198  truth_particles->Branch("truthEndVtx_r",&m_truthEndVtx_r);
199  truth_particles->Branch("truthAllClusterIDs",&m_truth_all_clusterIDs, 32000, 0);
200  }
201 
202  /* clusters_Towers->MakeClass("cluster"); */
203  /* truth_particles->MakeClass("truthParticles"); */
204 
206 }
207 
208 //____________________________________________________________________________..
210 {
211  std::cout << "pythiaEMCalAna::InitRun(PHCompositeNode *topNode) Initializing for Run XXX" << std::endl;
213 }
214 
215 //____________________________________________________________________________..
217 {
218  /* std::cout << "pythiaEMCalAna::process_event(PHCompositeNode *topNode) Processing event..." << std::endl; */
219 
220  //Tower geometry node for location information
221  RawTowerGeomContainer *towergeom = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_CEMC");
222  if (!towergeom)
223  {
224  std::cout << PHWHERE << "singlePhotonClusterAna::process_event Could not find node TOWERGEOM_CEMC" << std::endl;
226  }
227 
228  //Raw tower information
229  RawTowerContainer *towerContainer = nullptr;
230  // again, node has different names in MC and RD
231  if (isMonteCarlo) {
232  towerContainer = findNode::getClass<RawTowerContainer>(topNode,"TOWER_CALIB_CEMC");
233  /* std::cout << "isMonteCarlo=" << isMonteCarlo << ", towerContainer=" << towerContainer << "\n"; */
234  /* else { */
235  /* std::cout << "Greg info: isMonteCarlo is false\n"; */
236  /* towerContainer = findNode::getClass<RawTowerContainer>(topNode,"TOWERINFO_CALIB_CEMC"); */
237  /* std::cout << "Greg info: towerContainer is " << towerContainer << std::endl; */
238  /* } */
239  if(!towerContainer) {
240  if (isMonteCarlo) std::cout << PHWHERE << "pythiaEMCalAna::process_event Could not find node TOWER_CALIB_CEMC" << std::endl;
241  else std::cout << PHWHERE << "pythiaEMCalAna::process_event Could not find node TOWERINFO_CALIB_CEMC" << std::endl;
243  }
244  }
245 
246  CaloEvalStack *caloevalstack = nullptr;
247  CaloRawClusterEval *clustereval = nullptr;
248  if (isMonteCarlo) {
249  caloevalstack = new CaloEvalStack(topNode, "CEMC");
250  caloevalstack->next_event(topNode);
251  clustereval = caloevalstack->get_rawcluster_eval();
252  if(!clustereval)
253  {
254  std::cout << PHWHERE << "pythiaEMCalAna::process_event cluster eval not available" << std::endl;
256  }
257  }
258 
259  //Information on clusters
260  RawClusterContainer *clusterContainer = nullptr;
261  // Name of node is different in MC and RD
262  if (isMonteCarlo) {
263  /* clusterContainer = findNode::getClass<RawClusterContainer>(topNode,"CLUSTER_CEMC"); */
264  clusterContainer = findNode::getClass<RawClusterContainer>(topNode,"CLUSTER_POS_COR_CEMC");
265  }
266  else {
267  /* clusterContainer = findNode::getClass<RawClusterContainer>(topNode,"CLUSTERINFO_CEMC"); */
268  clusterContainer = findNode::getClass<RawClusterContainer>(topNode,"CLUSTERINFO_POS_COR_CEMC");
269  }
270  if(!clusterContainer)
271  {
272  if (isMonteCarlo) std::cout << PHWHERE << "pythiaEMCalAna::process_event - Fatal Error - CLUSTER_POS_COR_CEMC node is missing. " << std::endl;
273  else std::cout << PHWHERE << "pythiaEMCalAna::process_event - Fatal Error - CLUSTERINFO_CEMC node is missing. " << std::endl;
274  return 0;
275  }
276 
277  // Truth information
278  PHG4TruthInfoContainer *truthinfo = nullptr;
279  if (isMonteCarlo) {
280  truthinfo = findNode::getClass<PHG4TruthInfoContainer>(topNode, "G4TruthInfo");
281  if(!truthinfo) {
282  std::cout << PHWHERE << "pythiaEMCalAna::process_event Could not find node G4TruthInfo" << std::endl;
284  }
285  }
286  //Vertex information
287  GlobalVertex* gVtx = nullptr;
288  PHG4VtxPoint* mcVtx = nullptr;
289  // Problem is MC has a PrimaryVtx but no GlobalVertex, while RD has the opposite
290  if (isMonteCarlo) {
291  PHG4TruthInfoContainer::VtxRange vtx_range = truthinfo->GetPrimaryVtxRange();
292  PHG4TruthInfoContainer::ConstVtxIterator vtxIter = vtx_range.first;
293  mcVtx = vtxIter->second;
294  }
295  else {
296  GlobalVertexMap *vtxContainer = findNode::getClass<GlobalVertexMap>(topNode,"GlobalVertexMap");
297  if (!vtxContainer)
298  {
299  std::cout << PHWHERE << "pythiaEMCalAna::process_event - Fatal Error - GlobalVertexMap node is missing. Please turn on the do_global flag in the main macro in order to reconstruct the global vertex." << std::endl;
300  assert(vtxContainer); // force quit
301  return 0;
302  }
303  if (vtxContainer->empty())
304  {
305  /* std::cout << PHWHERE << "pythiaEMCalAna::process_event - Fatal Error - GlobalVertexMap node is empty. Please turn on the do_global flag in the main macro in order to reconstruct the global vertex." << std::endl; */
306  /* return 0; */
307  std::cout << "Info: global vertex map is empty. Using (0,0,0) for vertex\n";
308  }
309 
310  //More vertex information
311  else {
312  gVtx = vtxContainer->begin()->second;
313  if(!gVtx)
314  {
315  std::cout << PHWHERE << "pythiaEMCalAna::process_event Could not find vtx from vtxContainer" << std::endl;
317  }
318  }
319  }
320 
321  /* PHG4TruthInfoContainer::Range truthRange = truthinfo->GetPrimaryParticleRange(); */
322  /* PHG4TruthInfoContainer::ConstIterator truthIter; */
323  /* //from the HepMC event log */
324  /* for(truthIter = truthRange.first; truthIter != truthRange.second; truthIter++) */
325  /* { */
326  /* //PHG4Particle* part = truthinfo->GetParticle(truthIter->second->get_trkid()) */
327 
328  //For eventgen ancestory information
329  PHHepMCGenEventMap *genEventMap = nullptr;
330  if (isMonteCarlo) {
331  genEventMap = findNode::getClass<PHHepMCGenEventMap>(topNode, "PHHepMCGenEventMap");
332  if(!genEventMap)
333  {
334  std::cout << PHWHERE << "pythiaEMCalAna::process_event Could not find PHHepMCGenEventMap" << std::endl;
336  }
337  /* std::cout << "genEventMap is " << genEventMap << " with size " << genEventMap->size() << "; more details:\n"; */
338  /* genEventMap->identify(); */
339  }
340 
341  //event level information of the above
342  PHHepMCGenEvent *genEvent = nullptr; // = genEventMap -> get(getEvent);
343  /* if(!genEvent) */
344  /* { */
345  /* std::cout << PHWHERE << "pythiaEMCalAna::process_event Could not find PHHepMCGenEvent" << std::endl; */
346  /* return Fun4AllReturnCodes::ABORTEVENT; */
347  /* } */
348  /* std::cout << "genEvent is " << genEvent << " with size " << genEvent->size() << "; more details:\n"; */
349  /* genEvent->identify(); */
350 
351  HepMC::GenEvent *theEvent = nullptr; // = genEvent -> getEvent();
352 
353  //grab all the towers and fill their energies.
354  bool write_towers = true;
355  if (write_towers && isMonteCarlo) {
356  RawTowerContainer::ConstRange tower_range = towerContainer -> getTowers();
357  for(RawTowerContainer::ConstIterator tower_iter = tower_range.first; tower_iter!= tower_range.second; tower_iter++)
358  {
359  int phibin = tower_iter -> second -> get_binphi();
360  int etabin = tower_iter -> second -> get_bineta();
361  double phi = towergeom -> get_phicenter(phibin);
362  double eta = towergeom -> get_etacenter(etabin);
363  double energy = tower_iter -> second -> get_energy();
364 
365  m_tower_energy.push_back(energy);
366  m_eta_center.push_back(eta);
367  m_phi_center.push_back(phi);
368  }
369  }
370 
371  //grab all the clusters in the event
372  bool write_clusters = true;
373  bool apply_energy_cut = false;
374  float clusterMinEnergyCut = 0.3; // in GeV
375  if (write_clusters) {
376  RawClusterContainer::ConstRange clusterEnd = clusterContainer -> getClusters();
378  for(clusterIter = clusterEnd.first; clusterIter != clusterEnd.second; clusterIter++)
379  {
380  RawCluster *recoCluster = clusterIter -> second;
381  CLHEP::Hep3Vector vertex;
382  if (isMonteCarlo) vertex = CLHEP::Hep3Vector(mcVtx->get_x(), mcVtx->get_y(), mcVtx->get_z());
383  else {
384  if (gVtx) vertex = CLHEP::Hep3Vector(gVtx->get_x(), gVtx->get_y(), gVtx->get_z());
385  else vertex = CLHEP::Hep3Vector(0,0,0);
386  }
387  /* vertex = CLHEP::Hep3Vector(0., 0., 0.); */
388  CLHEP::Hep3Vector E_vec_cluster = RawClusterUtility::GetECoreVec(*recoCluster, vertex);
389  float clusE = recoCluster->get_energy();
390  float clusEcore = recoCluster->get_ecore();
391  float clus_eta = E_vec_cluster.pseudoRapidity();
392  float clus_phi = E_vec_cluster.phi();
393 
394  if (apply_energy_cut) {
395  if (clusE < clusterMinEnergyCut) continue;
396  }
397 
398  m_cluster_ID.push_back(recoCluster->get_id());
399  m_cluster_e.push_back(clusE);
400  m_cluster_eta.push_back(clus_eta);
401  m_cluster_phi.push_back(clus_phi);
402  m_cluster_ecore.push_back(clusEcore);
403  m_cluster_chi2.push_back(recoCluster -> get_chi2());
404  m_cluster_prob.push_back(recoCluster -> get_prob());
405  m_cluster_nTowers.push_back(recoCluster -> getNTowers());
406 
407  if (isMonteCarlo) {
408  std::set<PHG4Particle*> all_parts = clustereval->all_truth_primary_particles(recoCluster);
409  if (all_parts.empty()) {
410  // noise cluster without any real particles creating the shower
411  m_cluster_maxE_trackID.push_back(-1);
412  m_cluster_maxE_PID.push_back(-1);
413  std::vector<float> all_cluster_trackIDs;
414  m_cluster_all_trackIDs.push_back(all_cluster_trackIDs);
415  }
416  else {
417  PHG4Particle* maxE_part = clustereval->max_truth_primary_particle_by_energy(recoCluster);
418  m_cluster_maxE_trackID.push_back(maxE_part->get_track_id());
419  m_cluster_maxE_PID.push_back(maxE_part->get_pid());
420  // next we want a vector with all the tracks contributing to this cluster
421  std::vector<float> all_cluster_trackIDs;
422  for (auto& part : all_parts) {
423  all_cluster_trackIDs.push_back(part->get_track_id());
424  allTrackIDs.insert(part->get_track_id());
425  }
426  m_cluster_all_trackIDs.push_back(all_cluster_trackIDs);
427  }
428  }
429  } // end loop over clusters
430  }
431 
432  // Next grab the truth particles
433  if (isMonteCarlo) {
434  PHG4TruthInfoContainer::Range truthRange = truthinfo->GetPrimaryParticleRange();
436  /* std::cout << "\n\nGreg info: starting loop over Geant primary particles\n"; */
437  for(truthIter = truthRange.first; truthIter != truthRange.second; truthIter++)
438  {
439  PHG4Particle *truthPar = truthIter->second;
440  int track_id = truthPar->get_track_id();
441  // only interested in particles which produced a cluster
442  if (allTrackIDs.count(track_id) == 0) continue;
443  int embedID = truthinfo->isEmbeded(track_id);
444  genEvent = genEventMap -> get(embedID);
445  theEvent = genEvent -> getEvent();
446  if (truthPar->get_pid() != 22) {
447  // if it's not a photon, add it as a primary
448  addPrimaryFromGeant(truthPar, truthinfo, clustereval, theEvent);
449  }
450  else {
452  // if it is a photon, we have to check whether it's truly primary,
453  // or a decay photon handled in pythia
454  if (isDirectPhoton(truthPar, theEvent)) {
455  // if it's really a direct photon, add it normally
456  addPrimaryFromGeant(truthPar, truthinfo, clustereval, theEvent);
457  }
458  else {
459  // primary photon is actually a decay photon from a decay handled by pythia
460  // find the parent in pythia and add that as the true primary
461  HepMC::GenParticle* p = getGenParticle(truthPar->get_barcode(), theEvent);
462  HepMC::GenVertex* prod_vtx = p->production_vertex();
463  // should only have 1 parent; otherwise print an error
464  if (prod_vtx->particles_in_size() == 1) {
465  HepMC::GenVertex::particles_in_const_iterator parent = prod_vtx->particles_in_const_begin();
466  assert((*parent));
467  // parent's status and pdg_id tell us whether it's a direct photon
468  // or a decay photon
469  if ((*parent)->status() == 2 && abs((*parent)->pdg_id()) >= 100) {
470  // p is a decay photon and parent is the primary hadron
471  // check if we've already added the parent
472  if (pythiaBarcodes.count((*parent)->barcode()) == 0) {
473  // if not, add it
474  addPrimaryFromPythia((*parent));
475  }
476  }
477  else {
478  // weird case??
479  std::cout << "\nGreg info: weird combination of photon or parent status or PID... photon:\n";
480  p->print();
481  std::cout << "Parent:\n";
482  (*parent)->print();
483  std::cout << "\n";
484  }
485  }
486  else {
487  // weird photon -- they should only have 1 parent
488  std::cout << "\nGreg info: in PYTHIA check, found a photon with " << prod_vtx->particles_in_size() << " parent(s). Photon:\n";
489  p->print();
490  for (HepMC::GenVertex::particles_in_const_iterator parent = prod_vtx->particles_in_const_begin(); parent != prod_vtx->particles_in_const_end(); parent++) {
491  std::cout << "Parent:\n";
492  (*parent)->print();
493  }
494  std::cout << "\n";
495  }
496  } // end decay photon case
497  } // end photon check
498  } // end loop over primary particles
499  } // end grabbing truth info
500 
501 
502  clusters_Towers -> Fill();
503  if (isMonteCarlo) {
504  truth_particles -> Fill();
505  delete caloevalstack;
506  }
507 
508  // Below is some example code showing cluster->particle matching
509 
510  /* // Start with clusters, and find the corresponding truth particle(s) that */
511  /* // produced the shower */
512  /* RawClusterContainer::ConstRange clusterEnd = clusterContainer -> getClusters(); */
513  /* RawClusterContainer::ConstIterator clusterIter; */
514  /* for(clusterIter = clusterEnd.first; clusterIter != clusterEnd.second; clusterIter++) */
515  /* { */
516  /* RawCluster *recoCluster = clusterIter -> second; */
517  /* CLHEP::Hep3Vector vertex = CLHEP::Hep3Vector(mcVtx->get_x(), mcVtx->get_y(), mcVtx->get_z()); */
518  /* CLHEP::Hep3Vector E_vec_cluster = RawClusterUtility::GetECoreVec(*recoCluster, vertex); */
519  /* float clusE = E_vec_cluster.mag(); */
520  /* // Ignore clusters below 300MeV */
521  /* if (clusE < 0.3) continue; */
522 
523  /* // all particles that contributed energy to this cluster */
524  /* std::set<PHG4Particle*> all_parts = clustereval->all_truth_primary_particles(recoCluster); */
525  /* // need at least one particle; if not, cluster is just noise */
526  /* if (all_parts.size() < 1) continue; */
527  /* // particle which contributed the most energy to this cluster */
528  /* PHG4Particle* max_part = clustereval->max_truth_primary_particle_by_energy(recoCluster); */
529  /* /1* if (max_part->get_pid() > 0) continue; *1/ */
530  /* std::cout << "Greg info: printing cluster info:\n"; */
531  /* std::cout << Form("id=%d, (E, phi, eta) = (%f, %f, %f)\n", recoCluster->get_id(), clusE, E_vec_cluster.phi(), E_vec_cluster.pseudoRapidity()); */
532  /* /1* recoCluster->identify(); *1/ */
533  /* std::cout << "Corresponding particle info: (all_parts size=" << all_parts.size() << ", max_part=" << max_part << ")\n"; */
534  /* max_part->identify(); */
535  /* std::set<RawCluster*> max_part_clusters = clustereval->all_clusters_from(max_part); */
536  /* std::cout << "max_part contributed to " << max_part_clusters.size() << " clusters; printing those clusters\n"; */
537  /* for (auto& cl : max_part_clusters) { */
538  /* cl->identify(); */
539  /* } */
540  /* std::cout << "\n"; */
541  /* } */
542 
543 
544  // Below shows how to loop over all the different HepMC events in this Fun4All event
545 
546  /* PHHepMCGenEventMap::Iter genEventIter; */
547  /* for (genEventIter = genEventMap->begin(); genEventIter != genEventMap->end(); genEventIter++) { */
548  /* int embedID = genEventIter->first; */
549  /* // For HIJING embedded samples, the PYTHIA event has a positive embedID */
550  /* if (hasHIJING && embedID < 1) continue; */
551  /* if (embedID < 1) continue; */
552  /* genEvent = genEventIter->second; */
553  /* /1* std::cout << "Greg info: embedID=" << embedID << "; printing genEvent\n"; *1/ */
554  /* /1* genEvent->identify(); *1/ */
555  /* theEvent = genEvent->getEvent(); */
556  /* /1* std::cout << "Greg info: printing theEvent\n"; *1/ */
557  /* /1* theEvent->print(); *1/ */
558  /* /1* std::cout << Form("Greg info: embedID=%d, genEvent->is_simulated()=%d\n", embedID, genEvent->is_simulated()); *1/ */
559  /* // now loop over PYTHIA particles */
560  /* for(HepMC::GenEvent::particle_const_iterator p = theEvent -> particles_begin(); p != theEvent -> particles_end(); ++p) */
561  /* { */
562  /* assert(*p); */
563  /* // look for photons only */
564  /* if ((*p)->pdg_id() == 22) { */
565  /* // only want final-state particles, i.e. status = 1 */
566  /* if ((*p)->status() != 1) continue; */
567  /* // get the photon's parent */
568  /* HepMC::GenVertex* prod_vtx = (*p)->production_vertex(); */
569  /* if (prod_vtx->particles_in_size() == 1) { */
570  /* HepMC::GenVertex::particles_in_const_iterator parent = prod_vtx->particles_in_const_begin(); */
571  /* assert((*parent)); */
572  /* // parent's status and pdg_id tell us whether it's a direct photon */
573  /* // or a decay photon */
574  /* if ((*parent)->status() > 2 && abs((*parent)->pdg_id()) < 100) { */
575  /* // direct photon */
576  /* /1* addPrimaryFromPythia((*p)); *1/ */
577  /* n_pythia_direct_photons++; */
578  /* } */
579  /* else if ((*parent)->status() == 2 && abs((*parent)->pdg_id()) >= 100) { */
580  /* // decay photon */
581  /* n_pythia_decay_photons++; */
582  /* if (withinAcceptance((*p))) n_pythia_decay_photons_in_acceptance++; */
583  /* std::pair<int,int> embedBarcode = std::pair<int,int>(embedID, (*parent)->barcode()); */
584  /* if (! vector_contains(embedBarcode, pythia_primary_barcodes) ) { */
585  /* pythia_primary_barcodes.push_back(embedBarcode); */
586  /* n_pythia_decays++; */
587  /* if (withinAcceptance((*parent))) n_pythia_decays_in_acceptance++; */
588  /* if ( (*parent)->pdg_id() == 111 ) { */
589  /* n_pythia_decayed_pi0s++; */
590  /* if (withinAcceptance((*parent))) n_pythia_decayed_pi0s_in_acceptance++; */
591  /* } */
592  /* } */
593 
594  /* } */
595  /* else { */
596  /* // weird case?? */
597  /* std::cout << "\nGreg info: weird combination of photon or parent status or PID... photon:\n"; */
598  /* (*p)->print(); */
599  /* std::cout << "Parent:\n"; */
600  /* (*parent)->print(); */
601  /* std::cout << "\n"; */
602  /* } */
603  /* } */
604  /* else { */
605  /* // weird photon -- they should only have 1 parent */
606  /* std::cout << "\nGreg info: in PYTHIA check, found a photon with " << prod_vtx->particles_in_size() << " parent(s). Photon:\n"; */
607  /* (*p)->print(); */
608  /* for (HepMC::GenVertex::particles_in_const_iterator parent = prod_vtx->particles_in_const_begin(); parent != prod_vtx->particles_in_const_end(); parent++) { */
609  /* std::cout << "Parent:\n"; */
610  /* (*parent)->print(); */
611  /* } */
612  /* std::cout << "\n"; */
613  /* } */
614  /* } // end photon check */
615  /* else { */
616  /* // check for (final state) non-decayed pi0s */
617  /* if ( (*p)->status() == 1 && (*p)->pdg_id() > 100) { */
618  /* n_pythia_nondecayed_hadrons++; */
619  /* if (withinAcceptance((*p))) n_pythia_nondecayed_hadrons_in_acceptance++; */
620  /* if ( (*p)->pdg_id() == 111 ) { */
621  /* n_pythia_nondecayed_pi0s++; */
622  /* if (withinAcceptance((*p))) n_pythia_nondecayed_pi0s_in_acceptance++; */
623  /* } */
624  /* } */
625  /* } */
626  /* } // end PYTHIA loop */
627  /* } // end loop over embedID */
628  /* std::cout << "PYTHIA: " << n_pythia << " total particles, " << n_pho_pythia << " photons, " << n_pi0_pythia << " pi0s\n"; */
629 
630 
631  // Below is the old code I used to find truth photons
632  // Warning! Likely will not work after uncommenting. Should only be used as an example
633 
634  // Next check for decays handled by Geant
635  // Start with primary particles from GEANT
636  // Look for photons and decide if they are direct or decay photons
637  /* PHG4TruthInfoContainer::Range truthRange = truthinfo->GetPrimaryParticleRange(); */
638  /* PHG4TruthInfoContainer::ConstIterator truthIter; */
639  /* /1* std::cout << "\n\nGreg info: starting loop over Geant primary particles\n"; *1/ */
640  /* for(truthIter = truthRange.first; truthIter != truthRange.second; truthIter++) */
641  /* { */
642  /* PHG4Particle *truthPar = truthIter->second; */
643  /* int embedID = truthinfo->isEmbeded(truthPar->get_track_id()); */
644  /* if (hasHIJING && embedID < 1) continue; */
645  /* if (embedID < 1) continue; */
646  /* int geant_barcode = truthPar->get_barcode(); */
647  /* int pid = truthPar->get_pid(); */
648  /* // look for photons only */
649  /* if (pid == 22) { */
650  /* /1* std::cout << "\nFound a primary photon (embedID=" << embedID << ", barcode=" << geant_barcode << "); details:\t"; *1/ */
651  /* /1* truthPar->identify(); *1/ */
652  /* genEvent = genEventMap -> get(embedID); */
653  /* theEvent = genEvent -> getEvent(); */
654  /* // is it a direct photon? */
655  /* if (isDirectPhoton(truthPar, theEvent)) { */
656  /* /1* std::cout << "\tbarcode " << geant_barcode << " is a direct photon... adding to list\n"; *1/ */
657  /* n_direct_photons++; */
658  /* addDirectPhoton(truthPar, truthinfo); */
659  /* TLorentzVector truth_momentum; */
660  /* truth_momentum.SetPxPyPzE(truthPar->get_px(), truthPar->get_py(), truthPar->get_pz(), truthPar->get_e()); */
661  /* float eta = truth_momentum.PseudoRapidity(); */
662  /* if (abs(eta) <= 1.1) n_direct_photons_in_acceptance++; */
663  /* } */
664  /* else { */
665  /* // decay photon */
666  /* /1* std::cout << "\tbarcode " << geant_barcode << " is a decay photon... check parent info\n"; *1/ */
667  /* n_decay_photons++; */
668  /* if (withinAcceptance(truthPar)) n_decay_photons_in_acceptance++; */
669  /* addDecayPhoton(truthPar, truthinfo, theEvent); */
670  /* // find the parent and add it as a primary */
671  /* // primary photon means geant doesn't know about the parent */
672  /* // so match this photon to the pythia photon */
673  /* HepMC::GenParticle* pho = getGenParticle(geant_barcode, theEvent); */
674  /* /1* assert(pho); *1/ */
675  /* if (!pho) { */
676  /* // problem -- we couldn't find the corresponding pythia particle */
677  /* std::cout << "\t\tGreg info: skipping Geant primary with barcode " << geant_barcode << " because corresponding pythia particle could not be found; more details:\t"; */
678  /* truthPar->identify(); */
679  /* continue; */
680  /* } */
681  /* // now find the parent in pythia */
682  /* HepMC::GenVertex* prod_vtx = pho->production_vertex(); */
683  /* if (prod_vtx->particles_in_size() == 1) { */
684  /* HepMC::GenVertex::particles_in_const_iterator parent = prod_vtx->particles_in_const_begin(); */
685  /* assert((*parent)); */
686  /* /1* std::cout << "\t\tParent barcode=" << (*parent)->barcode() << ", id=" << (*parent)->pdg_id() << "... "; *1/ */
687  /* std::pair<int,int> embedBarcode(embedID, (*parent)->barcode()); */
688  /* if (! vector_contains(embedBarcode, primaryBarcodes) ) { */
689  /* /1* std::cout << "adding to primaries.\n"; *1/ */
690  /* primaryBarcodes.push_back(embedBarcode); */
691  /* n_primary++; */
692  /* if (withinAcceptance((*parent))) n_primary_in_acceptance++; */
693  /* /1* n_pythia_decays++; *1/ */
694  /* /1* std::cout << "adding primary from pythia. PID=" << (*parent)->pdg_id() << "\n"; *1/ */
695  /* addPrimaryHadronFromPythia((*parent), embedID); */
696  /* } */
697  /* else { */
698  /* /1* std::cout << "already added this primary.\n"; *1/ */
699  /* } */
700  /* } */
701  /* else { */
702  /* std::cout << "\t\tGreg info: pythia-decayed photon with " << prod_vtx->particles_in_size() << " parents. Skipping...\n"; */
703  /* } */
704  /* } */
705  /* } // end photon check */
706  /* else { */
707  /* if (pid > 100) { */
708  /* n_geant_primary_hadrons++; */
709  /* if (withinAcceptance(truthPar)) n_geant_primary_hadrons_in_acceptance++; */
710  /* } */
711  /* if (pid == 111) { */
712  /* n_geant_primary_pi0s++; */
713  /* if (withinAcceptance(truthPar)) n_geant_primary_pi0s_in_acceptance++; */
714  /* } */
715  /* } */
716  /* } // end loop over geant primary particles */
717 
718 
719  // Now loop over GEANT secondary particles, taking only the daughters
720  // of primary particles we already found
721  /* truthRange = truthinfo->GetSecondaryParticleRange(); */
722  /* /1* std::cout << "Greg info: starting loop over Geant secondary particles\n"; *1/ */
723  /* for(truthIter = truthRange.first; truthIter != truthRange.second; truthIter++) */
724  /* { */
725  /* PHG4Particle *truthPar = truthIter->second; */
726  /* int embedID = truthinfo->isEmbeded(truthPar->get_track_id()); */
727  /* if (hasHIJING && embedID < 1) continue; */
728  /* if (embedID < 1) continue; */
729  /* // only looking for decay photons and their corresponding primaries */
730  /* if (truthPar->get_pid() == 22) { */
731  /* // get the parent */
732  /* PHG4Particle* parent = truthinfo->GetParticle(truthPar->get_parent_id()); */
733  /* // make sure parent is a primary */
734  /* if ( truthinfo->is_primary(parent) ) { */
735  /* // make sure the "parent" isn't also a photon, i.e. the */
736  /* // same photon before and after an interaction */
737  /* if (parent->get_pid() == 22) continue; */
738 
739  /* /1* std::cout << "\tFound a secondary photon (barcode=" << truthPar->get_barcode() << ")\n"; *1/ */
740  /* /1* std::cout << "\t\tParent is primary (barcode=" << parent->get_barcode() << ", id=" << parent->get_pid() << "), "; *1/ */
741  /* n_decay_photons++; */
742  /* if (withinAcceptance(truthPar)) n_decay_photons_in_acceptance++; */
743  /* n_geant_decay_photons++; */
744  /* if (withinAcceptance(truthPar)) n_geant_decay_photons_in_acceptance++; */
745  /* addDecayPhoton(truthPar, truthinfo, theEvent); */
746  /* int embedID = truthinfo->isEmbeded(parent->get_track_id()); */
747  /* std::pair<int,int> embedBarcode(embedID, parent->get_barcode()); */
748  /* /1* if (parent->get_pid() == 111) { *1/ */
749  /* /1* std::cout << "Found a primary pi0 with embedID " << embedID << ", barcode " << parent->get_barcode() << "\n"; *1/ */
750  /* /1* } *1/ */
751  /* if (! vector_contains(embedBarcode, primaryBarcodes) ) { */
752  /* /1* std::cout << "adding to primaries.\n"; *1/ */
753  /* primaryBarcodes.push_back(embedBarcode); */
754  /* n_primary++; */
755  /* if (withinAcceptance(parent)) n_primary_in_acceptance++; */
756  /* n_geant_decays++; */
757  /* if (withinAcceptance(parent)) n_geant_decays_in_acceptance++; */
758 
759  /* /1* std::cout << "\tadded primary with embedID " << embedID << ", barcode " << parent->get_barcode() << "\n"; *1/ */
760  /* /1* std::cout << "Adding primary from geant. PID=" << parent->get_pid() << "\n"; *1/ */
761  /* addPrimaryHadronFromGeant(parent, truthinfo); */
762  /* /1* std::cout << "\nFound a geant-decayed primary:\n"; *1/ */
763  /* /1* parent->identify(); *1/ */
764  /* /1* std::cout << "Daughter photon is\n"; *1/ */
765  /* /1* truthPar->identify(); *1/ */
766  /* /1* std::cout << "\n"; *1/ */
767  /* } */
768  /* else { */
769  /* /1* std::cout << "already added this primary.\n"; *1/ */
770  /* } */
771  /* } */
772  /* /1* else { *1/ */
773  /* /1* std::cout << "\t\tParent is *not* primary. Skipping!\n"; *1/ */
774  /* /1* } *1/ */
775  /* } //end photon check */
776  /* } // end loop over geant secondaries */
777 
778 
780 }
781 
782 //____________________________________________________________________________..
784 {
785 
786  m_tower_energy.clear();
787  m_eta_center.clear();
788  m_phi_center.clear();
789  m_cluster_ID.clear();
790  m_cluster_e.clear();
791  m_cluster_eta.clear();
792  m_cluster_phi.clear();
793  m_cluster_ecore.clear();
794  m_cluster_chi2.clear();
795  m_cluster_prob.clear();
796  m_cluster_nTowers.clear();
797  m_cluster_maxE_trackID.clear();
798  m_cluster_maxE_PID.clear();
799  m_cluster_all_trackIDs.clear();
800  m_truthIsPrimary.clear();
801  m_truthTrackID.clear();
802  m_truthPid.clear();
803  m_truthE.clear();
804  m_truthEta.clear();
805  m_truthPhi.clear();
806  m_truthPt.clear();
807  m_truthMass.clear();
808  m_truthEndVtx_x.clear();
809  m_truthEndVtx_y.clear();
810  m_truthEndVtx_z.clear();
811  m_truthEndVtx_t.clear();
812  m_truthEndVtx_r.clear();
813  m_truth_all_clusterIDs.clear();
814  allTrackIDs.clear();
815  pythiaBarcodes.clear();
816 
818 }
819 
820 //____________________________________________________________________________..
822 {
823  std::cout << "pythiaEMCalAna::EndRun(const int runnumber) Ending Run for Run " << runnumber << std::endl;
825 }
826 
827 //____________________________________________________________________________..
829 {
830  std::cout << "pythiaEMCalAna::End(PHCompositeNode *topNode) This is the End..." << std::endl;
831  if (isMonteCarlo) {
832  std::cout << Form("Total primary particles: %ld\n", n_primaries);
833  std::cout << Form("Total primary hadrons decayed by pythia: %ld\n", n_pythia_decayed_hadrons);
834  std::cout << Form("Total \"primary\" photons: %ld\n", n_primary_photons);
835  std::cout << Form("Total direct photons: %ld\n", n_direct_photons);
836  std::cout << Form("Total neutral hadrons: %ld (%ld geant, %ld pythia)\n", n_neutral_hadrons, n_neutral_hadrons_geant, n_neutral_hadrons_pythia);
837  std::cout << Form("Total charged hadrons: %ld (%ld geant, %ld pythia)\n", n_charged_hadrons, n_charged_hadrons_geant, n_charged_hadrons_pythia);
838  std::cout << Form("Total primary leptons: %ld\n", n_leptons);
839  }
840  fout -> cd();
841  std::cout << "Writing clusters_Towers\n";
842  clusters_Towers -> Write();
843  if (isMonteCarlo) {
844  std::cout << "Writing truth_particles\n";
845  truth_particles -> Write();
846  }
847  fout -> Close();
849 }
850 
851 //____________________________________________________________________________..
853 {
854  std::cout << "pythiaEMCalAna::Reset(PHCompositeNode *topNode) being Reset" << std::endl;
856 }
857 
858 //____________________________________________________________________________..
859 void pythiaEMCalAna::Print(const std::string &what) const
860 {
861  std::cout << "pythiaEMCalAna::Print(const std::string &what) const Printing info for " << what << std::endl;
862 }
863 
864 // PID stuff to print info on how many of each truth particle there were
865 // Mostly useful as a sanity check
866 
867 bool IsBaryon(int pdg_id) {
868  /* std::cout << Form("Entering IsBaryon(%d)\n", pdg_id); */
869  bool ret = false;
870  // baryon ids are 4-digit numbers
871  if (abs(pdg_id) > 999 && abs(pdg_id) < 10000) ret = true;
872  /* std::cout << Form("In IsBaryon(%d): returning %s\n", pdg_id, ret ? "true": "false"); */
873  return ret;
874 }
875 
876 bool IsNeutralBaryon(int pdg_id) {
877  /* std::cout << Form("Entering IsNeutralBaryon(%d)\n", pdg_id); */
878  if (!IsBaryon(pdg_id)) return false;
879  // baryon ids are 4-digit numbers
880  int base_id = abs(pdg_id) % 10000;
881  // the last digit is the angular momentum state
882  // the first three digits are the quark flavors
883  int q1 = (int)(base_id/1000);
884  int q2 = (int)(base_id/100 % 10);
885  int q3 = (int)(base_id/10 % 10);
886  // odd numbers 1,3,5 are d,s,b; even numbers 2,4,6 are u,c,t
887  float charge = 0.;
888  if (q1%2 == 0) charge += 2./3.;
889  else charge -= 1./3.;
890  if (q2%2 == 0) charge += 2./3.;
891  else charge -= 1./3.;
892  if (q3%2 == 0) charge += 2./3.;
893  else charge -= 1./3.;
894  /* std::cout << Form("In IsNeutralBaryon: base_id=%d, charge=%f\n", base_id, charge); */
895  if (abs(charge) < 0.05) return true;
896  else return false;
897 }
898 
899 bool IsNeutralMeson(int pdg_id) {
900  /* std::cout << Form("Entering IsNeutralMeson(%d)\n", pdg_id); */
901  // excited states are >3 digit numbers; first reduce them to the base quark content
902  int base_id = pdg_id % 1000;
903  // meson ids are 3-digit numbers
904  // the last digit is the angular momentum state
905  // the first two digits are the quark flavors
906  int q1 = (int)(base_id/100);
907  int q2 = (int)(base_id/10 % 10);
908  float charge = 0.;
909  if (q1%2 == 0) charge += 2./3.;
910  else charge -= 1./3.;
911  if (q2%2 == 0) charge -= 2./3.;
912  else charge += 1./3.;
913  /* std::cout << Form("In IsNeutralMeson: base_id=%d, charge=%f\n", base_id, charge); */
914  if (abs(charge) < 0.05) return true;
915  else return false;
916 }
917 
918 bool IsNeutralHadron(int pdg_id) {
919  /* std::cout << Form("\nEntering IsNeutralHadron(%d)\n", pdg_id); */
920  bool ret = (IsNeutralBaryon(pdg_id) || IsNeutralMeson(pdg_id));
921  /* std::cout << Form("In IsNeutralHadron: returning %s\n", ret ? "true" : "false"); */
922  return ret;
923 }
924 
925 void pythiaEMCalAna::addPrimaryFromGeant(PHG4Particle* part, PHG4TruthInfoContainer* truthInfo, CaloRawClusterEval* caloEval, HepMC::GenEvent* theEvent) {
926  TLorentzVector truth_momentum;
927  truth_momentum.SetPxPyPzE(part->get_px(), part->get_py(), part->get_pz(), part->get_e());
928  if (! withinAcceptance(part)) return;
929  int this_id = part->get_track_id();
930 
931  PHG4VtxPoint* end_vtx = getG4EndVtx(this_id, truthInfo);
932  if (!end_vtx) {
933  std::cout << "\nGreg info: no end vertex found for Geant-decayed primary:\n";
934  part->identify();
935  std::cout << Form("Mass=%f, pT=%f\n\n", truth_momentum.M(), truth_momentum.Pt());
936  return;
937  }
938 
939  n_primaries++;
940 
941  /* int embedID = truthInfo->isEmbeded(part->get_track_id()); */
942  /* m_truthBarcode.push_back(std::pair<int,int>(embedID, part->get_barcode())); */
943  /* m_truthParentBarcode.push_back(std::pair<int,int>(embedID, 0)); */
944  if (part->get_pid() == 22) {
945  /* n_primary_photons++; */
946  // check for direct photons is done in process_event
948  }
949  if (abs(part->get_pid()) < 20) n_leptons++;
950  if (abs(part->get_pid()) > 100) {
951  if (IsNeutralHadron(abs(part->get_pid()))) {
954  }
955  else {
958  }
959  }
960 
961  m_truthIsPrimary.push_back(1);
962  m_truthTrackID.push_back(this_id);
963  m_truthPid.push_back(part->get_pid());
964 
965  m_truthE.push_back(truth_momentum.E());
966  m_truthEta.push_back(truth_momentum.PseudoRapidity());
967  m_truthPhi.push_back(truth_momentum.Phi());
968  m_truthPt.push_back(truth_momentum.Pt());
969  m_truthMass.push_back(truth_momentum.M());
970 
971  m_truthEndVtx_x.push_back(end_vtx->get_x());
972  m_truthEndVtx_y.push_back(end_vtx->get_y());
973  m_truthEndVtx_z.push_back(end_vtx->get_z());
974  m_truthEndVtx_t.push_back(end_vtx->get_t());
975  float x = end_vtx->get_x();
976  float y = end_vtx->get_y();
977  float r = sqrt(x*x + y*y);
978  m_truthEndVtx_r.push_back(r);
979 
980  std::vector<float> allClusterIDs;
981 
982  std::set<RawCluster*> clusters = caloEval->all_clusters_from(part);
983  for (auto& cl : clusters) {
984  allClusterIDs.push_back(cl->get_id());
985  }
986  m_truth_all_clusterIDs.push_back(allClusterIDs);
987 }
988 
989 
990 void pythiaEMCalAna::addPrimaryFromPythia(HepMC::GenParticle* part) {
991  /* std::cout << "Entering pythiaEMCalAna::addPrimaryFromPythia\npart=" << part << "\n"; */
992  HepMC::FourVector mom = part->momentum();
993  TLorentzVector truth_momentum;
994  truth_momentum.SetPxPyPzE(mom.px(), mom.py(), mom.pz(), mom.e());
995  if (! withinAcceptance(part)) return;
996 
997  pythiaBarcodes.insert(part->barcode());
998  n_primaries++;
1000  if (IsNeutralHadron(abs(part->pdg_id()))) {
1003  }
1004  else {
1007  }
1008 
1009  m_truthIsPrimary.push_back(1);
1010  // no track ID available from pythia
1011  m_truthTrackID.push_back(-999);
1012  m_truthPid.push_back(part->pdg_id());
1013 
1014  m_truthE.push_back(truth_momentum.E());
1015  m_truthEta.push_back(truth_momentum.PseudoRapidity());
1016  m_truthPhi.push_back(truth_momentum.Phi());
1017  m_truthPt.push_back(truth_momentum.Pt());
1018  m_truthMass.push_back(truth_momentum.M());
1019 
1020  /* std::cout << "Getting end vertex\n"; */
1021  HepMC::GenVertex* end_vtx = part->end_vertex();
1022  assert(end_vtx);
1023  /* std::cout << "Found end vertex in pythia\n"; */
1024  HepMC::FourVector position = end_vtx->position();
1025 
1026  m_truthEndVtx_x.push_back(position.x());
1027  m_truthEndVtx_y.push_back(position.y());
1028  m_truthEndVtx_z.push_back(position.z());
1029  m_truthEndVtx_t.push_back(position.t());
1030  float x = position.x();
1031  float y = position.y();
1032  float r = sqrt(x*x + y*y);
1033  /* std::cout << Form("pythiaEMCalAna::addPrimaryFromPythia(): Vertex r=%f, perp=%f\n", r, position.perp()); */
1034  m_truthEndVtx_r.push_back(r);
1035 
1036  // no cluster matching available from pythia
1037  std::vector<float> allClusterIDs;
1038  m_truth_all_clusterIDs.push_back(allClusterIDs);
1039 }
1040 
1041 bool pythiaEMCalAna::isDirectPhoton(PHG4Particle* part, HepMC::GenEvent* theEvent) {
1042  /* std::cout << "\tGreg info: entering isDirectPhoton(). "; */
1043  /* std::cout << "G4 particle is " << part << ", barcode " << part->get_barcode() << "\n";//; printing info\n"; */
1044  /* part->identify(); */
1045 
1046  // Only bother with this check if we have PYTHIA information
1047  // Otherwise assume any photon is a "direct" photon, since we can't tell from HIJING alone
1048  if (!hasPYTHIA) return (part->get_pid() == 22);
1049  HepMC::GenParticle* genpart = getGenParticle(part->get_barcode(), theEvent);
1050  if (!genpart) {
1051  std::cout << "\t\tGreg info: in isDirectPhoton(), could not find pythia particle with barcode " << part->get_barcode() << "; returning true. (This may be an error!)\n";
1052  return true;
1053  }
1054  assert(genpart);
1055  /* std::cout << "\tFound corresponding pythia particle; printing info\t"; */
1056  /* genpart->print(); */
1057  /* else std::cout << "Greg info: found corresponding pythia photon (" << genpart << ")\n"; */
1058  HepMC::GenVertex* prod_vtx = genpart->production_vertex();
1059  if (prod_vtx->particles_in_size() == 1) {
1060  HepMC::GenVertex::particles_in_const_iterator parent = prod_vtx->particles_in_const_begin();
1061  assert((*parent));
1062  // parent's status and pdg_id tell us whether it's a direct photon
1063  // or a decay photon
1064  if ((*parent)->status() > 2 && abs((*parent)->pdg_id()) < 100) {
1065  // direct photon
1066  /* std::cout << "\nGreg info: found a direct photon. Photon:\n"; */
1067  /* genpart->print(); */
1068  bool printHistory = false;
1069  if (printHistory) {
1070  // print history of all ancestors
1071  // generation 0 is genpart, gen -1 is its parent, etc.
1072  int generation = -1;
1073  std::cout << "\tGeneration " << generation << " -- ";
1074  (*parent)->print();
1075  while (true) {
1076  generation--;
1077  HepMC::GenVertex::particles_in_const_iterator parentparent;
1078  HepMC::GenVertex* parent_prod_vtx = (*parent)->production_vertex();
1079  if (parent_prod_vtx) {
1080  parentparent = parent_prod_vtx->particles_in_const_begin();
1081  std::cout << "\tGeneration " << generation << ": ";
1082  (*parentparent)->print();
1083  parent = parentparent;
1084  }
1085  else break;
1086  }
1087  parent = prod_vtx->particles_in_const_begin(); // reset parent to genpart's actual parent
1088  }
1089  return true;
1090  }
1091  else if ((*parent)->status() == 2 && abs((*parent)->pdg_id()) >= 100) {
1092  // decay photon
1093  /* std::cout << "\nGreg info: found a decay photon. Photon:\n"; */
1094  /* genpart->print(); */
1095  /* std::cout << "Parent:\n"; */
1096  /* (*parent)->print(); */
1097  /* std::cout << "\n"; */
1098  return false;
1099  }
1100  else {
1101  // weird case??
1102  std::cout << "\nGreg info: weird combination of photon or parent status or PID... photon:\n";
1103  genpart->print();
1104  std::cout << "Parent:\n";
1105  (*parent)->print();
1106  std::cout << "\n";
1107  return false;
1108  }
1109  } // single parent check
1110  else {
1111  // weird photon -- they should only have 1 parent
1112  std::cout << "Greg info: found a photon with " << prod_vtx->particles_in_size() << " parent(s). Photon:\n";
1113  genpart->print();
1114  for (HepMC::GenVertex::particles_in_const_iterator parent = prod_vtx->particles_in_const_begin(); parent != prod_vtx->particles_in_const_end(); parent++) {
1115  std::cout << "Parent:\n";
1116  (*parent)->print();
1117  }
1118  /* std::cout << "\n"; */
1119  return false;
1120  }
1121 }
1122 
1123 HepMC::GenParticle* pythiaEMCalAna::getGenParticle(int barcode, HepMC::GenEvent* theEvent) {
1124  /* std::cout << "Greg info: in getGenParticle, looking for barcode " << barcode << "\n"; */
1125  for(HepMC::GenEvent::particle_const_iterator p=theEvent->particles_begin(); p!=theEvent->particles_end(); ++p)
1126  {
1127  assert(*p);
1128  /* std::cout << "\tpythia barcode " << (*p)->barcode() << "\n"; */
1129  /* if ((*p)->barcode() == 33) { */
1130  /* std::cout << "barcode 33 details: \t"; */
1131  /* (*p)->print(); */
1132  /* } */
1133  if ( (*p)->barcode() == barcode ) {
1134  // found the right particle
1135  return (*p);
1136  }
1137  }
1138  // reached end of loop... if we still haven't found the right particle,
1139  // we have a problem
1140  std::cout << "\t\tGreg info: in getGenParticle(), could not find correct generated particle!\n";
1141  return nullptr;
1142 }
1143 
1145  float max_eta = 1.1;
1146  float min_E = 1.0;
1147  TLorentzVector truth_momentum;
1148  truth_momentum.SetPxPyPzE(part->get_px(), part->get_py(), part->get_pz(), part->get_e());
1149  float eta = truth_momentum.PseudoRapidity();
1150  if (abs(eta) > max_eta) return false;
1151  if (truth_momentum.E() < min_E) return false;
1152  else return true;
1153 }
1154 
1155 bool pythiaEMCalAna::withinAcceptance(HepMC::GenParticle* part) {
1156  float max_eta = 1.1;
1157  float min_E = 1.0;
1158  HepMC::FourVector mom = part->momentum();
1159  TLorentzVector truth_momentum;
1160  truth_momentum.SetPxPyPzE(mom.px(), mom.py(), mom.pz(), mom.e());
1161  float eta = truth_momentum.PseudoRapidity();
1162  if (abs(eta) > max_eta) return false;
1163  if (truth_momentum.E() < min_E) return false;
1164  else return true;
1165 }
1166 
1168  PHG4VtxPoint* end_vtx = nullptr;
1169  PHG4TruthInfoContainer::Range truthRange = truthInfo->GetSecondaryParticleRange();
1171  for(truthIter = truthRange.first; truthIter != truthRange.second; truthIter++)
1172  {
1173  PHG4Particle *decayPar = truthIter->second;
1174  int parent_id = decayPar->get_parent_id();
1175  if (parent_id == id) {
1176  end_vtx = truthInfo->GetVtx(decayPar->get_vtx_id());
1177  break;
1178  }
1179  }
1180  if (!end_vtx) {
1181  // couldn't find any daughter particles in secondary list
1182  // check primary list instead??
1183  truthRange = truthInfo->GetPrimaryParticleRange();
1184  for(truthIter = truthRange.first; truthIter != truthRange.second; truthIter++)
1185  {
1186  PHG4Particle *decayPar = truthIter->second;
1187  int parent_id = decayPar->get_parent_id();
1188  if (parent_id == id) {
1189  std::cout << "\tGreg info: found daughter in *primary* particle range!\n";
1190  end_vtx = truthInfo->GetVtx(decayPar->get_vtx_id());
1191  break;
1192  }
1193  }
1194  }
1195  return end_vtx;
1196 }
1197 
1198 // Old stuff
1199 
1200 /* void pythiaEMCalAna::addDirectPhoton(PHG4Particle* part, PHG4TruthInfoContainer* truthInfo) { */
1201 /* /1* std::cout << "Found a direct photon!\n"; *1/ */
1202 /* TLorentzVector truth_momentum; */
1203 /* truth_momentum.SetPxPyPzE(part->get_px(), part->get_py(), part->get_pz(), part->get_e()); */
1204 /* if (! withinAcceptance(part)) return; */
1205 /* /1* std::cout << "\tIs within acceptance!\n"; *1/ */
1206 /* /1* part->identify(); *1/ */
1207 /* int this_id = part->get_track_id(); */
1208 
1209 /* PHG4VtxPoint* end_vtx = getG4EndVtx(this_id, truthInfo); */
1210 /* if (!end_vtx) { */
1211 /* std::cout << "\nGreg info: no end vertex found for direct photon:\n"; */
1212 /* part->identify(); */
1213 /* std::cout << Form("Mass=%f, pT=%f\n\n", truth_momentum.M(), truth_momentum.Pt()); */
1214 /* return; */
1215 /* } */
1216 
1217 /* int embedID = truthInfo->isEmbeded(part->get_track_id()); */
1218 /* m_truthBarcode.push_back(std::pair<int,int>(embedID, part->get_barcode())); */
1219 /* m_truthParentBarcode.push_back(std::pair<int,int>(embedID, 0)); */
1220 /* m_truthIsPrimary.push_back(1); */
1221 /* m_truthPid.push_back(part->get_pid()); */
1222 
1223 /* /1* TLorentzVector truth_momentum; *1/ */
1224 /* /1* truth_momentum.SetPxPyPzE(part->get_px(), part->get_py(), part->get_pz(), part->get_e()); *1/ */
1225 /* m_truthE.push_back(truth_momentum.E()); */
1226 /* m_truthEta.push_back(truth_momentum.PseudoRapidity()); */
1227 /* m_truthPhi.push_back(truth_momentum.Phi()); */
1228 /* m_truthPt.push_back(truth_momentum.Pt()); */
1229 /* m_truthMass.push_back(truth_momentum.M()); */
1230 
1231 /* // part->get_vtx_id() gives the *production* vertex, not the end vertex */
1232 /* /1* PHG4VtxPoint* end_vtx = truthInfo->GetVtx(part->get_vtx_id()); // DOES NOT WORK *1/ */
1233 /* // get the end vertex from one of the daughter particles */
1234 /* /1* int this_id = part->get_track_id(); *1/ */
1235 /* /1* std::cout << "this_id = " << this_id << "; getting end vertex\n"; *1/ */
1236 /* /1* PHG4VtxPoint* end_vtx = getG4EndVtx(this_id, truthInfo); *1/ */
1237 /* /1* std::cout << "end_vtx = " << end_vtx << "\n"; *1/ */
1238 /* assert(end_vtx); */
1239 /* m_truthEndVtx_x.push_back(end_vtx->get_x()); */
1240 /* m_truthEndVtx_y.push_back(end_vtx->get_y()); */
1241 /* m_truthEndVtx_z.push_back(end_vtx->get_z()); */
1242 /* m_truthEndVtx_t.push_back(end_vtx->get_t()); */
1243 /* float x = end_vtx->get_x(); */
1244 /* float y = end_vtx->get_y(); */
1245 /* float r = sqrt(x*x + y*y); */
1246 /* m_truthEndVtx_r.push_back(r); */
1247 
1248 /* /1* primaryBarcodes.push_back(part->get_barcode()); *1/ */
1249 /* } */
1250 
1251 /* void pythiaEMCalAna::addDecayPhoton(PHG4Particle* part, PHG4TruthInfoContainer* truthInfo, HepMC::GenEvent* theEvent) { */
1252 /* TLorentzVector truth_momentum; */
1253 /* truth_momentum.SetPxPyPzE(part->get_px(), part->get_py(), part->get_pz(), part->get_e()); */
1254 /* if (! withinAcceptance(part)) return; */
1255 /* int this_id = part->get_track_id(); */
1256 
1257 /* PHG4VtxPoint* end_vtx = getG4EndVtx(this_id, truthInfo); */
1258 /* if (!end_vtx) { */
1259 /* /1* std::cout << "\nGreg info: no end vertex found for decay photon:\n"; *1/ */
1260 /* /1* part->identify(); *1/ */
1261 /* /1* std::cout << Form("Mass=%f, pT=%f\n\n", truth_momentum.M(), truth_momentum.Pt()); *1/ */
1262 /* return; */
1263 /* } */
1264 
1265 /* int parent_barcode; */
1266 /* // If Geant handled the decay, we can get the parent directly */
1267 /* PHG4Particle* geant_parent = truthInfo->GetParticle(part->get_parent_id()); */
1268 /* if (geant_parent) { */
1269 /* parent_barcode = geant_parent->get_barcode(); */
1270 /* } */
1271 /* else { */
1272 /* // pythia handled the decay, so get the parent from there */
1273 /* HepMC::GenParticle* pho = getGenParticle(part->get_barcode(), theEvent); */
1274 /* assert(pho); */
1275 /* HepMC::GenVertex* prod_vtx = pho->production_vertex(); */
1276 /* if (prod_vtx->particles_in_size() == 1) { */
1277 /* HepMC::GenVertex::particles_in_const_iterator pythia_parent = prod_vtx->particles_in_const_begin(); */
1278 /* assert((*pythia_parent)); */
1279 /* parent_barcode = (*pythia_parent)->barcode(); */
1280 /* } */
1281 /* else { */
1282 /* std::cout << "Greg info: pythia-decayed photon with " << prod_vtx->particles_in_size() << " parents. Skipping...\n"; */
1283 /* return; */
1284 /* } */
1285 /* } // done getting parent barcode */
1286 
1287 /* /1* std::cout << "Adding decay photon with barcode " << part->get_barcode() << "; geant_parent is " << geant_parent << "\n"; *1/ */
1288 /* int embedID = truthInfo->isEmbeded(part->get_track_id()); */
1289 /* m_truthBarcode.push_back(std::pair<int,int>(embedID, part->get_barcode())); */
1290 /* m_truthParentBarcode.push_back(std::pair<int,int>(embedID, parent_barcode)); */
1291 /* m_truthIsPrimary.push_back(0); */
1292 /* m_truthPid.push_back(part->get_pid()); */
1293 
1294 /* /1* TLorentzVector truth_momentum; *1/ */
1295 /* /1* truth_momentum.SetPxPyPzE(part->get_px(), part->get_py(), part->get_pz(), part->get_e()); *1/ */
1296 /* m_truthE.push_back(truth_momentum.E()); */
1297 /* m_truthEta.push_back(truth_momentum.PseudoRapidity()); */
1298 /* m_truthPhi.push_back(truth_momentum.Phi()); */
1299 /* m_truthPt.push_back(truth_momentum.Pt()); */
1300 /* m_truthMass.push_back(truth_momentum.M()); */
1301 
1302 /* // part->get_vtx_id() gives the *production* vertex, not the end vertex */
1303 /* /1* PHG4VtxPoint* end_vtx = truthInfo->GetVtx(part->get_vtx_id()); // DOES NOT WORK *1/ */
1304 /* // get the end vertex from one of the daughter particles */
1305 /* /1* int this_id = part->get_track_id(); *1/ */
1306 /* /1* std::cout << "this_id = " << this_id << "; getting end vertex\n"; *1/ */
1307 /* /1* PHG4VtxPoint* end_vtx = getG4EndVtx(this_id, truthInfo); *1/ */
1308 /* /1* std::cout << "end_vtx = " << end_vtx << "\n"; *1/ */
1309 /* assert(end_vtx); */
1310 /* m_truthEndVtx_x.push_back(end_vtx->get_x()); */
1311 /* m_truthEndVtx_y.push_back(end_vtx->get_y()); */
1312 /* m_truthEndVtx_z.push_back(end_vtx->get_z()); */
1313 /* m_truthEndVtx_t.push_back(end_vtx->get_t()); */
1314 /* float x = end_vtx->get_x(); */
1315 /* float y = end_vtx->get_y(); */
1316 /* float r = sqrt(x*x + y*y); */
1317 /* m_truthEndVtx_r.push_back(r); */
1318 
1319 /* /1* secondaryBarcodes.push_back(part->get_barcode()); *1/ */
1320 /* } */
1321 
1322 /* void pythiaEMCalAna::addPrimaryHadronFromPythia(HepMC::GenParticle* part, int embedID) { */
1323 /* // case where PYTHIA handles the decay and Geant never knows about the primary */
1324 /* HepMC::FourVector mom = part->momentum(); */
1325 /* TLorentzVector truth_momentum; */
1326 /* truth_momentum.SetPxPyPzE(mom.px(), mom.py(), mom.pz(), mom.e()); */
1327 /* if (! withinAcceptance(part)) return; */
1328 /* HepMC::GenVertex* end_vtx = part->end_vertex(); */
1329 /* if (!end_vtx) { */
1330 /* std::cout << "\nGreg info: no end vertex found for Pythia-decayed primary:\n"; */
1331 /* part->print(); */
1332 /* std::cout << Form("Mass=%f, pT=%f\n\n", truth_momentum.M(), truth_momentum.Pt()); */
1333 /* return; */
1334 /* } */
1335 
1336 /* m_truthBarcode.push_back(std::pair<int,int>(embedID, part->barcode())); */
1337 /* m_truthParentBarcode.push_back(std::pair<int,int>(embedID, 0)); */
1338 /* m_truthIsPrimary.push_back(1); */
1339 /* m_truthPid.push_back(part->pdg_id()); */
1340 /* if (part->pdg_id() == 22) std::cout << "Greg info: primary in addPrimaryHadronFromPythia is a photon!\n"; */
1341 
1342 /* /1* TLorentzVector truth_momentum; *1/ */
1343 /* /1* truth_momentum.SetPxPyPzE(part->get_px(), part->get_py(), part->get_pz(), part->get_e()); *1/ */
1344 /* m_truthE.push_back(truth_momentum.E()); */
1345 /* m_truthEta.push_back(truth_momentum.PseudoRapidity()); */
1346 /* m_truthPhi.push_back(truth_momentum.Phi()); */
1347 /* m_truthPt.push_back(truth_momentum.Pt()); */
1348 /* m_truthMass.push_back(truth_momentum.M()); */
1349 
1350 /* assert(end_vtx); */
1351 /* HepMC::FourVector position = end_vtx->position(); */
1352 
1353 /* m_truthEndVtx_x.push_back(position.x()); */
1354 /* m_truthEndVtx_y.push_back(position.y()); */
1355 /* m_truthEndVtx_z.push_back(position.z()); */
1356 /* m_truthEndVtx_t.push_back(position.t()); */
1357 /* float x = position.x(); */
1358 /* float y = position.y(); */
1359 /* float r = sqrt(x*x + y*y); */
1360 /* /1* std::cout << Form("pythiaEMCalAna::addPrimaryFromPythia(): Vertex r=%f, perp=%f\n", r, position.perp()); *1/ */
1361 /* m_truthEndVtx_r.push_back(r); */
1362 
1363 /* /1* primaryBarcodes.push_back(part->barcode()); *1/ */
1364 /* } */
1365 
1366 /* void pythiaEMCalAna::addPrimaryHadronFromGeant(PHG4Particle* part, PHG4TruthInfoContainer* truthInfo) { */
1367 /* // case where Geant handles the decay */
1368 /* TLorentzVector truth_momentum; */
1369 /* truth_momentum.SetPxPyPzE(part->get_px(), part->get_py(), part->get_pz(), part->get_e()); */
1370 /* if (! withinAcceptance(part)) return; */
1371 /* int this_id = part->get_track_id(); */
1372 
1373 /* PHG4VtxPoint* end_vtx = getG4EndVtx(this_id, truthInfo); */
1374 /* if (!end_vtx) { */
1375 /* std::cout << "\nGreg info: no end vertex found for Geant-decayed primary:\n"; */
1376 /* part->identify(); */
1377 /* std::cout << Form("Mass=%f, pT=%f\n\n", truth_momentum.M(), truth_momentum.Pt()); */
1378 /* return; */
1379 /* } */
1380 
1381 /* int embedID = truthInfo->isEmbeded(part->get_track_id()); */
1382 /* m_truthBarcode.push_back(std::pair<int,int>(embedID, part->get_barcode())); */
1383 /* m_truthParentBarcode.push_back(std::pair<int,int>(embedID, 0)); */
1384 /* m_truthIsPrimary.push_back(1); */
1385 /* m_truthPid.push_back(part->get_pid()); */
1386 /* if (part->get_pid() == 22) std::cout << "Greg info: primary in addPrimaryHadronFromGeant is a photon!\n"; */
1387 
1388 /* /1* TLorentzVector truth_momentum; *1/ */
1389 /* /1* truth_momentum.SetPxPyPzE(part->get_px(), part->get_py(), part->get_pz(), part->get_e()); *1/ */
1390 /* m_truthE.push_back(truth_momentum.E()); */
1391 /* m_truthEta.push_back(truth_momentum.PseudoRapidity()); */
1392 /* m_truthPhi.push_back(truth_momentum.Phi()); */
1393 /* m_truthPt.push_back(truth_momentum.Pt()); */
1394 /* m_truthMass.push_back(truth_momentum.M()); */
1395 
1396 /* assert(end_vtx); */
1397 /* m_truthEndVtx_x.push_back(end_vtx->get_x()); */
1398 /* m_truthEndVtx_y.push_back(end_vtx->get_y()); */
1399 /* m_truthEndVtx_z.push_back(end_vtx->get_z()); */
1400 /* m_truthEndVtx_t.push_back(end_vtx->get_t()); */
1401 /* float x = end_vtx->get_x(); */
1402 /* float y = end_vtx->get_y(); */
1403 /* float r = sqrt(x*x + y*y); */
1404 /* m_truthEndVtx_r.push_back(r); */
1405 
1406 /* /1* primaryBarcodes.push_back(part->get_barcode()); *1/ */
1407 /* } */
1408 
1409 /* void pythiaEMCalAna::addSecondaryFromPythia(HepMC::GenParticle* part) { */
1410 /* /1* std::cout << "Entering pythiaEMCalAna::addSecondaryFromPythia\npart=" << part << "\n"; *1/ */
1411 /* HepMC::FourVector mom = part->momentum(); */
1412 /* TLorentzVector truth_momentum; */
1413 /* truth_momentum.SetPxPyPzE(mom.px(), mom.py(), mom.pz(), mom.e()); */
1414 /* float eta = truth_momentum.PseudoRapidity(); */
1415 /* if (abs(eta) > 1.1) return; */
1416 
1417 /* HepMC::GenVertex* prod_vtx = (*p)->production_vertex(); */
1418 /* HepMC::GenVertex::particles_in_const_iterator parent; */
1419 /* if (prod_vtx->particles_in_size() == 1) { */
1420 /* parent = prod_vtx->particles_in_const_begin(); */
1421 /* } */
1422 /* else { */
1423 /* std::cout << "Greg info: found a weird decay photon in pythia. Has " << prod_vtx->particles_in_size() << " parents. Skipping this photon!\n"; */
1424 /* return; */
1425 /* } */
1426 
1427 /* m_truthBarcode.push_back(part->barcode()); */
1428 /* m_truthParentBarcode.push_back((*parent)->barcode()); */
1429 /* m_truthIsPrimary.push_back(0); */
1430 /* m_truthPid.push_back(part->pdg_id()); */
1431 
1432 /* /1* std::cout << "Getting momentum\n"; *1/ */
1433 /* /1* HepMC::FourVector mom = part->momentum(); *1/ */
1434 /* /1* TLorentzVector truth_momentum; *1/ */
1435 /* /1* truth_momentum.SetPxPyPzE(mom.px(), mom.py(), mom.pz(), mom.e()); *1/ */
1436 /* m_truthE.push_back(truth_momentum.E()); */
1437 /* m_truthEta.push_back(truth_momentum.PseudoRapidity()); */
1438 /* m_truthPhi.push_back(truth_momentum.Phi()); */
1439 /* m_truthPt.push_back(truth_momentum.Pt()); */
1440 /* m_truthMass.push_back(truth_momentum.M()); */
1441 
1442 /* /1* std::cout << "Getting end vertex\n"; *1/ */
1443 /* HepMC::GenVertex* end_vtx = part->end_vertex(); */
1444 /* assert(end_vtx); */
1445 /* /1* std::cout << "Found end vertex in pythia\n"; *1/ */
1446 /* HepMC::FourVector position = end_vtx->position(); */
1447 
1448 /* m_truthEndVtx_x.push_back(position.x()); */
1449 /* m_truthEndVtx_y.push_back(position.y()); */
1450 /* m_truthEndVtx_z.push_back(position.z()); */
1451 /* m_truthEndVtx_t.push_back(position.t()); */
1452 /* float x = position.x(); */
1453 /* float y = position.y(); */
1454 /* float r = sqrt(x*x + y*y); */
1455 /* /1* std::cout << Form("pythiaEMCalAna::addPrimaryFromPythia(): Vertex r=%f, perp=%f\n", r, position.perp()); *1/ */
1456 /* m_truthEndVtx_r.push_back(r); */
1457 
1458 /* primaryBarcodes.push_back(part->barcode()); */
1459 /* } */
1460 
1461 /* void pythiaEMCalAna::addPrimaryFromGeant(PHG4Particle* part, PHG4TruthInfoContainer* truthInfo) { */
1462  /* /1* std::cout << "Entering pythiaEMCalAna::addPrimaryFromGeant\npart=" << part << "\n"; *1/ */
1463  /* /1* part->identify(); *1/ */
1464  /* /1* std::cout << "Barcode is " << part->get_barcode() << "\n"; *1/ */
1465  /* /1* int vtx_id = part->get_vtx_id(); *1/ */
1466  /* /1* std::cout << "vertex id is " << vtx_id << "\n"; *1/ */
1467  /* /1* PHG4VtxPoint* vtxpt = truthInfo->GetVtx(vtx_id); *1/ */
1468  /* /1* vtxpt->identify(); *1/ */
1469  /* TLorentzVector truth_momentum; */
1470  /* truth_momentum.SetPxPyPzE(part->get_px(), part->get_py(), part->get_pz(), part->get_e()); */
1471  /* float eta = truth_momentum.PseudoRapidity(); */
1472  /* if (abs(eta) > 1.1) return; */
1473  /* int this_id = part->get_track_id(); */
1474  /* PHG4VtxPoint* end_vtx = getG4EndVtx(this_id, truthInfo); */
1475  /* if (!end_vtx) { */
1476  /* /1* std::cout << "\nGreg info: no end vertex found for primary particle:\n"; *1/ */
1477  /* /1* part->identify(); *1/ */
1478  /* /1* std::cout << Form("Mass=%f, pT=%f\n\n", truth_momentum.M(), truth_momentum.Pt()); *1/ */
1479  /* return; */
1480  /* } */
1481 
1482  /* m_truthBarcode.push_back(part->get_barcode()); */
1483  /* m_truthParentBarcode.push_back(0); */
1484  /* m_truthIsPrimary.push_back(1); */
1485  /* m_truthPid.push_back(part->get_pid()); */
1486 
1487  /* /1* TLorentzVector truth_momentum; *1/ */
1488  /* /1* truth_momentum.SetPxPyPzE(part->get_px(), part->get_py(), part->get_pz(), part->get_e()); *1/ */
1489  /* m_truthE.push_back(truth_momentum.E()); */
1490  /* m_truthEta.push_back(truth_momentum.PseudoRapidity()); */
1491  /* m_truthPhi.push_back(truth_momentum.Phi()); */
1492  /* m_truthPt.push_back(truth_momentum.Pt()); */
1493  /* m_truthMass.push_back(truth_momentum.M()); */
1494 
1495  /* // part->get_vtx_id() gives the *production* vertex, not the end vertex */
1496  /* /1* PHG4VtxPoint* end_vtx = truthInfo->GetVtx(part->get_vtx_id()); // DOES NOT WORK *1/ */
1497  /* // get the end vertex from one of the daughter particles */
1498  /* /1* int this_id = part->get_track_id(); *1/ */
1499  /* /1* std::cout << "this_id = " << this_id << "; getting end vertex\n"; *1/ */
1500  /* /1* PHG4VtxPoint* end_vtx = getG4EndVtx(this_id, truthInfo); *1/ */
1501  /* /1* std::cout << "end_vtx = " << end_vtx << "\n"; *1/ */
1502  /* assert(end_vtx); */
1503  /* m_truthEndVtx_x.push_back(end_vtx->get_x()); */
1504  /* m_truthEndVtx_y.push_back(end_vtx->get_y()); */
1505  /* m_truthEndVtx_z.push_back(end_vtx->get_z()); */
1506  /* m_truthEndVtx_t.push_back(end_vtx->get_t()); */
1507  /* float x = end_vtx->get_x(); */
1508  /* float y = end_vtx->get_y(); */
1509  /* float r = sqrt(x*x + y*y); */
1510  /* m_truthEndVtx_r.push_back(r); */
1511 
1512  /* primaryBarcodes.push_back(part->get_barcode()); */
1513 /* } */
1514 
1515 /* void pythiaEMCalAna::addSecondaryFromGeant(PHG4Particle* part, PHG4TruthInfoContainer* truthInfo) { */
1516 /* /1* std::cout << "Entering pythiaEMCalAna::addSecondary(), geant particle is " << part << "\n"; *1/ */
1517 /* TLorentzVector truth_momentum; */
1518 /* truth_momentum.SetPxPyPzE(part->get_px(), part->get_py(), part->get_pz(), part->get_e()); */
1519 /* float eta = truth_momentum.PseudoRapidity(); */
1520 /* if (abs(eta) > 1.1) return; */
1521 /* /1* std::cout << "Done checking eta\n"; *1/ */
1522 /* int this_id = part->get_track_id(); */
1523 /* PHG4VtxPoint* end_vtx = getG4EndVtx(this_id, truthInfo); */
1524 /* if (!end_vtx) { */
1525 /* /1* std::cout << "\n\nGreg info: no end vertex found for secondary particle:\n"; *1/ */
1526 /* /1* part->identify(); *1/ */
1527 /* /1* std::cout << "Particle eta=" << eta << "\n"; *1/ */
1528 /* return; */
1529 /* } */
1530 /* /1* std::cout << "Done checking end_vtx\n"; *1/ */
1531 
1532 /* m_truthBarcode.push_back(part->get_barcode()); */
1533 /* PHG4Particle* parent = truthInfo->GetParticle(part->get_parent_id()); */
1534 /* m_truthParentBarcode.push_back(parent->get_barcode()); */
1535 /* m_truthIsPrimary.push_back(0); */
1536 /* m_truthPid.push_back(part->get_pid()); */
1537 /* /1* std::cout << "Done adding pid to vector\n"; *1/ */
1538 
1539 /* /1* TLorentzVector truth_momentum; *1/ */
1540 /* /1* truth_momentum.SetPxPyPzE(part->get_px(), part->get_py(), part->get_pz(), part->get_e()); *1/ */
1541 /* m_truthE.push_back(truth_momentum.E()); */
1542 /* m_truthEta.push_back(truth_momentum.PseudoRapidity()); */
1543 /* m_truthPhi.push_back(truth_momentum.Phi()); */
1544 /* m_truthPt.push_back(truth_momentum.Pt()); */
1545 /* m_truthMass.push_back(truth_momentum.M()); */
1546 /* /1* std::cout << "Done adding kinematics to vector\n"; *1/ */
1547 
1548 /* /1* std::cout << "Asserting end_vtx= " << end_vtx << "\n"; *1/ */
1549 /* assert(end_vtx); */
1550 /* m_truthEndVtx_x.push_back(end_vtx->get_x()); */
1551 /* m_truthEndVtx_y.push_back(end_vtx->get_y()); */
1552 /* m_truthEndVtx_z.push_back(end_vtx->get_z()); */
1553 /* m_truthEndVtx_t.push_back(end_vtx->get_t()); */
1554 /* float x = end_vtx->get_x(); */
1555 /* float y = end_vtx->get_y(); */
1556 /* float r = sqrt(x*x + y*y); */
1557 /* m_truthEndVtx_r.push_back(r); */
1558 /* /1* std::cout << "Done adding vertex to vector\n"; *1/ */
1559 
1560 /* secondaryBarcodes.push_back(part->get_barcode()); */
1561 /* } */
1562 
1563 /* void pythiaEMCalAna::addSecondaryWithoutParent(PHG4Particle* part, PHG4TruthInfoContainer* truthInfo, HepMC::GenParticle* genParent) { */
1564 /* /1* std::cout << "Entering pythiaEMCalAna::addSecondaryWithoutParent(), geant particle is " << part << ", pythia particle is " << genParent << "\n"; *1/ */
1565 /* TLorentzVector truth_momentum; */
1566 /* truth_momentum.SetPxPyPzE(part->get_px(), part->get_py(), part->get_pz(), part->get_e()); */
1567 /* float eta = truth_momentum.PseudoRapidity(); */
1568 /* if (abs(eta) > 1.1) return; */
1569 /* /1* std::cout << "Done checking eta\n"; *1/ */
1570 /* int this_id = part->get_track_id(); */
1571 /* PHG4VtxPoint* end_vtx = getG4EndVtx(this_id, truthInfo); */
1572 /* if (!end_vtx) { */
1573 /* /1* std::cout << "\n\nGreg info: no end vertex found for secondary particle:\n"; *1/ */
1574 /* /1* part->identify(); *1/ */
1575 /* /1* std::cout << "Particle eta=" << eta << "\n"; *1/ */
1576 /* return; */
1577 /* } */
1578 /* /1* std::cout << "Done checking end_vtx\n"; *1/ */
1579 
1580 /* m_truthBarcode.push_back(part->get_barcode()); */
1581 /* m_truthParentBarcode.push_back(genParent->barcode()); */
1582 /* m_truthIsPrimary.push_back(0); */
1583 /* m_truthPid.push_back(part->get_pid()); */
1584 /* /1* std::cout << "Done adding pid to vector\n"; *1/ */
1585 
1586 /* /1* TLorentzVector truth_momentum; *1/ */
1587 /* /1* truth_momentum.SetPxPyPzE(part->get_px(), part->get_py(), part->get_pz(), part->get_e()); *1/ */
1588 /* m_truthE.push_back(truth_momentum.E()); */
1589 /* m_truthEta.push_back(truth_momentum.PseudoRapidity()); */
1590 /* m_truthPhi.push_back(truth_momentum.Phi()); */
1591 /* m_truthPt.push_back(truth_momentum.Pt()); */
1592 /* m_truthMass.push_back(truth_momentum.M()); */
1593 /* /1* std::cout << "Done adding kinematics to vector\n"; *1/ */
1594 
1595 /* /1* std::cout << "Asserting end_vtx= " << end_vtx << "\n"; *1/ */
1596 /* assert(end_vtx); */
1597 /* m_truthEndVtx_x.push_back(end_vtx->get_x()); */
1598 /* m_truthEndVtx_y.push_back(end_vtx->get_y()); */
1599 /* m_truthEndVtx_z.push_back(end_vtx->get_z()); */
1600 /* m_truthEndVtx_t.push_back(end_vtx->get_t()); */
1601 /* float x = end_vtx->get_x(); */
1602 /* float y = end_vtx->get_y(); */
1603 /* float r = sqrt(x*x + y*y); */
1604 /* m_truthEndVtx_r.push_back(r); */
1605 /* /1* std::cout << "Done adding vertex to vector\n"; *1/ */
1606 
1607 /* secondaryBarcodes.push_back(part->get_barcode()); */
1608 /* } */
1609 
1610 
1611 /* bool pythiaEMCalAna::vector_contains(std::pair<int,int> val, std::vector<std::pair<int,int>> vec) { */
1612 /* unsigned int s = vec.size(); */
1613 /* if ( s == 0 ) return false; */
1614 /* unsigned int i; */
1615 /* for (i=0; i<s; i++) { */
1616 /* if (vec.at(i) == val) break; */
1617 /* } */
1618 /* if ( i == s ) return false; */
1619 /* else return true; */
1620 /* } */
1621