Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
IsolatedTrackAnalysis.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file IsolatedTrackAnalysis.cc
2 
3 // Centrality includes
5 
6 // Tracking includes
10 #include <trackbase_historic/SvtxVertexMap.h>
11 
12 #include <trackbase/TrkrCluster.h>
15 #include <trackbase/TrkrHit.h>
17 #include <trackbase/TrkrDefs.h>
18 #include <trackbase/ActsGeometry.h>
20 
21 #include <trackbase/TpcDefs.h>
22 
24 #include <trackbase/TrkrHitSet.h>
27 
28 // Cluster includes
29 #include <calobase/RawCluster.h>
30 #include <calobase/RawClusterContainer.h>
31 #include <calobase/RawClusterUtility.h>
32 #include <calobase/RawTowerGeomContainer_Cylinderv1.h>
33 
34 // Tower includes
35 #include <calobase/RawTower.h>
36 #include <calobase/RawTowerContainer.h>
37 #include <calobase/RawTowerGeom.h>
38 #include <calobase/RawTowerGeomContainer.h>
39 #include <calobase/RawTowerDefs.h>
40 
41 // G4 truth includes
42 #include <g4eval/SvtxEvalStack.h>
43 #include <g4main/PHG4Particle.h>
45 #include <g4main/PHG4Hit.h>
47 #include <g4main/PHG4VtxPoint.h>
48 
49 // HepMC truth includes
50 #pragma GCC diagnostic push
51 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
52 #include <HepMC/GenEvent.h>
53 #pragma GCC diagnostic pop
54 #include <HepMC/GenVertex.h>
57 
58 // Fun4All includes
60 #include <phool/PHCompositeNode.h>
61 #include <phool/getClass.h>
62 
63 // Acts includes
65 
66 // ROOT includes
67 #include <TFile.h>
68 #include <TTree.h>
69 
70 // System includes
71 #include <iostream>
72 #include <cmath>
73 #include <string>
74 #include <vector>
75 #include <set>
76 
77 //____________________________________________________________________________..
79  SubsysReco(name),
80  m_outputFileName(fileName),
81  m_minEMClusterEnergy(0.1),
82  m_minIHClusterEnergy(0.012),
83  m_minOHClusterEnergy(0.025),
84  m_minCemcTowerEnergy(0.04),
85  m_minHcalTowerEnergy(0.006),
86  m_minSimTowerEnergy(0.0),
87  m_analyzeTracks(true),
88  m_analyzeClusters(true),
89  m_analyzeTowers(true),
90  m_analyzeSimTowers(true),
91  m_analyzeHepMCTruth(true),
92  m_analyzeG4Truth(true),
93  m_analyzeCentrality(true),
94  m_analyzeAddTruth(true)
95 {
97 }
98 
99 //____________________________________________________________________________..
101 {
102  delete m_tracktree;
103  delete m_clustertree;
104  delete m_towertree;
105  delete m_simtowertree;
106  delete m_hepmctree;
107  delete m_g4tree;
108  delete m_centraltree;
109  delete m_addtruthtree;
110 }
111 
112 //____________________________________________________________________________..
114 {
115  m_outputFile = new TFile(m_outputFileName.c_str(), "RECREATE");
116 
117  counter = 0;
118 
120 }
121 
122 //____________________________________________________________________________..
124 {
125  if(m_analyzeTracks){
126  RawTowerGeomContainer_Cylinderv1* cemcGeomContainer = findNode::getClass<RawTowerGeomContainer_Cylinderv1>(topNode, "TOWERGEOM_CEMC");
127  RawTowerGeomContainer_Cylinderv1* ihcalGeomContainer = findNode::getClass<RawTowerGeomContainer_Cylinderv1>(topNode, "TOWERGEOM_HCALIN");
128  RawTowerGeomContainer_Cylinderv1* ohcalGeomContainer = findNode::getClass<RawTowerGeomContainer_Cylinderv1>(topNode, "TOWERGEOM_HCALOUT");
129 
130  if(!cemcGeomContainer){
131  std::cout << "ERROR: TOWERGEOM_CEMC not found" << std::endl;
132  }
133  if(!ihcalGeomContainer){
134  std::cout << "ERROR: TOWERGEOM_HCALIN not found" << std::endl;
135  }
136  if(!ohcalGeomContainer){
137  std::cout << "ERROR: TOWERGEOM_HCALOUT not found" << std::endl;
138  }
139 
140  m_cemcRadius = cemcGeomContainer->get_radius();
141  m_ihcalRadius = ihcalGeomContainer->get_radius();
142  m_ohcalRadius = ohcalGeomContainer->get_radius();
143  }
144 
146 }
147 
148 //____________________________________________________________________________..
150 {
151  if(m_analyzeTracks){ getTracks(topNode); }
152  if(m_analyzeClusters){ getClusters(topNode); }
153  if(m_analyzeTowers){ getTowers(topNode); }
154  if(m_analyzeSimTowers){ getSimTowers(topNode); }
155  if(m_analyzeHepMCTruth){ getHepMCTruth(topNode); }
156  if(m_analyzeG4Truth){ getG4Truth(topNode); }
157  if(m_analyzeCentrality){ getCentrality(topNode); }
158  if(m_analyzeAddTruth){ getAddTruth(topNode); }
159 
160  counter++;
161 
162  //if(counter % 100 == 0)
163  std::cout << counter << " events processed" << std::endl;
164 
166 }
167 
168 //____________________________________________________________________________..
170 {
172 }
173 
174 //____________________________________________________________________________..
176 {
177  m_outputFile->cd();
178  m_tracktree->Write();
179  m_clustertree->Write();
180  m_towertree->Write();
181  m_simtowertree->Write();
182  m_hepmctree->Write();
183  m_g4tree->Write();
184  m_centraltree->Write();
185  m_addtruthtree->Write();
186  m_outputFile->Close();
188 }
189 
190 
192 
194 // Function extracting centrality //
196 
198 {
199  central = findNode::getClass<CentralityInfo>(topNode, "CentralityInfo");
200  centrality = central->get_centile(CentralityInfo::PROP::bimp);
201  m_centraltree->Fill();
202 }
203 
205 // Function extracting tracks //
207 
209 {
210  SvtxTrackMap *trackmap = findNode::getClass<SvtxTrackMap>(topNode, "SvtxTrackMap");
211 
212  // Check whether SvtxTrackMap is present in the node tree or not
213  if (!trackmap)
214  {
215  std::cout << PHWHERE
216  << "SvtxTrackMap node is missing, can't collect tracks"
217  << std::endl;
218  return;
219  }
220 
221  SvtxVertexMap *vertexmap = findNode::getClass<SvtxVertexMap>(topNode, "SvtxVertexMap");
222 
223  // Check whether SvtxTrackMap is present in the node tree or not
224  if (!vertexmap)
225  {
226  std::cout << PHWHERE
227  << "SvtxVertexMap node is missing, can't collect tracks"
228  << std::endl;
229  return;
230  }
231 
232  // EvalStack for truth track matching
233  if(!m_svtxEvalStack){ m_svtxEvalStack = new SvtxEvalStack(topNode); }
234 
235  m_svtxEvalStack->next_event(topNode);
236 
237  // Get the track evaluator
239 
240  // Get the range for primary tracks
241  PHG4TruthInfoContainer *truthinfo = findNode::getClass<PHG4TruthInfoContainer>(topNode, "G4TruthInfo");
242 
243  m_trkmult = 0;
244  // Looping over tracks in an event
245  for(auto entry : *trackmap)
246  {
247  SvtxTrack *track = entry.second;
248 
249  m_tr_p[m_trkmult] = track->get_p();
250  m_tr_pt[m_trkmult] = track->get_pt();
251  m_tr_eta[m_trkmult] = track->get_eta();
252  m_tr_phi[m_trkmult] = track->get_phi();
253 
254  m_tr_charge[m_trkmult] = track->get_charge();
255  m_tr_chisq[m_trkmult] = track->get_chisq();
256  m_tr_ndf[m_trkmult] = track->get_ndf();
258 
259  float dca_xy, dca_z, dca_xy_error, dca_z_error;
260  calculateDCA(track, vertexmap, dca_xy, dca_z, dca_xy_error, dca_z_error);
261 
262  m_tr_dca_xy[m_trkmult] = dca_xy;
263  m_tr_dca_xy_error[m_trkmult] = dca_xy_error;
264  m_tr_dca_z[m_trkmult] = dca_z;
265  m_tr_dca_z_error[m_trkmult] = dca_z_error;
266 
267  m_tr_x[m_trkmult] = track->get_x();
268  m_tr_y[m_trkmult] = track->get_y();
269  m_tr_z[m_trkmult] = track->get_z();
270 
272 
273  // Project tracks to CEMC
274  if(track->find_state(m_cemcRadius) != track->end_states()){
277  }
278  else{
279  m_tr_cemc_eta[m_trkmult] = -999;
280  m_tr_cemc_phi[m_trkmult] = -999;
281  }
282 
283  // Project tracks to inner HCAL
284  if(track->find_state(m_ihcalRadius) != track->end_states()){
287  }
288  else{
289  m_tr_ihcal_eta[m_trkmult] = -999;
290  m_tr_ihcal_phi[m_trkmult] = -999;
291  }
292 
293  // Project tracks to outer HCAL
294  if(track->find_state(m_ohcalRadius) != track->end_states()){
297  }
298  else{
299  m_tr_ohcal_eta[m_trkmult] = -999;
300  m_tr_ohcal_phi[m_trkmult] = -999;
301  }
302 
303  // Matching SvtxTracks to G4 truth
304  //std::cout << "before truth matching" << std::endl;
305  PHG4Particle *truthtrack = trackeval->max_truth_particle_by_nclusters(track);
306  //std::cout << "after truth matching" << std::endl;
307 
308  if(truthtrack){
309  //std::cout << "found truth track" << std::endl;
310  m_tr_truth_pid[m_trkmult] =truthtrack->get_pid();
311  m_tr_truth_is_primary[m_trkmult] =truthinfo->is_primary(truthtrack);
312 
313  m_tr_truth_e[m_trkmult] =truthtrack->get_e();
314 
315  float px = truthtrack->get_px();
316  float py = truthtrack->get_py();
317  float pz = truthtrack->get_pz();
318 
319  m_tr_truth_pt[m_trkmult] = sqrt(px*px+py*py);
320  m_tr_truth_phi[m_trkmult] = atan2(py, px);
321  m_tr_truth_eta[m_trkmult] = atanh(pz/sqrt(px*px+py*py+pz*pz));
322  m_tr_truth_track_id[m_trkmult] = truthtrack->get_track_id();
323  }
324  else{
325  //std::cout << "truth track null" << std::endl;
326  m_tr_truth_pid[m_trkmult] = -999;
328  m_tr_truth_e[m_trkmult] = -999;
329  m_tr_truth_pt[m_trkmult] = -999;
330  m_tr_truth_eta[m_trkmult] = -999;
331  m_tr_truth_phi[m_trkmult] = -999;
333  }
334 
335  m_trkmult++;
336  }
337 
338  m_vtxmult = 0;
339  for(auto entry : *vertexmap)
340  {
341  SvtxVertex *vertex = entry.second;
342 
343  m_vertex_id[m_vtxmult] = vertex->get_id();
344  m_vx[m_vtxmult] = vertex->get_x();
345  m_vy[m_vtxmult] = vertex->get_y();
346  m_vz[m_vtxmult] = vertex->get_z();
347  m_vtxmult++;
348  }
349 
350  m_tracktree->Fill();
351 }
352 
354 // Function extracting clusters //
357 
358  RawClusterContainer *cemcContainer = findNode::getClass<RawClusterContainer>(topNode,"CLUSTER_CEMC");
359 
360  // Check whether CLUSTER_CEMC is present in the node tree or not
361  if (!cemcContainer)
362  {
363  std::cout << PHWHERE
364  << "CLUSTER_CEMC node is missing, can't collect EMCal clusters"
365  << std::endl;
366  return;
367  }
368 
369  RawClusterContainer::Map cemcMap = cemcContainer->getClustersMap();
370 
371  m_clsmult_cemc = 0;
372  for(auto entry : cemcMap){
373  RawCluster* cluster = entry.second;
374 
375  if(cluster->get_energy() > m_minEMClusterEnergy){
376  // calculating eta
377  // we need the nominal eta, with respect to the origin, not the vertex!
378  CLHEP::Hep3Vector origin(0, 0, 0);
379  CLHEP::Hep3Vector cluster_vector = RawClusterUtility::GetECoreVec(*cluster, origin);
380 
381  m_cl_cemc_e[m_clsmult_cemc] = cluster->get_energy();
382  m_cl_cemc_eta[m_clsmult_cemc] = cluster_vector.pseudoRapidity();
383  m_cl_cemc_phi[m_clsmult_cemc] = cluster->get_phi();
384  m_cl_cemc_r[m_clsmult_cemc] = cluster->get_r();
385  m_cl_cemc_z[m_clsmult_cemc] = cluster->get_z();
386 
387  m_clsmult_cemc++;
388  }
389  }
390 
391  RawClusterContainer *ihcalContainer = findNode::getClass<RawClusterContainer>(topNode,"CLUSTER_HCALIN");
392 
393  // Check whether CLUSTER_HCALIN is present in the node tree or not
394  if (!ihcalContainer)
395  {
396  std::cout << PHWHERE
397  << "CLUSTER_HCALIN node is missing, can't collect EMCal clusters"
398  << std::endl;
399  return;
400  }
401 
402  RawClusterContainer::Map ihcalMap = ihcalContainer->getClustersMap();
403 
404  m_clsmult_ihcal = 0;
405  for(auto entry : ihcalMap){
406  RawCluster* cluster = entry.second;
407 
408  if(cluster->get_energy() > m_minIHClusterEnergy){
409  // calculating eta
410  // we need the nominal eta, with respect to the origin, not the vertex!
411  CLHEP::Hep3Vector origin(0, 0, 0);
412  CLHEP::Hep3Vector cluster_vector = RawClusterUtility::GetECoreVec(*cluster, origin);
413 
415  m_cl_ihcal_eta[m_clsmult_ihcal] = cluster_vector.pseudoRapidity();
416  m_cl_ihcal_phi[m_clsmult_ihcal] = cluster->get_phi();
417  m_cl_ihcal_r[m_clsmult_ihcal] = cluster->get_r();
418  m_cl_ihcal_z[m_clsmult_ihcal] = cluster->get_z();
419 
420  m_clsmult_ihcal++;
421  }
422  }
423 
424  RawClusterContainer *ohcalContainer = findNode::getClass<RawClusterContainer>(topNode,"CLUSTER_HCALOUT");
425 
426  // Check whether CLUSTER_HCALOUT is present in the node tree or not
427  if (!ohcalContainer)
428  {
429  std::cout << PHWHERE
430  << "CLUSTER_HCALOUT node is missing, can't collect EMCal clusters"
431  << std::endl;
432  return;
433  }
434 
435  RawClusterContainer::Map ohcalMap = ohcalContainer->getClustersMap();
436 
437  m_clsmult_ohcal = 0;
438  for(auto entry : ohcalMap){
439  RawCluster* cluster = entry.second;
440 
441  if(cluster->get_energy() > m_minOHClusterEnergy){
442  // calculating eta
443  // we need the nominal eta, with respect to the origin, not the vertex!
444  CLHEP::Hep3Vector origin(0, 0, 0);
445  CLHEP::Hep3Vector cluster_vector = RawClusterUtility::GetECoreVec(*cluster, origin);
446 
448  m_cl_ohcal_eta[m_clsmult_ohcal] = cluster_vector.pseudoRapidity();
449  m_cl_ohcal_phi[m_clsmult_ohcal] = cluster->get_phi();
450  m_cl_ohcal_r[m_clsmult_ohcal] = cluster->get_r();
451  m_cl_ohcal_z[m_clsmult_ohcal] = cluster->get_z();
452 
453  m_clsmult_ohcal++;
454  }
455  }
456 
457  m_clustertree->Fill();
458 
459 }
460 
462 // Function extracting towers //
464 
466 
467  m_twrmult_cemc = 0;
468 
469  RawTowerContainer *cemcTowerContainer = findNode::getClass<RawTowerContainer>(topNode, "TOWER_CALIB_CEMC");
470  RawTowerGeomContainer *cemcGeom = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_CEMC");
471 
472  if(cemcTowerContainer && cemcGeom)
473  {
474  RawTowerContainer::ConstRange range = cemcTowerContainer->getTowers();
475  for(RawTowerContainer::ConstIterator it = range.first; it != range.second; it++){
476  RawTower *tower = it->second;
477 
478  RawTowerGeom *tower_geom = cemcGeom->get_tower_geometry(tower->get_key());
479  if(tower->get_energy() > m_minCemcTowerEnergy)
480  {
482  m_twr_cemc_eta[m_twrmult_cemc] = tower_geom->get_eta();
483  m_twr_cemc_phi[m_twrmult_cemc] = tower_geom->get_phi();
484  m_twr_cemc_ieta[m_twrmult_cemc] = tower_geom->get_bineta();
485  m_twr_cemc_iphi[m_twrmult_cemc] = tower_geom->get_binphi();
486  m_twrmult_cemc++;
487  }
488  }
489  }
490 
491 
492  m_twrmult_ihcal = 0;
493 
494  RawTowerContainer *ihcalTowerContainer = findNode::getClass<RawTowerContainer>(topNode, "TOWER_CALIB_HCALIN");
495  RawTowerGeomContainer *ihcalGeom = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_HCALIN");
496 
497  if(ihcalTowerContainer && ihcalGeom)
498  {
499  RawTowerContainer::ConstRange range = ihcalTowerContainer->getTowers();
500  for(RawTowerContainer::ConstIterator it = range.first; it != range.second; it++){
501  RawTower *tower = it->second;
502 
503  RawTowerGeom *tower_geom = ihcalGeom->get_tower_geometry(tower->get_key());
504  if(tower->get_energy() > m_minHcalTowerEnergy)
505  {
507  m_twr_ihcal_eta[m_twrmult_ihcal] = tower_geom->get_eta();
508  m_twr_ihcal_phi[m_twrmult_ihcal] = tower_geom->get_phi();
511  m_twrmult_ihcal++;
512  }
513  }
514  }
515 
516 
517  m_twrmult_ohcal = 0;
518 
519  RawTowerContainer *ohcalTowerContainer = findNode::getClass<RawTowerContainer>(topNode, "TOWER_CALIB_HCALOUT");
520  RawTowerGeomContainer *ohcalGeom = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_HCALOUT");
521 
522  if(ohcalTowerContainer && ohcalGeom)
523  {
524  RawTowerContainer::ConstRange range = ohcalTowerContainer->getTowers();
525  for(RawTowerContainer::ConstIterator it = range.first; it != range.second; it++){
526  RawTower *tower = it->second;
527 
528  RawTowerGeom *tower_geom = ohcalGeom->get_tower_geometry(tower->get_key());
529  if(tower->get_energy() > m_minHcalTowerEnergy)
530  {
532  m_twr_ohcal_eta[m_twrmult_ohcal] = tower_geom->get_eta();
533  m_twr_ohcal_phi[m_twrmult_ohcal] = tower_geom->get_phi();
536  m_twrmult_ohcal++;
537  }
538  }
539  }
540 
541  m_towertree->Fill();
542 
543 }
544 
546 // Function extracting towers //
548 
550 
551  m_simtwrmult_cemc = 0;
552 
553  RawTowerContainer *cemcTowerContainer = findNode::getClass<RawTowerContainer>(topNode, "TOWER_SIM_CEMC");
554  RawTowerGeomContainer *cemcGeom = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_CEMC");
555 
556  if(cemcTowerContainer && cemcGeom)
557  {
558  RawTowerContainer::ConstRange range = cemcTowerContainer->getTowers();
559  for(RawTowerContainer::ConstIterator it = range.first; it != range.second; it++){
560  RawTower *tower = it->second;
561 
562  RawTowerGeom *tower_geom = cemcGeom->get_tower_geometry(tower->get_key());
563  if(tower->get_energy() > m_minSimTowerEnergy)
564  {
571  }
572  }
573  }
574 
575 
576  m_simtwrmult_ihcal = 0;
577 
578  RawTowerContainer *ihcalTowerContainer = findNode::getClass<RawTowerContainer>(topNode, "TOWER_SIM_HCALIN");
579  RawTowerGeomContainer *ihcalGeom = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_HCALIN");
580 
581  if(ihcalTowerContainer && ihcalGeom)
582  {
583  RawTowerContainer::ConstRange range = ihcalTowerContainer->getTowers();
584  for(RawTowerContainer::ConstIterator it = range.first; it != range.second; it++){
585  RawTower *tower = it->second;
586 
587  RawTowerGeom *tower_geom = ihcalGeom->get_tower_geometry(tower->get_key());
588  if(tower->get_energy() > m_minSimTowerEnergy)
589  {
596  }
597  }
598  }
599 
600  m_simtwrmult_ohcal = 0;
601 
602  RawTowerContainer *ohcalTowerContainer = findNode::getClass<RawTowerContainer>(topNode, "TOWER_SIM_HCALOUT");
603  RawTowerGeomContainer *ohcalGeom = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_HCALOUT");
604 
605  if(ohcalTowerContainer && ohcalGeom)
606  {
607  RawTowerContainer::ConstRange range = ohcalTowerContainer->getTowers();
608  for(RawTowerContainer::ConstIterator it = range.first; it != range.second; it++){
609  RawTower *tower = it->second;
610 
611  RawTowerGeom *tower_geom = ohcalGeom->get_tower_geometry(tower->get_key());
612  if(tower->get_energy() > m_minSimTowerEnergy)
613  {
620  }
621  }
622  }
623 
624  m_simtowertree->Fill();
625 }
626 
627 
628 
630 // Functions extracting truth information //
632 
634 
635  PHHepMCGenEventMap *hepmceventmap = findNode::getClass<PHHepMCGenEventMap>(topNode, "PHHepMCGenEventMap");
636  if (!hepmceventmap) std::cout << PHWHERE << "HEPMC event map node is missing, can't collected HEPMC truth particles"<< std::endl;
637 
638  for (PHHepMCGenEventMap::ConstIter eventIter = hepmceventmap->begin();
639  eventIter != hepmceventmap->end(); ++eventIter) {
640 
642  PHHepMCGenEvent *hepmcevent = eventIter->second;
643 
644  // To fill TTree, require that the event be the primary event (embedding_id > 0)
645  if (hepmcevent && hepmcevent->get_embedding_id() == 0)
646  {
648  HepMC::GenEvent *truthevent = hepmcevent->getEvent();
649  if (!truthevent) {
650  std::cout << PHWHERE
651  << "no evt pointer under phhepmvgeneventmap found "
652  << std::endl;
653  }
654 
656  m_hepmc = 0;
657  for (HepMC::GenEvent::particle_const_iterator iter = truthevent->particles_begin();
658  iter != truthevent->particles_end(); ++iter) {
659 
660  m_hepmc_e[m_hepmc] = (*iter)->momentum().e();
661  m_hepmc_pid[m_hepmc] = (*iter)->pdg_id();
662  m_hepmc_eta[m_hepmc] = (*iter)->momentum().pseudoRapidity();
663  m_hepmc_phi[m_hepmc] = (*iter)->momentum().phi();
664  m_hepmc_pt[m_hepmc] = sqrt((*iter)->momentum().px() * (*iter)->momentum().px()
665  + (*iter)->momentum().py() * (*iter)->momentum().py());
667  m_hepmc++;
668  if (m_hepmc >= 20000) break;
669  }
670  break;
671  }
672  }
673 
674  m_hepmctree->Fill();
675 
676 }
677 
679 
680  PHG4TruthInfoContainer *truthinfo = findNode::getClass<PHG4TruthInfoContainer>(topNode, "G4TruthInfo");
681  if (!truthinfo) std::cout << PHWHERE << "PHG4TruthInfoContainer node is missing, can't collect G4 truth particles"<< std::endl;
682 
684  m_g4 = 0;
685  for (PHG4TruthInfoContainer::ConstIterator iter = range.first;
686  iter != range.second; ++iter) {
687 
688  // Get truth particle
689  const PHG4Particle *truth = iter->second;
690  if (!truthinfo->is_primary(truth)) continue;
691 
693  m_g4_pt[m_g4] = sqrt(truth->get_px() * truth->get_px()
694  + truth->get_py() * truth->get_py());
695  m_g4_e[m_g4] = truth->get_e();
696  m_g4_phi[m_g4] = atan2(truth->get_py(), truth->get_px());
697  m_g4_eta[m_g4] = atanh(truth->get_pz() / truth->get_e());
698  if (m_g4_eta[m_g4] != m_g4_eta[m_g4]) m_g4_eta[m_g4] = -999; // check for nans
699  m_g4_pid[m_g4] = truth->get_pid();
700  m_g4_track_id[m_g4] = truth->get_track_id();
701  m_g4_parent_id[m_g4] = truth->get_parent_id();
702  m_g4++;
703  if (m_g4 >= 20000) break;
704  }
705 
706  PHG4TruthInfoContainer::Range second_range = truthinfo->GetSecondaryParticleRange();
707 
708  for (PHG4TruthInfoContainer::ConstIterator siter = second_range.first;
709  siter != second_range.second; ++siter) {
710  if (m_g4 >= 19999) break;
711  // Get photons from pi0 decays
712  const PHG4Particle *truth = siter->second;
713  if (truth->get_pid() == 22) {
714  PHG4Particle *parent = truthinfo->GetParticle(truth->get_parent_id());
715  if (parent->get_pid() == 111 && parent->get_track_id() > 0) {
716  m_g4_pt[m_g4] = sqrt(truth->get_px() * truth->get_px()
717  + truth->get_py() * truth->get_py());
718  m_g4_e[m_g4] = truth->get_e();
719  m_g4_phi[m_g4] = atan2(truth->get_py(), truth->get_px());
720  m_g4_eta[m_g4] = atanh(truth->get_pz() / truth->get_e());
721  if (m_g4_eta[m_g4] != m_g4_eta[m_g4]) m_g4_eta[m_g4] = -999; // check for nans
722  m_g4_pid[m_g4] = truth->get_pid();
723  m_g4_track_id[m_g4] = truth->get_track_id();
724  m_g4_parent_id[m_g4] = truth->get_parent_id();
725  m_g4++;
726  }
727  }
728  }
729 
730  m_g4tree->Fill();
731 
732 }
733 
735 // Functions extracting additional truth information //
737 
739 
740  PHG4TruthInfoContainer *truthinfo = findNode::getClass<PHG4TruthInfoContainer>(topNode, "G4TruthInfo");
741  if (!truthinfo) std::cout << PHWHERE << "PHG4TruthInfoContainer node is missing, can't collect additional truth particles"<< std::endl;
742  PHG4TruthInfoContainer::Range second_range = truthinfo->GetSecondaryParticleRange();
743 
744  n_child = 0;
745  std::set<int> vertex;
746  if (!vertex.empty()) vertex.clear();
747  for (PHG4TruthInfoContainer::ConstIterator iter = second_range.first; iter != second_range.second; ++iter) {
748  const PHG4Particle *child = iter->second;
749  if (child->get_parent_id() > 0) {
750  vertex.insert(child->get_vtx_id());
751  child_pid[n_child] = child->get_pid();
753  child_vertex_id[n_child] = child->get_vtx_id();
754  child_px[n_child] = child->get_px();
755  child_py[n_child] = child->get_py();
756  child_pz[n_child] = child->get_pz();
757  child_energy[n_child] = child->get_e();
758  n_child++;
759  if (n_child >= 100000) break;
760  }
761  }
762 
763  PHG4TruthInfoContainer::VtxRange vtxrange = truthinfo->GetVtxRange();
764  n_vertex = 0;
765  for (PHG4TruthInfoContainer::ConstVtxIterator iter = vtxrange.first; iter != vtxrange.second; ++iter) {
766  PHG4VtxPoint *vtx = iter->second;
767  if (vertex.find(vtx->get_id()) != vertex.end()) {
768  vertex_x[n_vertex] = vtx->get_x();
769  vertex_y[n_vertex] = vtx->get_y();
770  vertex_z[n_vertex] = vtx->get_z();
771  vertex_id[n_vertex] = vtx->get_id();
772  n_vertex++;
773  if (n_vertex >= 100000) break;
774  }
775  }
776 
777  PHG4HitContainer* blackhole = findNode::getClass<PHG4HitContainer>(topNode, "G4HIT_BH_1");
778  if (!blackhole) std::cout << "No blackhole" << std::endl;
779 
780  _nBH = 0;
781  PHG4HitContainer::ConstRange bh_hit_range = blackhole->getHits();
782  for (PHG4HitContainer::ConstIterator hit_iter = bh_hit_range.first;
783  hit_iter != bh_hit_range.second; hit_iter++) {
784  PHG4Hit *this_hit = hit_iter->second;
785  assert(this_hit);
786  _BH_e[_nBH] = this_hit->get_edep();
787  _BH_px[_nBH] = this_hit->get_px(0);
788  _BH_py[_nBH] = this_hit->get_py(0);
789  _BH_pz[_nBH] = this_hit->get_pz(0);
790  PHG4Particle *p = truthinfo->GetParticle(this_hit->get_trkid());
792  _nBH++;
793  }
794 
795  m_addtruthtree->Fill();
796 }
797 
799 // Track helper functions //
801 
803  float x = projectedState->get_x();// - initialState->get_x();
804  float y = projectedState->get_y();// - initialState->get_y();
805  float z = projectedState->get_z();// - initialState->get_z();
806 
807  float theta = acos(z / sqrt(x*x + y*y + z*z) );
808 
809  return -log( tan(theta/2.0) );
810 }
811 
813  float x = projectedState->get_x();// - initialState->get_x();
814  float y = projectedState->get_y();// - initialState->get_y();
815 
816  return atan2(y,x);
817 }
818 
819 // From SvtxEval.cc
821  float& dca3dxy, float& dca3dz,
822  float& dca3dxysigma, float& dca3dzsigma)
823 {
824  Acts::Vector3 pos(track->get_x(),
825  track->get_y(),
826  track->get_z());
827  Acts::Vector3 mom(track->get_px(),
828  track->get_py(),
829  track->get_pz());
830 
831  auto vtxid = track->get_vertex_id();
832  auto svtxVertex = vertexmap->get(vtxid);
833  if(!svtxVertex)
834  { return; }
835  Acts::Vector3 vertex(svtxVertex->get_x(),
836  svtxVertex->get_y(),
837  svtxVertex->get_z());
838 
839  pos -= vertex;
840 
841  Acts::ActsSymMatrix<3> posCov;
842  for(int i = 0; i < 3; ++i)
843  {
844  for(int j = 0; j < 3; ++j)
845  {
846  posCov(i, j) = track->get_error(i, j);
847  }
848  }
849 
850  Acts::Vector3 r = mom.cross(Acts::Vector3(0.,0.,1.));
851  float phi = atan2(r(1), r(0));
852 
854  Acts::RotationMatrix3 rot_T;
855  rot(0,0) = cos(phi);
856  rot(0,1) = -sin(phi);
857  rot(0,2) = 0;
858  rot(1,0) = sin(phi);
859  rot(1,1) = cos(phi);
860  rot(1,2) = 0;
861  rot(2,0) = 0;
862  rot(2,1) = 0;
863  rot(2,2) = 1;
864 
865  rot_T = rot.transpose();
866 
867  Acts::Vector3 pos_R = rot * pos;
868  Acts::ActsSymMatrix<3> rotCov = rot * posCov * rot_T;
869 
870  dca3dxy = pos_R(0);
871  dca3dz = pos_R(2);
872  dca3dxysigma = sqrt(rotCov(0,0));
873  dca3dzsigma = sqrt(rotCov(2,2));
874 
875 }
876 
877 
879 // Function to set tree branches //
881 
883 {
885  // Central tree //
887  m_centraltree = new TTree("centraltree", "Tree of centralities");
888  m_centraltree->Branch("centrality", &centrality, "centrality/F");
889 
891  // Track tree //
893  m_tracktree = new TTree("tracktree", "Tree of svtx tracks");
894 
895  m_tracktree->Branch("m_trkmult", &m_trkmult, "m_trkmult/I");
896 
897  // Basic properties
898  m_tracktree->Branch("m_tr_p", m_tr_p, "m_tr_p[m_trkmult]/F");
899  m_tracktree->Branch("m_tr_pt", m_tr_pt, "m_tr_pt[m_trkmult]/F");
900  m_tracktree->Branch("m_tr_eta", m_tr_eta, "m_tr_eta[m_trkmult]/F");
901  m_tracktree->Branch("m_tr_phi", m_tr_phi, "m_tr_phi[m_trkmult]/F");
902  m_tracktree->Branch("m_tr_charge", m_tr_charge, "m_tr_charge[m_trkmult]/I");
903  m_tracktree->Branch("m_tr_chisq", m_tr_chisq, "m_tr_chisq[m_trkmult]/F");
904  m_tracktree->Branch("m_tr_ndf", m_tr_ndf, "m_tr_ndf[m_trkmult]/I");
905  m_tracktree->Branch("m_tr_silicon_hits", m_tr_silicon_hits, "m_tr_silicon_hits[m_trkmult]/I");
906 
907  // Distance of closest approach
908  m_tracktree->Branch("m_tr_dca_xy", m_tr_dca_xy, "m_tr_dca_xy[m_trkmult]/F");
909  m_tracktree->Branch("m_tr_dca_xy_error", m_tr_dca_xy_error, "m_tr_dc_xy_error[m_trkmult]/F");
910  m_tracktree->Branch("m_tr_dca_z", m_tr_dca_z, "m_tr_dca_z[m_trkmult]/F");
911  m_tracktree->Branch("m_tr_dca_z_error", m_tr_dca_z_error, "m_tr_dca_z_error[m_trkmult]/F");
912 
913  // Initial point of track
914  m_tracktree->Branch("m_tr_x", m_tr_x, "m_tr_x[m_trkmult]/F");
915  m_tracktree->Branch("m_tr_y", m_tr_y, "m_tr_y[m_trkmult]/F");
916  m_tracktree->Branch("m_tr_z", m_tr_z, "m_tr_z[m_trkmult]/F");
917 
918  // Vertex id of track
919  m_tracktree->Branch("m_tr_vertex_id", m_tr_vertex_id, "m_tr_vertex_id[m_trkmult]/I");
920 
921  // Vertex ids and positions, also stored on track tree
922  m_tracktree->Branch("m_vtxmult", &m_vtxmult, "m_vtxmult/I");
923  m_tracktree->Branch("m_vertex_id", m_vertex_id, "m_vertex_id[m_vtxmult]/I");
924  m_tracktree->Branch("m_vx", m_vx, "m_vx[m_vtxmult]/F");
925  m_tracktree->Branch("m_vy", m_vy, "m_vy[m_vtxmult]/F");
926  m_tracktree->Branch("m_vz", m_vz, "m_vz[m_vtxmult]/F");
927 
928  // Projection of track to calorimeters
929  // CEMC
930  m_tracktree->Branch("m_tr_cemc_eta", m_tr_cemc_eta, "m_tr_cemc_eta[m_trkmult]/F");
931  m_tracktree->Branch("m_tr_cemc_phi", m_tr_cemc_phi, "m_tr_cemc_phi[m_trkmult]/F");
932  // Inner HCAL
933  m_tracktree->Branch("m_tr_ihcal_eta", m_tr_ihcal_eta, "m_tr_ihcal_eta[m_trkmult]/F");
934  m_tracktree->Branch("m_tr_ihcal_phi", m_tr_ihcal_phi, "m_tr_ihcal_phi[m_trkmult]/F");
936  m_tracktree->Branch("m_tr_ohcal_eta", m_tr_ohcal_eta, "m_tr_ohcal_eta[m_trkmult]/F");
937  m_tracktree->Branch("m_tr_ohcal_phi", m_tr_ohcal_phi, "m_tr_ohcal_phi[m_trkmult]/F");
938 
939  // Matched truth track
940  m_tracktree->Branch("m_tr_truth_pid", m_tr_truth_pid, "m_tr_truth_pid[m_trkmult]/I");
941  m_tracktree->Branch("m_tr_truth_is_primary",m_tr_truth_is_primary,"m_tr_truth_is_primary[m_trkmult]/I");
942  m_tracktree->Branch("m_tr_truth_e", m_tr_truth_e, "m_tr_truth_e[m_trkmult]/F");
943  m_tracktree->Branch("m_tr_truth_pt", m_tr_truth_pt, "m_tr_truth_pt[m_trkmult]/F");
944  m_tracktree->Branch("m_tr_truth_eta", m_tr_truth_eta, "m_tr_truth_eta[m_trkmult]/F");
945  m_tracktree->Branch("m_tr_truth_phi", m_tr_truth_phi, "m_tr_truth_phi[m_trkmult]/F");
946  m_tracktree->Branch("m_tr_truth_track_id", m_tr_truth_track_id, "m_tr_truth_track_id[m_trkmult]/I");
947 
949  // Cluster tree //
951  m_clustertree = new TTree("clustertree", "Tree of raw clusters");
952 
953  // CEMC clusters
954  m_clustertree->Branch("m_clsmult_cemc", &m_clsmult_cemc, "m_clsmult_cemc/I");
955  m_clustertree->Branch("m_cl_cemc_e", m_cl_cemc_e, "m_cl_cemc_e[m_clsmult_cemc]/F");
956  m_clustertree->Branch("m_cl_cemc_eta", m_cl_cemc_eta, "m_cl_cemc_eta[m_clsmult_cemc]/F");
957  m_clustertree->Branch("m_cl_cemc_phi", m_cl_cemc_phi, "m_cl_cemc_phi[m_clsmult_cemc]/F");
958  m_clustertree->Branch("m_cl_cemc_r", m_cl_cemc_r, "m_cl_cemc_r[m_clsmult_cemc]/F");
959  m_clustertree->Branch("m_cl_cemc_z", m_cl_cemc_z, "m_cl_cemc_z[m_clsmult_cemc]/F");
960 
961  // Inner HCAL clusters
962  m_clustertree->Branch("m_clsmult_ihcal", &m_clsmult_ihcal, "m_clsmult_ihcal/I");
963  m_clustertree->Branch("m_cl_ihcal_e", m_cl_ihcal_e, "m_cl_ihcal_e[m_clsmult_ihcal]/F");
964  m_clustertree->Branch("m_cl_ihcal_eta", m_cl_ihcal_eta, "m_cl_ihcal_eta[m_clsmult_ihcal]/F");
965  m_clustertree->Branch("m_cl_ihcal_phi", m_cl_ihcal_phi, "m_cl_ihcal_phi[m_clsmult_ihcal]/F");
966  m_clustertree->Branch("m_cl_ihcal_r", m_cl_ihcal_r, "m_cl_ihcal_r[m_clsmult_ihcal]/F");
967  m_clustertree->Branch("m_cl_ihcal_z", m_cl_ihcal_z, "m_cl_ihcal_z[m_clsmult_ihcal]/F");
968 
969  // Outer HCAL clusters
970  m_clustertree->Branch("m_clsmult_ohcal", &m_clsmult_ohcal, "m_clsmult_ohcal/I");
971  m_clustertree->Branch("m_cl_ohcal_e", m_cl_ohcal_e, "m_cl_ohcal_e[m_clsmult_ohcal]/F");
972  m_clustertree->Branch("m_cl_ohcal_eta", m_cl_ohcal_eta, "m_cl_ohcal_eta[m_clsmult_ohcal]/F");
973  m_clustertree->Branch("m_cl_ohcal_phi", m_cl_ohcal_phi, "m_cl_ohcal_phi[m_clsmult_ohcal]/F");
974  m_clustertree->Branch("m_cl_ohcal_r", m_cl_ohcal_r, "m_cl_ohcal_r[m_clsmult_ohcal]/F");
975  m_clustertree->Branch("m_cl_ohcal_z", m_cl_ohcal_z, "m_cl_ohcal_z[m_clsmult_ohcal]/F");
976 
978  // Tower tree //
980  m_towertree = new TTree("towertree", "Tree of raw towers");
981 
982  // CEMC towers
983  m_towertree->Branch("m_twrmult_cemc", &m_twrmult_cemc, "m_twrmult_cemc/I");
984  m_towertree->Branch("m_twr_cemc_e", m_twr_cemc_e, "m_twr_cemc_e[m_twrmult_cemc]/F");
985  m_towertree->Branch("m_twr_cemc_eta", m_twr_cemc_eta, "m_twr_cemc_eta[m_twrmult_cemc]/F");
986  m_towertree->Branch("m_twr_cemc_phi", m_twr_cemc_phi, "m_twr_cemc_phi[m_twrmult_cemc]/F");
987  m_towertree->Branch("m_twr_cemc_ieta", m_twr_cemc_ieta, "m_twr_cemc_ieta[m_twrmult_cemc]/I");
988  m_towertree->Branch("m_twr_cemc_iphi", m_twr_cemc_iphi, "m_twr_cemc_iphi[m_twrmult_cemc]/I");
989 
990  // Inner HCAL towers
991  m_towertree->Branch("m_twrmult_ihcal", &m_twrmult_ihcal, "m_twrmult_ihcal/I");
992  m_towertree->Branch("m_twr_ihcal_e", m_twr_ihcal_e, "m_twr_ihcal_e[m_twrmult_ihcal]/F");
993  m_towertree->Branch("m_twr_ihcal_eta", m_twr_ihcal_eta, "m_twr_ihcal_eta[m_twrmult_ihcal]/F");
994  m_towertree->Branch("m_twr_ihcal_phi", m_twr_ihcal_phi, "m_twr_ihcal_phi[m_twrmult_ihcal]/F");
995  m_towertree->Branch("m_twr_ihcal_ieta", m_twr_ihcal_ieta, "m_twr_ihcal_ieta[m_twrmult_ihcal]/I");
996  m_towertree->Branch("m_twr_ihcal_iphi", m_twr_ihcal_iphi, "m_twr_ihcal_iphi[m_twrmult_ihcal]/I");
997 
998  // Outer HCAL towers
999  m_towertree->Branch("m_twrmult_ohcal", &m_twrmult_ohcal, "m_twrmult_ohcal/I");
1000  m_towertree->Branch("m_twr_ohcal_e", m_twr_ohcal_e, "m_twr_ohcal_e[m_twrmult_ohcal]/F");
1001  m_towertree->Branch("m_twr_ohcal_eta", m_twr_ohcal_eta, "m_twr_ohcal_eta[m_twrmult_ohcal]/F");
1002  m_towertree->Branch("m_twr_ohcal_phi", m_twr_ohcal_phi, "m_twr_ohcal_phi[m_twrmult_ohcal]/F");
1003  m_towertree->Branch("m_twr_ohcal_ieta", m_twr_ohcal_ieta, "m_twr_ohcal_ieta[m_twrmult_ohcal]/I");
1004  m_towertree->Branch("m_twr_ohcal_iphi", m_twr_ohcal_iphi, "m_twr_ohcal_iphi[m_twrmult_ohcal]/I");
1005 
1007  // Sim tower tree //
1009  m_simtowertree = new TTree("simtowertree", "Tree of raw simtowers");
1010 
1011  // CEMC simtowers
1012  m_simtowertree->Branch("m_simtwrmult_cemc", &m_simtwrmult_cemc, "m_simtwrmult_cemc/I");
1013  m_simtowertree->Branch("m_simtwr_cemc_e", m_simtwr_cemc_e, "m_simtwr_cemc_e[m_simtwrmult_cemc]/F");
1014  m_simtowertree->Branch("m_simtwr_cemc_eta", m_simtwr_cemc_eta, "m_simtwr_cemc_eta[m_simtwrmult_cemc]/F");
1015  m_simtowertree->Branch("m_simtwr_cemc_phi", m_simtwr_cemc_phi, "m_simtwr_cemc_phi[m_simtwrmult_cemc]/F");
1016  m_simtowertree->Branch("m_simtwr_cemc_ieta", m_simtwr_cemc_ieta, "m_simtwr_cemc_ieta[m_simtwrmult_cemc]/I");
1017  m_simtowertree->Branch("m_simtwr_cemc_iphi", m_simtwr_cemc_iphi, "m_simtwr_cemc_iphi[m_simtwrmult_cemc]/I");
1018 
1019  // Inner HCAL simtowers
1020  m_simtowertree->Branch("m_simtwrmult_ihcal", &m_simtwrmult_ihcal, "m_simtwrmult_ihcal/I");
1021  m_simtowertree->Branch("m_simtwr_ihcal_e", m_simtwr_ihcal_e, "m_simtwr_ihcal_e[m_simtwrmult_ihcal]/F");
1022  m_simtowertree->Branch("m_simtwr_ihcal_eta", m_simtwr_ihcal_eta, "m_simtwr_ihcal_eta[m_simtwrmult_ihcal]/F");
1023  m_simtowertree->Branch("m_simtwr_ihcal_phi", m_simtwr_ihcal_phi, "m_simtwr_ihcal_phi[m_simtwrmult_ihcal]/F");
1024  m_simtowertree->Branch("m_simtwr_ihcal_ieta", m_simtwr_ihcal_ieta, "m_simtwr_ihcal_ieta[m_simtwrmult_ihcal]/I");
1025  m_simtowertree->Branch("m_simtwr_ihcal_iphi", m_simtwr_ihcal_iphi, "m_simtwr_ihcal_iphi[m_simtwrmult_ihcal]/I");
1026 
1027  // Outer HCAL simtowers
1028  m_simtowertree->Branch("m_simtwrmult_ohcal", &m_simtwrmult_ohcal, "m_simtwrmult_ohcal/I");
1029  m_simtowertree->Branch("m_simtwr_ohcal_e", m_simtwr_ohcal_e, "m_simtwr_ohcal_e[m_simtwrmult_ohcal]/F");
1030  m_simtowertree->Branch("m_simtwr_ohcal_eta", m_simtwr_ohcal_eta, "m_simtwr_ohcal_eta[m_simtwrmult_ohcal]/F");
1031  m_simtowertree->Branch("m_simtwr_ohcal_phi", m_simtwr_ohcal_phi, "m_simtwr_ohcal_phi[m_simtwrmult_ohcal]/F");
1032  m_simtowertree->Branch("m_simtwr_ohcal_ieta", m_simtwr_ohcal_ieta, "m_simtwr_ohcal_ieta[m_simtwrmult_ohcal]/I");
1033  m_simtowertree->Branch("m_simtwr_ohcal_iphi", m_simtwr_ohcal_iphi, "m_simtwr_ohcal_iphi[m_simtwrmult_ohcal]/I");
1034 
1036  // HepMC particle tree //
1038 
1039  m_hepmctree = new TTree("hepmctree","Tree of truth hepmc info and particles");
1040  m_hepmctree->Branch("m_hepmc",&m_hepmc, "m_hepmc/I");
1041  m_hepmctree->Branch("m_hepmc_pid", m_hepmc_pid, "m_hepmc_pid[m_hepmc]/I");
1042  m_hepmctree->Branch("m_hepmc_e", m_hepmc_e, "m_hepmc_e[m_hepmc]/F");
1043  m_hepmctree->Branch("m_hepmc_pt", m_hepmc_pt, "m_hepmc_pt[m_hepmc]/F");
1044  m_hepmctree->Branch("m_hepmc_eta", m_hepmc_eta, "m_hepmc_eta[m_hepmc]/F");
1045  m_hepmctree->Branch("m_hepmc_phi", m_hepmc_phi, "m_hepmc_phi[m_hepmc]/F");
1046 
1048  // G4 particle tree //
1050 
1051  m_g4tree = new TTree("g4tree","Tree of truth G4 particles");
1052  m_g4tree->Branch("m_g4",&m_g4, "m_g4/I");
1053  m_g4tree->Branch("m_g4_pid", m_g4_pid, "m_g4_pid[m_g4]/I");
1054  m_g4tree->Branch("m_g4_e", m_g4_e, "m_g4_e[m_g4]/F");
1055  m_g4tree->Branch("m_g4_pt", m_g4_pt, "m_g4_pt[m_g4]/F");
1056  m_g4tree->Branch("m_g4_eta", m_g4_eta, "m_g4_eta[m_g4]/F");
1057  m_g4tree->Branch("m_g4_phi", m_g4_phi, "m_g4_phi[m_g4]/F");
1058  m_g4tree->Branch("m_g4_track_id", m_g4_track_id, "m_g4_track_id[m_g4]/I");
1059  m_g4tree->Branch("m_g4_parent_id", m_g4_parent_id, "m_g4_parent_id[m_g4]/I");
1060 
1062  // Additional truth tree //
1064 
1065  m_addtruthtree = new TTree("addtruthtree", "Tree of additional truth information");
1066 
1067  // child information
1068  m_addtruthtree->Branch("n_child",&n_child,"n_child/I");
1069  m_addtruthtree->Branch("child_pid",child_pid,"child_pid[n_child]/I");
1070  m_addtruthtree->Branch("child_parent_id",child_parent_id,"child_parent_id[n_child]/I");
1071  m_addtruthtree->Branch("child_vertex_id",child_vertex_id,"child_vertex_id[n_child]/I");
1072  m_addtruthtree->Branch("child_px",child_px,"child_px[n_child]/F");
1073  m_addtruthtree->Branch("child_py",child_py,"child_py[n_child]/F");
1074  m_addtruthtree->Branch("child_pz",child_pz,"child_pz[n_child]/F");
1075  m_addtruthtree->Branch("child_energy",child_energy,"child_energy[n_child]/F");
1076 
1077  // vertex information
1078  m_addtruthtree->Branch("n_vertex",&n_vertex,"n_vertex/I");
1079  m_addtruthtree->Branch("vertex_id",vertex_id,"vertex_id[n_vertex]/I");
1080  m_addtruthtree->Branch("vertex_x",vertex_x,"vertex_x[n_vertex]/F");
1081  m_addtruthtree->Branch("vertex_y",vertex_y,"vertex_y[n_vertex]/F");
1082  m_addtruthtree->Branch("vertex_z",vertex_z,"vertex_z[n_vertex]/F");
1083 
1084  // blackhole information
1085  m_addtruthtree->Branch("_nBH",&_nBH,"_nBH/I");
1086  m_addtruthtree->Branch("BH_track_id",_BH_track_id,"BH_track_id[_nBH]/I");
1087  m_addtruthtree->Branch("BH_px",_BH_px,"BH_px[_nBH]/F");
1088  m_addtruthtree->Branch("BH_py",_BH_py,"BH_py[_nBH]/F");
1089  m_addtruthtree->Branch("BH_pz",_BH_pz,"BH_pz[_nBH]/F");
1090  m_addtruthtree->Branch("BH_e",_BH_e,"BH_e[_nBH]/F");
1091 
1092 
1093 }