Belle II Software  release-06-01-15
ParticleList.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 <analysis/dataobjects/ParticleList.h>
10 
11 // framework - DataStore
12 #include <framework/datastore/StoreArray.h>
13 #include <framework/datastore/StoreObjPtr.h>
14 
15 // framework aux
16 #include <framework/logging/Logger.h>
17 #include <framework/utilities/HTML.h>
18 
19 #include <iostream>
20 #include <algorithm>
21 
22 using namespace std;
23 using namespace Belle2;
24 
25 ParticleList::~ParticleList()
26 {
27  delete m_antiList;
28 }
29 
30 void ParticleList::initialize(int pdg, const std::string& name, const std::string& particleStoreName)
31 {
32  m_pdg = pdg;
33  m_pdgbar = pdg;
34  m_particleStore = particleStoreName;
35 
36  m_thisListName = name;
37  m_antiListName.clear();
38 }
39 
40 void ParticleList::setParticleCollectionName(const std::string& name, bool forAntiParticle)
41 {
42  m_particleStore = name;
43 
44  if (forAntiParticle and !m_antiListName.empty())
45  getAntiParticleList().setParticleCollectionName(name, false);
46 }
47 
48 void ParticleList::addParticle(const Particle* particle)
49 {
50  if (particle->getArrayName() != m_particleStore) {
51  B2ERROR("ParticleList::addParticle particle is from different store array, not added");
52  return;
53  }
54 
55  int iparticle = particle->getArrayIndex();
56  if (iparticle < 0) {
57  B2ERROR("ParticleList::addParticle particle is not in a store array, not added");
58  return;
59  }
60 
61  int pdg = particle->getPDGCode();
62  Particle::EFlavorType type = particle->getFlavorType();
63  addParticle((unsigned) iparticle, pdg, type, true);
64 }
65 
66 void ParticleList::bindAntiParticleList(ParticleList& antiList, bool includingAntiList)
67 {
68  m_pdgbar = antiList.getPDGCode();
69  m_antiListName = antiList.getParticleListName();
70 
71  if (abs(m_pdgbar) != abs(m_pdg))
72  B2ERROR("ParticleList::bindAntiParticleList invalid (inconsistent) PDG codes!");
73 
74  if (includingAntiList)
75  antiList.bindAntiParticleList(*this, false);
76 }
77 
78 void ParticleList::addParticle(unsigned iparticle, int pdg, Particle::EFlavorType type, bool includingAntiList)
79 {
80  if (abs(pdg) != abs(getPDGCode())) {
81  B2ERROR("ParticleList::addParticle PDG codes do not match, not added");
82  return;
83  }
84 
85  if (type == Particle::c_Unflavored) {
86  // this is self-conjugated particle
87  // add it to the self-conjugated list of this (and anti-particle list if exists)
88 
89  // check if the particle is already in this list
90  if (std::find(m_scList.begin(), m_scList.end(), iparticle) == m_scList.end()) {
91  m_scList.push_back(iparticle);
92  } else {
93  B2WARNING("ParticleList::addParticle Trying to add Particle with index=" << iparticle
94  << " to the ParticleList=" << m_thisListName << " that is already included!");
95  return;
96  }
97 
98  // add it to the self-conjugated list
99  if (includingAntiList and !m_antiListName.empty())
100  getAntiParticleList().addParticle(iparticle, pdg, type, false);
101  } else if (type == Particle::c_Flavored) {
102  unsigned antiParticle = (pdg == getPDGCode()) ? 0 : 1;
103 
104  if (antiParticle)
105  getAntiParticleList().addParticle(iparticle, pdg, type, false);
106  else {
107  if (std::find(m_fsList.begin(), m_fsList.end(), iparticle) == m_fsList.end()) {
108  m_fsList.push_back(iparticle);
109  } else {
110  B2WARNING("ParticleList::addParticle Trying to add Particle with index=" << iparticle
111  << " to the ParticleList=" << m_thisListName << "that is already included! Particle not added");
112  }
113  }
114  } else {
115  B2ERROR("ParticleList::addParticle invalid flavor type, not added");
116  }
117 }
118 
119 void ParticleList::removeParticles(const std::vector<unsigned int>& toRemove, bool removeFromAntiList)
120 {
121  std::vector<int> newList;
122  // remove Particles from flavor-specific list of this Particle List
123  for (int i : m_fsList) {
124  if (std::find(toRemove.begin(), toRemove.end(), i) == toRemove.end())
125  newList.push_back(i);
126  }
127  m_fsList = newList;
128 
129  // remove Particles from self-conjugated list of this Particle List
130  newList.clear();
131  for (int i : m_scList) {
132  if (std::find(toRemove.begin(), toRemove.end(), i) == toRemove.end())
133  newList.push_back(i);
134  }
135  m_scList = newList;
136 
137  if (removeFromAntiList and !m_antiListName.empty()) {
138  getAntiParticleList().removeParticles(toRemove, false);
139  }
140 }
141 
142 void ParticleList::clear(bool includingAntiList)
143 {
144  m_fsList.clear();
145  m_scList.clear();
146 
147  if (includingAntiList and !m_antiListName.empty()) {
148  getAntiParticleList().clear(false);
149  }
150 }
151 
152 Particle* ParticleList::getParticle(unsigned i, bool includingAntiList) const
153 {
154  StoreArray<Particle> Particles(m_particleStore);
155 
156  if (i < m_fsList.size()) {
157  return Particles[m_fsList[i]];
158  } else if (i < m_fsList.size() + m_scList.size()) {
159  i -= m_fsList.size();
160  return Particles[m_scList[i]];
161  }
162 
163  if (includingAntiList and !m_antiListName.empty())
164  return getAntiParticleList().getParticle(i - m_fsList.size() - m_scList.size(), false);
165 
166  return nullptr;
167 }
168 
169 unsigned ParticleList::getListSize(bool includingAntiList) const
170 {
171  unsigned size = 0;
172 
173  // FlavorSpecific particles of this list
174  size += m_fsList.size();
175  // SelfConjugated particles of this list = SelfConjugated particles of anti-particle list
176  size += m_scList.size();
177 
178  if (includingAntiList) {
179  // FlavorSpecific particles of anti-particle list
180  size += getNParticlesOfType(EParticleType::c_FlavorSpecificParticle, true);
181  }
182 
183  return size;
184 }
185 
186 const std::vector<int>& ParticleList::getList(EParticleType K, bool forAntiParticle) const
187 {
188  if (!forAntiParticle) {
189  if (K == c_FlavorSpecificParticle)
190  return m_fsList;
191  else
192  return m_scList;
193  } else {
194  const static std::vector<int> emptyList;
195  if (m_antiListName.empty())
196  return emptyList;
197 
198  return getAntiParticleList().getList(K);
199  }
200 }
201 
202 bool ParticleList::contains(const Particle* p, bool includingAntiList) const
203 {
204  const int index = p->getArrayIndex();
205  for (int i = 0; i < 3; i++) {
206  if (i == 1 && !includingAntiList)
207  continue;
208 
209  const std::vector<int>& currentList = getList((i < 2) ? c_FlavorSpecificParticle : c_SelfConjugatedParticle, i == 1);
210  if (std::find(currentList.begin(), currentList.end(), index) != currentList.end())
211  return true;
212  }
213  return false;
214 }
215 
216 void ParticleList::print() const
217 {
218  B2INFO(HTML::htmlToPlainText(getInfoHTML()));
219 }
220 
221 std::string ParticleList::getInfoHTML() const
222 {
223  std::stringstream stream;
224  unsigned thisFSCount = getNParticlesOfType(c_FlavorSpecificParticle);
225  unsigned thisSCCount = getNParticlesOfType(c_SelfConjugatedParticle);
226  unsigned antiFSCount = getNParticlesOfType(c_FlavorSpecificParticle, true);
227  unsigned antiSCCount = getNParticlesOfType(c_SelfConjugatedParticle, true);
228 
229  if (!m_antiListName.empty()) {
230  stream << " ParticleLists: " << m_thisListName << " (" << thisFSCount << "+" << thisSCCount << ")"
231  << " + " << m_antiListName << " (" << antiFSCount << "+" << antiSCCount << ")";
232  } else {
233  stream << " ParticleList : " << m_thisListName << " (" << thisFSCount << "+" << thisSCCount << ")";
234  }
235  return HTML::escape(stream.str());
236 }
237 
238 ParticleList& ParticleList::getAntiParticleList() const
239 {
240  if (!m_antiList) {
241  m_antiList = new StoreObjPtr<ParticleList>(m_antiListName);
242  if (!m_antiList->isValid()) {
243  B2FATAL("Anti-particle list " << m_antiListName << " for " << m_thisListName <<
244  " not found, even though one was set via bindAntiParticleList(). Maybe you only saved one list into a .root file?");
245  }
246  }
247  return **m_antiList;
248 }
249 
ParticleList is a container class that stores a collection of Particle objects.
Definition: ParticleList.h:140
void bindAntiParticleList(ParticleList &antiList, bool includingAntiList=true)
Binds particle and anti-particle ParticleLists.
Definition: ParticleList.cc:66
int getPDGCode() const
Returns PDG code.
Definition: ParticleList.h:238
std::string getParticleListName() const
Returns the name this ParticleList.
Definition: ParticleList.h:276
EParticleType
Type of Particle (determines in which of the two internal lists the particle is stored).
Definition: ParticleList.h:149
Class to store reconstructed particles.
Definition: Particle.h:74
EFlavorType
describes flavor type, see getFlavorType().
Definition: Particle.h:92
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:95
Abstract base class for different kinds of events.