Belle II Software  release-06-02-00
MCParticle.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <mdst/dataobjects/MCParticle.h>
10 #include <framework/logging/Logger.h>
11 #include <framework/datastore/DataStore.h>
12 #include <framework/datastore/StoreArray.h>
13 #include <framework/utilities/HTML.h>
14 
15 #include <TDatabasePDG.h>
16 
17 #include <iostream>
18 #include <sstream>
19 
20 using namespace std;
21 using namespace Belle2;
22 
23 const double MCParticle::c_epsilon = 10e-7;
24 
25 
26 void MCParticle::setMassFromPDG()
27 {
28  if (TDatabasePDG::Instance()->GetParticle(m_pdg) == nullptr)
29  throw(ParticlePDGNotKnownError() << m_pdg);
30  m_mass = TDatabasePDG::Instance()->GetParticle(m_pdg)->Mass();
31 }
32 
33 
34 float MCParticle::getCharge() const
35 {
36  // Geant4 "optical photon" (m_pdg == 0) is not known to TDatabasePDG::Instance().
37  if (m_pdg == 0) {
38  return 0.0;
39  }
40 
41  if (TDatabasePDG::Instance()->GetParticle(m_pdg) == nullptr) {
42  B2ERROR("PDG=" << m_pdg << " ***code unknown to TDatabasePDG");
43  return 0.0;
44  }
45 
46  return TDatabasePDG::Instance()->GetParticle(m_pdg)->Charge() / 3.0;
47 }
48 
49 
50 vector<MCParticle*> MCParticle::getDaughters() const
51 {
52  vector<MCParticle*> result;
53  if (m_firstDaughter > 0) {
54  fixParticleList();
55  if (m_lastDaughter > m_plist->GetEntriesFast()) throw LastChildIndexOutOfRangError();
56  TClonesArray& plist = *m_plist;
57  result.reserve(m_lastDaughter - m_firstDaughter + 1);
58  for (int i = m_firstDaughter - 1; i < m_lastDaughter; i++) {
59  result.push_back(static_cast<MCParticle*>(plist[i]));
60  }
61  }
62  return result;
63 }
64 
65 int MCParticle::getNDaughters() const
66 {
67  if (getFirstDaughter() == 0) //no daughters
68  return 0;
69  return getLastDaughter() - getFirstDaughter() + 1;
70 }
71 
72 void MCParticle::fixParticleList() const
73 {
74  if (m_plist != 0) return;
75 
76  TClonesArray* plist(0);
77 
78  //Search default location
79  //TODO: this could be replaced with RelationsObject::getArrayIndex()/getArrayName()
80  StoreArray<MCParticle> MCParticles;
81  if (MCParticles && MCParticles.getPtr()->IndexOf(this) >= 0) {
82  plist = MCParticles.getPtr();
83  } else {
84  //Search all StoreArrays which happen to store MCParticles
85  const DataStore::StoreEntryMap& map = DataStore::Instance().getStoreEntryMap(DataStore::c_Event);
86  for (DataStore::StoreEntryConstIter iter = map.begin(); iter != map.end(); ++iter) {
87  TClonesArray* value = dynamic_cast<TClonesArray*>(iter->second.ptr);
88  if (value && value->GetClass() == Class() && value->IndexOf(this) >= 0) {
89  plist = value;
90  break;
91  }
92  }
93  }
94  //Could not find any collection, raise exception
95  if (!plist) {
96  B2ERROR("Could not determine StoreArray the MCParticle belongs to !");
97  throw NoParticleListSetError();
98  }
99 
100  //Set plist pointer and index for whole array
101  for (int i = 0; i < plist->GetEntriesFast(); i++) {
102  MCParticle& mc = *(static_cast<MCParticle*>(plist->At(i)));
103  mc.m_plist = plist;
104  mc.m_index = i + 1;
105  }
106 }
107 std::string MCParticle::getName() const
108 {
109  const TParticlePDG* p = TDatabasePDG::Instance()->GetParticle(m_pdg);
110  if (p)
111  return p->GetName();
112  else //handle unknown PDG codes
113  return std::to_string(m_pdg);
114 }
115 std::string MCParticle::getInfoHTML() const
116 {
117  std::stringstream out;
118  out << "<b>Charge</b>=" << (int)getCharge();
119  out << ", <b>PDG</b>=" << getPDG();
120  out << " (" << getName() << ")";
121  out << "<br>";
122  out << "<b>isPrimaryParticle</b>=" << isPrimaryParticle();
123  out << ",<b>isInitial</b>=" << isInitial();
124  out << ",<b>isVirtual</b>=" << isVirtual();
125  out << "<br>";
126 
127  out << "<b>pT</b>=" << getMomentum().Pt();
128  out << ", <b>pZ</b>=" << m_momentum_z;
129  out << "<br>";
130  std::string unitType = HTML::chooseUnitOfLength(getProductionVertex());
131  int precision = 3;
132  out << "<b>V</b>=" << HTML::getStringConvertToUnit(getProductionVertex(), precision, unitType);
133 
134  const MCParticle* mom = getMother();
135  if (mom) {
136  out << "<br>";
137  out << "<b>Mother</b>: " << mom->getArrayName() << "[" << mom->getArrayIndex() << "] (" << mom->getName() << ")";
138  }
139  return out.str();
140 }
StoreEntryMap::const_iterator StoreEntryConstIter
const_iterator for a StoreEntry map.
Definition: DataStore.h:89
std::map< std::string, StoreEntry > StoreEntryMap
Map for StoreEntries.
Definition: DataStore.h:87
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:32
virtual std::string getName() const override
Return name of this particle.
Definition: MCParticle.cc:107
int getArrayIndex() const
Get 0-based index of the particle in the corresponding MCParticle list.
Definition: MCParticle.h:244
std::string getArrayName() const
Get name of array this object is stored in, or "" if not found.
TClonesArray * getPtr() const
Raw access to the underlying TClonesArray.
Definition: StoreArray.h:311
Abstract base class for different kinds of events.