Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
singlePhotonClusterAna.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file singlePhotonClusterAna.cc
2 
3 //Fun4all stuff
8 #include <phool/getClass.h>
9 #include <phool/phool.h>
10 #include <ffaobjects/EventHeader.h>
11 
12 //ROOT stuff
13 #include <TH1F.h>
14 #include <TH2F.h>
15 #include <TH3F.h>
16 #include <TFile.h>
17 #include <TLorentzVector.h>
18 #include <TTree.h>
19 
20 //for emc clusters
21 #include <calobase/RawCluster.h>
22 #include <calobase/RawClusterContainer.h>
23 #include <calobase/RawClusterUtility.h>
24 #include <calobase/RawTowerGeomContainer.h>
25 #include <calobase/RawTower.h>
26 #include <calobase/RawTowerContainer.h>
27 
28 //for vetex information
31 
32 //tracking
35 #include <trackbase_historic/SvtxVertex.h>
36 #include <trackbase_historic/SvtxVertexMap.h>
37 
38 //truth information
40 #include <g4main/PHG4Particle.h>
41 #include <g4main/PHG4VtxPoint.h>
42 #pragma GCC diagnostic push
43 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
44 #include <HepMC/GenEvent.h>
45 #include <HepMC/GenParticle.h>
46 #include <HepMC/GenVertex.h>
47 #include <HepMC/IteratorRange.h>
48 #include <HepMC/SimpleVector.h>
49 #include <HepMC/GenParticle.h>
50 #pragma GCC diagnostic pop
51 #include <CLHEP/Geometry/Point3D.h>
52 
53 
54 //____________________________________________________________________________..
55 singlePhotonClusterAna::singlePhotonClusterAna(const std::string &name, const std::string &outName = "singlePhotonClusterAnaOut"):
56 SubsysReco(name)
57  , clusters_Towers(nullptr)
58  , truth_photon(nullptr)
59  , conversion(nullptr)
60  //, caloevalstack(NULL)
61  , m_eta_center()
62  , m_phi_center()
63  , m_tower_energy()
64 , m_cluster_eta()
65  , m_cluster_phi()
66 , m_cluster_e()
67 , m_cluster_ecore()
68  , m_cluster_chi2()
69  , m_cluster_prob()
70 , m_cluster_nTowers()
71  , m_photon_E()
72 , m_photon_eta()
73 , m_photon_phi()
74  , m_electron_E()
75 , m_electron_eta()
76 , m_electron_phi()
77  , m_positron_E()
78 , m_positron_eta()
79 , m_positron_phi()
80  , m_vtx_x()
81  , m_vtx_y()
82  , m_vtx_z()
83  , m_vtx_t()
84  , m_vtx_r()
85  , m_isConversionEvent()
86  , Outfile(outName)
87 
88 {
89 
90 
91  std::cout << "singlePhotonClusterAna::singlePhotonClusterAna(const std::string &name) Calling ctor" << std::endl;
92 }
93 
94 //____________________________________________________________________________..
96 {
97  std::cout << "singlePhotonClusterAna::~singlePhotonClusterAna() Calling dtor" << std::endl;
98 }
99 
100 //____________________________________________________________________________..
102 {
103 
104  clusters_Towers = new TTree("TreeClusterTower","Tree for cluster and tower information");
105  clusters_Towers -> Branch("towerEtaCEnter",&m_eta_center);
106  clusters_Towers -> Branch("towerPhiCenter",& m_phi_center);
107  clusters_Towers -> Branch("towerEnergy",&m_tower_energy);
108  clusters_Towers -> Branch("clusterEta",&m_cluster_eta);
109  clusters_Towers -> Branch("clusterPhi", &m_cluster_phi);
110  clusters_Towers -> Branch("clusterE",&m_cluster_e);
111  clusters_Towers -> Branch("clusterEcore",&m_cluster_ecore);
112  clusters_Towers -> Branch("clusterChi2",&m_cluster_chi2);
113  clusters_Towers -> Branch("clusterProb",&m_cluster_prob);
114  clusters_Towers -> Branch("clusterNTowers",&m_cluster_nTowers);
115 
116  truth_photon = new TTree("TreeTruthPhoton", "Tree for Truth Photon");
117  truth_photon -> Branch("photonE",&m_photon_E);
118  truth_photon -> Branch("photon_phi",&m_photon_phi);
119  truth_photon -> Branch("photon_eta",&m_photon_eta);
120 
121  conversion = new TTree("TreeConversion", "Tree for Photon Conversion Info");
122  conversion -> Branch("electronE",&m_electron_E);
123  conversion -> Branch("electron_phi",&m_electron_phi);
124  conversion -> Branch("electron_eta",&m_electron_eta);
125  conversion -> Branch("positronE",&m_positron_E);
126  conversion -> Branch("positron_phi",&m_positron_phi);
127  conversion -> Branch("positron_eta",&m_positron_eta);
128  conversion -> Branch("vtx_x",&m_vtx_x);
129  conversion -> Branch("vtx_y",&m_vtx_y);
130  conversion -> Branch("vtx_z",&m_vtx_z);
131  conversion -> Branch("vtx_t",&m_vtx_t);
132  conversion -> Branch("vtx_r",&m_vtx_r);
133  conversion -> Branch("isConversionEvent",&m_isConversionEvent);
134 
135  //so that the histos actually get written out
137  se -> Print("NODETREE");
138  hm = new Fun4AllHistoManager("MYHISTOS");
139 
140  se -> registerHistoManager(hm);
141 
142  se -> registerHisto(truth_photon -> GetName(), truth_photon);
143  se -> registerHisto(clusters_Towers -> GetName(), clusters_Towers);
144 
145  out = new TFile(Outfile.c_str(),"RECREATE");
146 
147  std::cout << "singlePhotonClusterAna::Init(PHCompositeNode *topNode) Initializing" << std::endl;
149 }
150 
151 //____________________________________________________________________________..
153 {
154  std::cout << "singlePhotonClusterAna::InitRun(PHCompositeNode *topNode) Initializing for Run XXX" << std::endl;
155 
157 }
158 
159 //____________________________________________________________________________..
161 {
162 
163  //Information on clusters
164  RawClusterContainer *clusterContainer = findNode::getClass<RawClusterContainer>(topNode,"CLUSTER_POS_COR_CEMC");
165  //RawClusterContainer *clusterContainer = findNode::getClass<RawClusterContainer>(topNode,"CLUSTER_CEMC");
166  if(!clusterContainer)
167  {
168  std::cout << PHWHERE << "singlePhotonClusterAna::process_event - Fatal Error - CLUSTER_CEMC node is missing. " << std::endl;
169 
170  return 0;
171  }
172 
173 
174  /* //Vertex information */
175  GlobalVertexMap *vtxContainer = findNode::getClass<GlobalVertexMap>(topNode,"GlobalVertexMap");
176  if (!vtxContainer)
177  {
178  std::cout << PHWHERE << "singlePhotonClusterAna::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;
179  assert(vtxContainer); // force quit
180 
181  return 0;
182  }
183 
184  if (vtxContainer->empty())
185  {
186  std::cout << PHWHERE << "singlePhotonClusterAna::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;
187  return 0;
188  }
189 
190  //More vertex information
191  GlobalVertex *vtx = vtxContainer->begin()->second;
192  if(!vtx)
193  {
194 
195  std::cout << PHWHERE << "singlePhotonClusterAna::process_event Could not find vtx from vtxContainer" << std::endl;
197  }
198 
199  //Tower geometry node for location information
200  RawTowerGeomContainer *towergeom = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_CEMC");
201  if (!towergeom)
202  {
203  std::cout << PHWHERE << "singlePhotonClusterAna::process_event Could not find node TOWERGEOM_CEMC" << std::endl;
205  }
206 
207  //Raw tower information
208  RawTowerContainer *towerContainer = findNode::getClass<RawTowerContainer>(topNode,"TOWER_CALIB_CEMC");
209  if(!towerContainer)
210  {
211  std::cout << PHWHERE << "singlePhotonClusterAna::process_event Could not find node TOWER_CALIB_CEMC" << std::endl;
213  }
214 
215  //truth particle information
216  PHG4TruthInfoContainer *truthinfo = findNode::getClass<PHG4TruthInfoContainer>(topNode, "G4TruthInfo");
217  if(!truthinfo)
218  {
219  std::cout << PHWHERE << "singlePhotonClusterAna::process_event Could not find node G4TruthInfo" << std::endl;
221  }
222 
223 
224  float photonEta = -99999;
225  float photonEtaMax = 1.1;
226  TLorentzVector photon;
227  //Now we go and find our truth photon and just take its eta coordinate for now
228  PHG4TruthInfoContainer::Range truthRange = truthinfo->GetPrimaryParticleRange();
230 
231  PHG4Particle *truthPar = NULL;
232 
233  for(truthIter = truthRange.first; truthIter != truthRange.second; truthIter++)
234  {
235  truthPar = truthIter->second;
236 
237  // photon pid is 22
238  if(truthPar -> get_pid() == 22 && truthPar -> get_parent_id() == 0)
239  {
240  photonEta = getEta(truthPar);
241  if(abs(photonEta) >= photonEtaMax)
242  {
243  return 0;
244  }
245  /* std::cout << "\n\nGreg info:\n\nFound truth photon.\n"; */
246  /* std::cout << "Truth photon E = " << truthPar->get_e() << "; eta = " << getEta(truthPar) << "\n"; */
247  /* std::cout << "truthPar = " << truthPar << "\n"; */
248  /* std::cout << "truthPar->get_primary_id() = " << truthPar->get_primary_id() << "\n"; */
249  /* std::cout << "truthPar->get_pid() = " << truthPar->get_pid() << "\n"; */
250  /* std::cout << "truthPar->get_vtx_id() = " << truthPar->get_vtx_id() << "\n"; */
251  /* std::cout << "truthPar->get_track_id() = " << truthPar->get_track_id() << "\n"; */
252  photon.SetPxPyPzE(truthPar -> get_px(), truthPar -> get_py(), truthPar -> get_pz(), truthPar -> get_e());
253  }
254  }
255 
256  // Check the daughter particles of truth photon
257  int decay_vtx_idx = 0;
258  int decay_vtx_idx1 = 0; // first decay particle vertex
259  int decay_vtx_idx2 = 0; // second decay particle vertex; SHOULD be the same!
260  bool first_decay_particle = false;
261  bool second_decay_particle = false;
262  bool decay_electron = false;
263  bool decay_positron = false;
264  int n_children = 0;
265  TLorentzVector electron;
266  TLorentzVector positron;
267  bool isGoodEvent = true;
268 
269  PHG4TruthInfoContainer::Range truthRangeDecay1 = truthinfo->GetSecondaryParticleRange();
271 
272  // First just check that the truth photon has exactly 2 daughters
273  // and they share the same vertex
274  for(truthIterDecay1 = truthRangeDecay1.first; truthIterDecay1 != truthRangeDecay1.second; truthIterDecay1++)
275  {
276  PHG4Particle *decay = truthIterDecay1 -> second;
277 
278  int dumparentid = decay -> get_parent_id();
279  if(dumparentid == 1) {
280  n_children++;
281  if (! first_decay_particle) {
282  first_decay_particle = true;
283  decay_vtx_idx1 = decay->get_vtx_id();
284  }
285  else {
286  second_decay_particle = true;
287  decay_vtx_idx2 = decay->get_vtx_id();
288  }
289  /* std::cout << "\nDecay particle E = " << decay->get_e() << "; eta = " << getEta(decay) << "\n"; */
290  /* std::cout << "decay = " << decay << "\n"; */
291  /* std::cout << "decay->get_primary_id() = " << decay->get_primary_id() << "\n"; */
292  /* std::cout << "decay->get_pid() = " << decay->get_pid() << "\n"; */
293  /* std::cout << "decay->get_vtx_id() = " << decay->get_vtx_id() << "\n"; */
294  /* std::cout << "decay->get_track_id() = " << decay->get_track_id() << "\n"; */
295  }
296  }
297 
298  if (n_children != 2) isGoodEvent = false;
299  if (!(first_decay_particle && second_decay_particle)) isGoodEvent = false;
300  if (decay_vtx_idx1 != decay_vtx_idx2) isGoodEvent = false;
301 
302  // Now get decay electron and positron kinematics
303  for(truthIterDecay1 = truthRangeDecay1.first; truthIterDecay1 != truthRangeDecay1.second; truthIterDecay1++)
304  {
305  PHG4Particle *decay = truthIterDecay1 -> second;
306 
307  int dumtruthpid = decay -> get_pid();
308  int dumparentid = decay -> get_parent_id();
309  if(dumparentid == 1) {
310  if (dumtruthpid == 11) {
311  // electron
312  decay_electron = true;
313  electron.SetPxPyPzE(decay -> get_px(), decay -> get_py(), decay -> get_pz(), decay -> get_e());
314  }
315  if (dumtruthpid == -11) {
316  // positron
317  decay_positron = true;
318  positron.SetPxPyPzE(decay -> get_px(), decay -> get_py(), decay -> get_pz(), decay -> get_e());
319  }
320  }
321  }
322 
323  if (!(decay_electron && decay_positron)) isGoodEvent = false;
324 
325  // Conversion vertex information
326  /* std::cout << "\nVertex information:\n"; */
327  /* PHG4VtxPoint* photon_vtx = truthinfo->GetVtx(photon_vxt_idx); */
328  /* std::cout << "\ntruthinfo->is_primary_vtx(photon_vtx) = " << truthinfo->is_primary_vtx(photon_vtx) << "\n"; */
329  /* std::cout << "photon_vtx->get_id() = " << photon_vtx->get_id() << "\n"; */
330  /* std::cout << "photon_vtx (x,y,z,t) = (" << photon_vtx->get_x() << ", " << photon_vtx->get_y() << ", " << photon_vtx->get_z() << ", " << photon_vtx->get_t() << ")\n"; */
331  if (isGoodEvent) {
332  m_photon_E.push_back(photon.Energy());
333  m_photon_eta.push_back(photon.PseudoRapidity());
334  m_photon_phi.push_back(photon.Phi());
335  m_electron_E.push_back(electron.Energy());
336  m_electron_eta.push_back(electron.PseudoRapidity());
337  m_electron_phi.push_back(electron.Phi());
338  m_positron_E.push_back(positron.Energy());
339  m_positron_eta.push_back(positron.PseudoRapidity());
340  m_positron_phi.push_back(positron.Phi());
341 
342  decay_vtx_idx = decay_vtx_idx1;
343  PHG4VtxPoint* decay_vtx = truthinfo->GetVtx(decay_vtx_idx);
344  m_vtx_x.push_back(decay_vtx->get_x());
345  m_vtx_y.push_back(decay_vtx->get_y());
346  m_vtx_z.push_back(decay_vtx->get_z());
347  m_vtx_t.push_back(decay_vtx->get_t());
348  float vtx_x = decay_vtx->get_x();
349  float vtx_y = decay_vtx->get_y();
350  float vtx_r = sqrt(vtx_x*vtx_x + vtx_y*vtx_y);
351  m_vtx_r.push_back(vtx_r);
352  bool isConversionEvent = false;
353  float EMCal_inner_radius = 95; // nominal radius is 97.5cm
354  if (vtx_r < EMCal_inner_radius) isConversionEvent = true;
355  m_isConversionEvent.push_back(isConversionEvent);
356  /* std::cout << "\ntruthinfo->is_primary_vtx(decay_vtx) = " << truthinfo->is_primary_vtx(decay_vtx) << "\n"; */
357  /* std::cout << "decay_vtx->get_id() = " << decay_vtx->get_id() << "\n"; */
358  /* std::cout << "decay_vtx (x,y,z,t) = (" << decay_vtx->get_x() << ", " << decay_vtx->get_y() << ", " << decay_vtx->get_z() << ", " << decay_vtx->get_t() << ")\n"; */
359  }
360  else {
361  std::cout << "\nGreg info:\nBad conversion event\n";
362  std::cout << "n_children = " << n_children << "\n";
363  std::cout << "first_decay_particle = " << first_decay_particle << "; second_decay_particle = " << second_decay_particle << "\n";
364  std::cout << "decay_vtx_idx1 = " << decay_vtx_idx1 << "; decay_vtx_idx2 = " << decay_vtx_idx2 << "\n";
365  std::cout << "decay_electron = " << decay_electron << "; decay_positron = " << decay_positron << "\n";
366  return 0;
367  }
368 
369  // Anthony's code for pi0 decays
370  /*
371 
372  int firstphotonflag = 0;
373  int firstfirstphotonflag = 0;
374  int secondphotonflag = 0;
375 
376  //int secondsecondphotonflag = 0;
377 
378  PHG4TruthInfoContainer::Range truthRangeDecay1 = truthinfo->GetSecondaryParticleRange();
379  PHG4TruthInfoContainer::ConstIterator truthIterDecay1;
380 
381 
382  TLorentzVector photon1;
383  TLorentzVector photon2;
384  int nParticles = 0;
385 
386  //loop over all our decay photons.
387  //Make sure they fall within the desired acceptance
388  //Toss Dalitz decays
389  //Retain photon kinematics to determine lead photon for eta binning
390  for(truthIterDecay1 = truthRangeDecay1.first; truthIterDecay1 != truthRangeDecay1.second; truthIterDecay1++)
391  {
392  PHG4Particle *decay = truthIterDecay1 -> second;
393 
394  int dumtruthpid = decay -> get_pid();
395  int dumparentid = decay -> get_parent_id();
396 
397  //if the parent is the pi0 and it's a photon and we haven't marked one yet
398  if(dumparentid == 1 && dumtruthpid == 22 && !firstphotonflag)
399  {
400  if(abs(getEta(decay)) > photonEtaMax)
401  {
402  return 0;
403  }
404  photon1.SetPxPyPzE(decay -> get_px(), decay -> get_py(), decay -> get_pz(), decay -> get_e());
405 
406  firstphotonflag = 1;
407  }
408 
409  if(dumparentid == 1 && dumtruthpid == 22 && firstphotonflag && firstfirstphotonflag)
410  {
411  if(abs(getEta(decay)) > photonEtaMax)
412  {
413  return 0;
414  }
415  photon2.SetPxPyPzE(decay -> get_px(), decay -> get_py(), decay -> get_pz(), decay -> get_e()) ;
416 
417  secondphotonflag = 1;
418  }
419 
420  //Need this flag to make it skip the first photon slot
421  if(firstphotonflag) firstfirstphotonflag = 1;
422  if(dumparentid == 1)nParticles ++;
423  }
424 
425  if((!firstphotonflag || !secondphotonflag) && nParticles > 1) //Dalitz
426  {
427  return 0;
428  }
429  else if((!firstphotonflag || !secondphotonflag) && nParticles == 1) //One photon falls outside simulation acceptance
430  {
431  return 0;
432  }
433  else if((!firstphotonflag || !secondphotonflag) && nParticles == 0) //Both photons fall outside simulation acceptance
434  {
435  return 0;
436  }
437  */ // End check on decay photons
438 
439  //grab all the towers and fill their energies.
440  RawTowerContainer::ConstRange tower_range = towerContainer -> getTowers();
441  for(RawTowerContainer::ConstIterator tower_iter = tower_range.first; tower_iter!= tower_range.second; tower_iter++)
442  {
443  int phibin = tower_iter -> second -> get_binphi();
444  int etabin = tower_iter -> second -> get_bineta();
445  double phi = towergeom -> get_phicenter(phibin);
446  double eta = towergeom -> get_etacenter(etabin);
447  double energy = tower_iter -> second -> get_energy();
448 
449  m_phi_center.push_back(phi);
450  m_eta_center.push_back(eta);
451  m_tower_energy.push_back(energy);
452  }
453 
454  //This is how we iterate over items in the container.
455  RawClusterContainer::ConstRange clusterEnd = clusterContainer -> getClusters();
457 
458  for(clusterIter = clusterEnd.first; clusterIter != clusterEnd.second; clusterIter++)
459  {
460  RawCluster *recoCluster = clusterIter -> second;
461 
462  CLHEP::Hep3Vector vertex(vtx->get_x(), vtx->get_y(), vtx->get_z());
463  /* CLHEP::Hep3Vector vertex(0., 0., 0.); */
464  CLHEP::Hep3Vector E_vec_cluster = RawClusterUtility::GetECoreVec(*recoCluster, vertex);
465  float clusE = E_vec_cluster.mag();
466  float clusEcore = recoCluster->get_ecore();
467  float clus_eta = E_vec_cluster.pseudoRapidity();
468  float clus_phi = E_vec_cluster.phi();
469 
470  m_cluster_eta.push_back(clus_eta);
471  m_cluster_phi.push_back(clus_phi);
472  m_cluster_e.push_back(clusE);
473  m_cluster_ecore.push_back(clusEcore);
474 
475  m_cluster_chi2.push_back(recoCluster -> get_chi2());
476  m_cluster_prob.push_back(recoCluster -> get_prob());
477  m_cluster_nTowers.push_back(recoCluster -> getNTowers());
478  }
479 
480 
481  clusters_Towers -> Fill();
482  truth_photon -> Fill();
483  conversion -> Fill();
484 
485 
487 }
488 
489 //____________________________________________________________________________..
491 {
492  //std::cout << "singlePhotonClusterAna::ResetEvent(PHCompositeNode *topNode) Resetting internal structures, prepare for next event" << std::endl;
493 
494  m_eta_center.clear();
495  m_phi_center.clear();
496  m_tower_energy.clear();
497  m_cluster_eta.clear();
498  m_cluster_phi.clear();
499  m_cluster_e.clear();
500  m_cluster_chi2.clear();
501  m_cluster_prob.clear();
502  m_cluster_nTowers.clear();
503  m_photon_E.clear();
504  m_photon_eta.clear();
505  m_photon_phi.clear();
506  m_electron_E.clear();
507  m_electron_eta.clear();
508  m_electron_phi.clear();
509  m_positron_E.clear();
510  m_positron_eta.clear();
511  m_positron_phi.clear();
512  m_vtx_x.clear();
513  m_vtx_y.clear();
514  m_vtx_z.clear();
515  m_vtx_t.clear();
516  m_vtx_r.clear();
517  m_isConversionEvent.clear();
519 }
520 
521 //____________________________________________________________________________..
523 {
524  std::cout << "singlePhotonClusterAna::EndRun(const int runnumber) Ending Run for Run " << runnumber << std::endl;
526 }
527 
528 //____________________________________________________________________________..
530 {
531  std::cout << "singlePhotonClusterAna::End(PHCompositeNode *topNode) This is the End..." << std::endl;
532  out -> cd();
533 
534  truth_photon -> Write();
535  clusters_Towers -> Write();
536  conversion -> Write();
537 
538  out -> Close();
539  delete out;
540 
541  hm -> dumpHistos(Outfile.c_str(),"UPDATE");
542 
543 
545 }
546 
547 //____________________________________________________________________________..
549 {
550  std::cout << "singlePhotonClusterAna::Reset(PHCompositeNode *topNode) being Reset" << std::endl;
552 }
553 
554 //____________________________________________________________________________..
556 {
557  std::cout << "singlePhotonClusterAna::Print(const std::string &what) const Printing info for " << what << std::endl;
558 }
559 //____________________________________________________________________________..
561 {
562  float px = particle -> get_px();
563  float py = particle -> get_py();
564  float pz = particle -> get_pz();
565  float p = sqrt(pow(px,2) + pow(py,2) + pow(pz,2));
566 
567  return 0.5*log((p+pz)/(p-pz));
568 }