Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pi0Efficiency.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file pi0Efficiency.cc
1 #include "pi0Efficiency.h"
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 
19 //for emc clusters
20 #include <calobase/RawCluster.h>
21 #include <calobase/RawClusterContainer.h>
22 #include <calobase/RawClusterUtility.h>
23 #include <calobase/RawTowerGeomContainer.h>
24 #include <calobase/RawTower.h>
25 #include <calobase/RawTowerContainer.h>
26 
27 //caloEvalStack for cluster to truth matching
28 #include <g4eval/CaloEvalStack.h>
30 
31 //for vetex information
32 #include <g4vertex/GlobalVertex.h>
33 #include <g4vertex/GlobalVertexMap.h>
34 
35 //tracking
38 #include <trackbase_historic/SvtxVertex.h>
39 #include <trackbase_historic/SvtxVertexMap.h>
40 
41 //truth information
43 #include <g4main/PHG4Particle.h>
44 #include </gpfs/mnt/gpfs02/sphenix/user/ahodges/macros_git/coresoftware/generators/phhepmc/PHHepMCGenEvent.h>
45 #include </gpfs/mnt/gpfs02/sphenix/user/ahodges/macros_git/coresoftware/generators/phhepmc/PHHepMCGenEventMap.h>
46 #include <g4main/PHG4VtxPoint.h>
47 #include <HepMC/GenEvent.h>
48 #include <HepMC/GenParticle.h>
49 #include <HepMC/GenVertex.h>
50 #include <HepMC/IteratorRange.h>
51 #include <HepMC/SimpleVector.h>
52 #include <HepMC/GenParticle.h>
53 #include <CLHEP/Geometry/Point3D.h>
54 
55 //____________________________________________________________________________..
57 SubsysReco(name),
58  OutFile(outName)
59 {
60  std::cout << "pi0Efficiency::pi0Efficiency(const std::string &name) Calling ctor" << std::endl;
61 
62 
63  for(int j = 0; j < nEtaBins; j++) ePi0InvMassEcut[j] = 0;
64 
65  photonE = 0;
66 
67  for(int i = 0; i < nEtaBins; i++)prim_pi0_E[i] = 0;
68 
69  clusterE = 0;
70 
71  truthPi0EAsym = 0;
72 
73  truthPi0EDeltaR = 0;
74 
75  hMassRat = 0;
76 
77  pi0EScale = 0;
78 }
79 
80 //____________________________________________________________________________..
82 {
83  std::cout << "pi0Efficiency::~pi0Efficiency() Calling dtor" << std::endl;
84 }
85 
86 //____________________________________________________________________________..
88 {
89  std::cout << "pi0Efficiency::Init(PHCompositeNode *topNode) Initializing" << std::endl;
90 
91 
92 
93  for(int j = 0; j < nEtaBins; j++)
94  {
95  ePi0InvMassEcut[j] = new TH3F(Form("ePi0InvMassEcut_Eta%d",j),Form("Pi0 energy vs. Inv Mass vs. Min pho Energy Eta%d", j), 500,0,50,500,-0.1,1,200,0,20);
96  }
97 
98  clusterE = new TH1F("clusterE","Cluster Energy",200,0,20);
99 
100  for(int i = 0; i < nEtaBins; i++)prim_pi0_E[i] = new TH1F(Form("primPi0E_Eta%d",i),"Primary pi0 Energy",200,0,20);
101 
102  photonE = new TH1F("photonE","Decay Photon Energy",200,0,20);
103 
104  pi0EScale = new TH2F("pi0EScale","Pi0 energy fraction",200,0,2,200,0,20);
105 
106  truthPi0EDeltaR = new TH2F("truthPi0EDeltaR","truth pi0 energy versus decay opening angle",200,0,20,100,0,.5);
107 
108  truthPi0EAsym = new TH2F("truthPi0EAsym","truth pi0 energy vs. decay energy asymmetry",200,0,20,200,0,1);
109 
110  hMassRat = new TH1F("hMassRat","ratio of pi0 mass reco from truth photons to primary mass",200,0,2);
111 
113  se -> Print("NODETREE");
114  hm = new Fun4AllHistoManager("MYHISTOS");
115 
116  se -> registerHistoManager(hm);
117 
118  se -> registerHisto(clusterE -> GetName(), clusterE);
119 
120  for(int i = 0; i < nEtaBins; i++)se -> registerHisto(prim_pi0_E[i] -> GetName(), prim_pi0_E[i]);
121 
122  se -> registerHisto(photonE -> GetName(), photonE);
123 
124  for(int j = 0; j < nEtaBins; j++) se -> registerHisto(ePi0InvMassEcut[j] -> GetName(), ePi0InvMassEcut[j]);
125 
126  se -> registerHisto(truthPi0EAsym->GetName(), truthPi0EAsym);
127 
128  se -> registerHisto(hMassRat -> GetName(), hMassRat);
129 
130  se -> registerHisto(truthPi0EDeltaR -> GetName(), truthPi0EDeltaR);
131 
132  out = new TFile(OutFile.c_str(),"RECREATE");
133 
135 }
136 
137 //____________________________________________________________________________..
139 {
140  std::cout << "pi0Efficiency::InitRun(PHCompositeNode *topNode) Initializing for Run XXX" << std::endl;
142 }
143 
144 //____________________________________________________________________________..
146 {
147  std::cout << "pi0Efficiency::process_event(PHCompositeNode *topNode) Processing Event" << std::endl;
148 
149 
150  //Information on clusters
151  RawClusterContainer *clusterContainer = findNode::getClass<RawClusterContainer>(topNode,"CLUSTER_POS_COR_CEMC");
152  //RawClusterContainer *clusterContainer = findNode::getClass<RawClusterContainer>(topNode,"CLUSTER_CEMC");
153  if(!clusterContainer)
154  {
155  std::cout << PHWHERE << "pi0Efficiency::process_event - Fatal Error - CLUSTER_POS_COR_CEMC node is missing. " << std::endl;
156 
157  return 0;
158  }
159 
160 
161  //Vertex information
162  GlobalVertexMap *vtxContainer = findNode::getClass<GlobalVertexMap>(topNode,"GlobalVertexMap");
163  if (!vtxContainer)
164  {
165  std::cout << PHWHERE << "pi0Efficiency::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;
166  assert(vtxContainer); // force quit
167 
168  return 0;
169  }
170 
171  if (vtxContainer->empty())
172  {
173  std::cout << PHWHERE << "pi0Efficiency::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;
174  return 0;
175  }
176 
177  //More vertex information
178  GlobalVertex *vtx = vtxContainer->begin()->second;
179  if(!vtx)
180  {
181 
182  std::cout << PHWHERE << "pi0Efficiency::process_event Could not find vtx from vtxContainer" << std::endl;
184  }
185 
186  //Tower geometry node for location information
187  RawTowerGeomContainer *towergeom = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_CEMC");
188  if (!towergeom)
189  {
190  std::cout << PHWHERE << "pi0Efficiency::process_event Could not find node TOWERGEOM_CEMC" << std::endl;
192  }
193 
194  //Raw tower information
195  RawTowerContainer *towerContainer = findNode::getClass<RawTowerContainer>(topNode,"TOWER_CALIB_CEMC");
196  if(!towerContainer)
197  {
198  std::cout << PHWHERE << "pi0Efficiency::process_event Could not find node TOWER_CALIB_CEMC" << std::endl;
200  }
201 
202  //truth particle information
203  PHG4TruthInfoContainer *truthinfo = findNode::getClass<PHG4TruthInfoContainer>(topNode, "G4TruthInfo");
204  if(!truthinfo)
205  {
206  std::cout << PHWHERE << "pi0Efficiency::process_event Could not find node G4TruthInfo" << std::endl;
208  }
209 
210  int firstphotonflag = 0;
211  int firstfirstphotonflag = 0;
212  int secondphotonflag = 0;
213  int secondsecondphotonflag = 0;
214 
215  PHG4TruthInfoContainer::Range truthRangeDecay1 = truthinfo->GetSecondaryParticleRange();
217 
218  float photonEtaMax = 1.1;
219  float mesonEtaMax = 0.3;
220  TLorentzVector photon1;
221  TLorentzVector photon2;
222 
223  for(truthIterDecay1 = truthRangeDecay1.first; truthIterDecay1 != truthRangeDecay1.second; truthIterDecay1++)
224  {
225 
226  PHG4Particle *decay = truthIterDecay1 -> second;
227 
228  int dumtruthpid = decay -> get_pid();
229  int dumparentid = decay -> get_parent_id();
230 
231  //if the parent is the pi0 and it's a photon and we haven't marked one yet
232  if(dumparentid == 1 && dumtruthpid == 22 && !firstphotonflag)
233  {
234  if(abs(getEta(decay)) > photonEtaMax)
235  {
236  std::cout << "Photon 1 outside acceptance " << std::endl;
237  return 0; //decay product outside acceptance.
238  }
239  photon1.SetPxPyPzE(decay -> get_px(), decay -> get_py(), decay -> get_pz(), decay -> get_e());
240 
241  firstphotonflag = 1;
242  }
243 
244  if(dumparentid == 1 && dumtruthpid == 22 && firstphotonflag && firstfirstphotonflag)
245  {
246  if(abs(getEta(decay)) > photonEtaMax)
247  {
248  std::cout << "Photon 2 outside acceptance " << std::endl;
249  return 0; //decay product outside acceptance
250  }
251  photon2.SetPxPyPzE(decay -> get_px(), decay -> get_py(), decay -> get_pz(), decay -> get_e()) ;
252 
253  secondphotonflag = 1;
254  }
255 
256  //deal with dalitz decays
257  if(dumparentid == 1 && firstphotonflag && secondphotonflag && secondsecondphotonflag)
258  {
259  std::cout << "Dalitz decay, skipping event" << std::endl;
260  return 0;
261  }
262 
263 
264 
265  //Need these extra flags, otherwise the dalitz
266  //check will always have first and second photon
267  //flags marked true, so this allows the dalitz check
268  //to occur after marking the second truth photon
269  //as a decay component
270  if(firstphotonflag) firstfirstphotonflag = 1;
271  if(secondphotonflag) secondsecondphotonflag = 1;
272  }
273  photonE -> Fill(photon1.Energy());
274  photonE -> Fill(photon2.Energy());
275  float asym = abs(photon1.Energy() - photon2.Energy())/(photon1.Energy() + photon2.Energy());
276  float deltaR = photon1.DeltaR(photon2);
277 
278  //Now we go and find all our truth pi0s
279  PHG4TruthInfoContainer::Range truthRange = truthinfo->GetPrimaryParticleRange();
281  std::vector<int> mPi0Barcode;
282  Double_t pi0Mass = 0;
283  PHG4Particle *truthPar = NULL;
284  TLorentzVector truePi0;
285 
286  for(truthIter = truthRange.first; truthIter != truthRange.second; truthIter++)
287  {
288  truthPar = truthIter->second;
289 
290  if(truthPar -> get_pid() == 111 && truthPar -> get_parent_id() == 0)//for single particle gun, this list has one particle, the
291  //one of interest, but best be safe out of habit
292  {
293  if(getEta(truthPar) >= mesonEtaMax)
294  {
295  std::cout << "Parent outside allowed spatial limit" << std::endl;
296  return 0;
297  }
298  int etaBin = -1;
299  if(photon1.Energy() >= photon2.Energy())etaBin = getEtaBin(photon1.PseudoRapidity());
300  else etaBin = getEtaBin(photon2.PseudoRapidity());
301  if(etaBin >= 0)prim_pi0_E[etaBin] -> Fill(truthPar -> get_e());
302  prim_pi0_E[nEtaBins-1] -> Fill(truthPar -> get_e());
303 
304  mPi0Barcode.push_back(truthPar -> get_barcode());
305  truePi0.SetPxPyPzE(truthPar -> get_px(), truthPar -> get_py(), truthPar -> get_pz(), truthPar -> get_e());
306  pi0Mass = truePi0.M();//sanity check later to make sure when we reconstruct the pi0 from truth photons we get the pi0 mass back
307 
308  }
309 
310  }
311 
312  truthPi0EDeltaR -> Fill(truePi0.Energy(), deltaR);
313  truthPi0EAsym -> Fill(truePi0.Energy(), asym);
314 
315  //iterate over items in the container.
316  RawClusterContainer::ConstRange clusterEnd = clusterContainer -> getClusters();
318 
319  //remove noise with a 300MeV energy cut and store
320  //good clusters in a vector for later.
321  std::vector<RawCluster*> goodRecoCluster;
322  float minE = 0.3;
323  CLHEP::Hep3Vector vertex(vtx->get_x(), vtx->get_y(), vtx->get_z());
324 
325  for(clusterIter = clusterEnd.first; clusterIter != clusterEnd.second; clusterIter++)
326  {
327  RawCluster *recoCluster = clusterIter -> second;
328 
329  CLHEP::Hep3Vector E_vec_cluster = RawClusterUtility::GetECoreVec(*recoCluster, vertex);
330  float clusE = E_vec_cluster.mag();
331  clusterE -> Fill(clusE);
332  if(clusE < minE) continue;
333 
334  goodRecoCluster.push_back(recoCluster);
335  }
336 
337  for(int i = 0; i < (int)goodRecoCluster.size(); ++i)
338  {
339  //grab the first good cluster.
340  CLHEP::Hep3Vector vertex(vtx->get_x(), vtx->get_y(), vtx->get_z());
341  CLHEP::Hep3Vector E_vec_cluster = RawClusterUtility::GetECoreVec(*goodRecoCluster[i], vertex);
342 
343  TLorentzVector pho1, pho2, pi0;
344  pho1.SetPtEtaPhiE(E_vec_cluster.perp(), E_vec_cluster.pseudoRapidity(), E_vec_cluster.getPhi(), E_vec_cluster.mag());
345 
346  for(int j = 0; j <(int)goodRecoCluster.size(); ++j)
347  {
348 
349  if(j <= i) continue; //make sure we don't get redundant pairs
350  CLHEP::Hep3Vector E_vec_cluster2 = RawClusterUtility::GetECoreVec(*goodRecoCluster[j], vertex);
351 
352  pho2.SetPtEtaPhiE(E_vec_cluster2.perp(), E_vec_cluster2.pseudoRapidity(), E_vec_cluster2.getPhi(), E_vec_cluster2.mag());
353 
354  pi0 = pho1 + pho2;
355 
356  pi0EScale -> Fill(pi0.Energy()/truePi0.Energy(), truePi0.Energy());//check the pi0 energy scale.
357 
358 
359  //isolating spatial kinematics to make sure we're really measuring
360  //sPHENIX's ability to reconstruct pi0's within its volume
361  if(abs(pho1.PseudoRapidity()) < photonEtaMax && abs(pho2.PseudoRapidity()) < photonEtaMax && abs(pi0.PseudoRapidity()) < mesonEtaMax)
362  {
363  int etaBin = -1;
364  //determine psuedorapidity bin from lead photon
365  if(pho1.Energy() >= pho2.Energy()) etaBin = getEtaBin(pho1.PseudoRapidity());
366  else etaBin = getEtaBin(pho2.PseudoRapidity());
367  if(etaBin >= 0)ePi0InvMassEcut[etaBin] -> Fill(pi0.Energy(), pi0.M(),std::min(pho1.Energy(), pho2.Energy()));
368  ePi0InvMassEcut[nEtaBins-1] -> Fill(pi0.Energy(), pi0.M(),std::min(pho1.Energy(), pho2.Energy()));
369  }
370  }
371  }
372 
373 
374 
375 
376 
377  //make sure we aren't messing up the reconstruction :)
378  TLorentzVector pi0fromTruPhoton = photon1 + photon2;
379  hMassRat -> Fill(pi0fromTruPhoton.M()/pi0Mass);
380  //std::cout << "Mass diff " << massdiff << " from truth reco pi0: " << pi0fromTruPhoton.M() << " and truth pi0 mass: " << pi0Mass << std::endl;
381 
382  /*This doesn't work on things that aren't primary particles.
383  //and here's where we do the sneaky business of finding out where the photons went.
384  if(!cluster1 || !cluster2)
385  {
386  if(!cluster1)
387  {
388 
389  unmatchedLocale -> Fill(photon1.PseudoRapidity(), photon1.Phi(), truthPar -> get_e());
390  unmatchedE -> Fill(photon1.E());
391  }
392  if(!cluster2)
393  {
394 
395  unmatchedLocale -> Fill(photon2.PseudoRapidity(), photon2.Phi(), truthPar -> get_e());
396  unmatchedE -> Fill(photon2.E());
397  }
398  ePi0InvMassEcut[1] -> Fill(truthPar -> get_e(), 0., std::min(photon1.Energy(), photon2.Energy()));
399  }
400  else
401  {
402 
403  if(cluster1 -> get_id() == cluster2 -> get_id()) return 0;
404 
405  TLorentzVector cpi0, c1, c2;
406 
407  CLHEP::Hep3Vector eVecCluster1 = RawClusterUtility::GetECoreVec(*cluster1, vertex);
408  CLHEP::Hep3Vector eVecCluster2 = RawClusterUtility::GetECoreVec(*cluster2, vertex);
409 
410  c1.SetPtEtaPhiE(eVecCluster1.perp(), eVecCluster1.pseudoRapidity(), eVecCluster1.getPhi(), eVecCluster1.mag());
411  c2.SetPtEtaPhiE(eVecCluster2.perp(), eVecCluster2.pseudoRapidity(), eVecCluster2.getPhi(), eVecCluster2.mag());
412 
413  cpi0 = c1 + c2;
414 
415  ePi0InvMassEcut[1] -> Fill(cpi0.Energy(), cpi0.M(),std::min(c1.Energy(), c1.Energy()));
416 
417  invMassEPhi -> Fill(cpi0.M(), truthPar -> get_e(), cpi0.Phi());
418  invMassPhoPi0 -> Fill(cpi0.M(), cpi0.Energy()/truthPar -> get_e(), c1.Energy()/photon1.Energy());
419  invMassPhoPi0 -> Fill(cpi0.M(), cpi0.Energy()/truthPar -> get_e(), c1.Energy()/photon2.Energy());
420  }*/
421  /*Supplanting with method developed by Joe Osborn above
422  PHG4TruthInfoContainer::Range truthRangeDecay1 = truthinfo->GetSecondaryParticleRange();
423  PHG4TruthInfoContainer::ConstIterator truthIterDecay1;
424 
425 
426  //Collect truth decay photons
427  std::vector<PHG4Particle*> pi0Pho;
428  std::vector<int> pi0PhoBarcode;
429  for(truthIterDecay1 = truthRangeDecay1.first; truthIterDecay1 != truthRangeDecay1.second; truthIterDecay1++)
430  {
431  PHG4Particle *truthDecay1 = truthIterDecay1 -> second;
432  PHG4Particle *mother = truthinfo -> GetParticle(truthDecay1 -> get_parent_id());
433  int mBarcode = mother -> get_barcode();
434 
435  if(truthDecay1 -> get_parent_id() != 0 && truthDecay1 -> get_pid() == 22 && getEta(truthDecay1) <= etaMax && (std::find(mPi0Barcode.begin(), mPi0Barcode.end(),mBarcode) != mPi0Barcode.end())) //want decay photons w/ strict matching back to a pi0
436  {
437  pi0PhoBarcode.push_back(mBarcode);//this is for the actual pairing process later where we want to match two photons together.
438  photonE -> Fill(truthDecay1 -> get_e());
439  pi0Pho.push_back(truthDecay1);
440 
441 
442  }
443  }
444 
445  //Re-pair decay photons to extract their kinematic information, match to clusters, and hopefully
446  //see what causes inefficiencies. Apparently GEANT considers literally every particle
447  //created after the initial generation a secondary particle, you need to do this pairing and then
448  //find the pair with the invariant mass closes to the pi0's (~O(10-9) difference)
449  float massdiff = 10;
450 
451  for(int i = 0; i < (int)pi0Pho.size(); i++)
452  {
453  for(int j = 0; j < (int)pi0Pho.size(); j++)
454  {
455  if(j <= i) continue;
456 
457  if(pi0PhoBarcode.at(i) != pi0PhoBarcode.at(j)) continue;
458 
459  TLorentzVector tpi0, pho1, pho2;
460  pho1.SetPxPyPzE(pi0Pho.at(i) -> get_px(), pi0Pho.at(i) -> get_py(), pi0Pho.at(i) -> get_pz(), pi0Pho.at(i) -> get_e());
461  pho2.SetPxPyPzE(pi0Pho.at(j) -> get_px(), pi0Pho.at(j) -> get_py(), pi0Pho.at(j) -> get_pz(), pi0Pho.at(j) -> get_e());
462 
463  tpi0 = pho1 + pho2;
464  if(std::floor(100000*tpi0.M()) == std::floor(100000*pi0Mass))
465  {
466  massdiff = abs(tpi0.M() - pi0Mass);
467  RawCluster *cluster1 = clustereval -> best_cluster_from(pi0Pho.at(i));
468  RawCluster *cluster2 = clustereval -> best_cluster_from(pi0Pho.at(j));
469  //.13497
470  if(!cluster1 || !cluster2)
471  {
472  ePi0InvMassEcut[1] -> Fill(tpi0.Energy(), 0., std::min(pi0Pho.at(i) -> get_e(), pi0Pho.at(j) -> get_e()));
473  }
474  else
475  {
476  TLorentzVector cpi0, c1, c2;
477 
478  CLHEP::Hep3Vector eVecCluster1 = RawClusterUtility::GetECoreVec(*cluster1, vertex);
479  CLHEP::Hep3Vector eVecCluster2 = RawClusterUtility::GetECoreVec(*cluster2, vertex);
480 
481  c1.SetPtEtaPhiE(eVecCluster1.perp(), eVecCluster1.pseudoRapidity(), eVecCluster1.getPhi(), eVecCluster1.mag());
482  c2.SetPtEtaPhiE(eVecCluster2.perp(), eVecCluster2.pseudoRapidity(), eVecCluster2.getPhi(), eVecCluster2.mag());
483 
484  cpi0 = c1 + c2;
485 
486  ePi0InvMassEcut[1] -> Fill(cpi0.Energy(),cpi0.M(),std::min(c1.Energy(), c1.Energy()));
487 
488  invMassEPhi -> Fill(cpi0.M(), tpi0.Energy(), cpi0.Phi());
489  invMassPhoPi0 -> Fill(cpi0.M(), cpi0.Energy()/tpi0.Energy(), c1.Energy()/pho1.Energy());
490  invMassPhoPi0 -> Fill(cpi0.M(), cpi0.Energy()/tpi0.Energy(), c1.Energy()/pho2.Energy());
491 
492 
493  }
494  }
495  }
496  }*/
497 
498 
499 
500 
501  goodRecoCluster.clear();
503 }
504 
505 //____________________________________________________________________________..
507 {
509 }
510 
511 //____________________________________________________________________________..
513 {
514  std::cout << "pi0Efficiency::EndRun(const int runnumber) Ending Run for Run " << runnumber << std::endl;
516 }
517 
518 //____________________________________________________________________________..
520 {
521  std::cout << "pi0Efficiency::End(PHCompositeNode *topNode) This is the End..." << std::endl;
522 
523  out -> cd();
524 
525 
526  for(int j = 0; j < nEtaBins; j++) ePi0InvMassEcut[j] -> Write();
527 
528  clusterE -> Write();
529  for(int i = 0; i < nEtaBins; i++)prim_pi0_E[i] -> Write();
530  photonE -> Write();
531  pi0EScale -> Write();
533  hMassRat -> Write();
534  truthPi0EDeltaR -> Write();
535  truthPi0EAsym -> Write();
536  //unmatchedE -> Write();
537 
538 
539 
541 }
542 
543 //____________________________________________________________________________..
545 {
546  std::cout << "pi0Efficiency::Reset(PHCompositeNode *topNode) being Reset" << std::endl;
548 }
549 
550 //____________________________________________________________________________..
551 void pi0Efficiency::Print(const std::string &what) const
552 {
553  std::cout << "pi0Efficiency::Print(const std::string &what) const Printing info for " << what << std::endl;
554 }
555 //____________________________________________________________________________..
557 {
558  float px = particle -> get_px();
559  float py = particle -> get_py();
560  float pz = particle -> get_pz();
561  float p = sqrt(pow(px,2) + pow(py,2) + pow(pz,2));
562 
563  return 0.5*log((p+pz)/(p-pz));
564 }
565 //____________________________________________________________________________..
567 {
568  for(int i = 0; i < nEtaBins-1; i++)
569  {
570  if(abs(eta) < (i+1)/(float)(nEtaBins-1) * 1.1 && abs(eta) >= (i+1-1)/(float)(nEtaBins-1) * 1.1) return i;
571  }
572  return -1;
573 }