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