Belle II Software  release-08-01-10
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  std::string label = m_thisListName.substr(m_thisListName.find_first_of(':') + 1);
40  if ((Const::finalStateParticlesSet.contains(Const::ParticleType(abs(m_pdg))) and label == "all") or label == "V0")
41  m_isReserved = true;
42 }
43 
44 void ParticleList::setParticleCollectionName(const std::string& name, bool forAntiParticle)
45 {
46  m_particleStore = name;
47 
48  if (forAntiParticle and !m_antiListName.empty())
49  getAntiParticleList().setParticleCollectionName(name, false);
50 }
51 
52 void ParticleList::addParticle(const Particle* particle)
53 {
54  if (m_isReserved)
55  B2FATAL("ParticleList::addParticle The ParticleList " << m_thisListName <<
56  " is reserved and forbidden to be manipulated.");
57 
58  if (particle->getArrayName() != m_particleStore) {
59  B2ERROR("ParticleList::addParticle particle is from different store array, not added");
60  return;
61  }
62 
63  int iparticle = particle->getArrayIndex();
64  if (iparticle < 0) {
65  B2ERROR("ParticleList::addParticle particle is not in a store array, not added");
66  return;
67  }
68 
69  int pdg = particle->getPDGCode();
70  Particle::EFlavorType type = particle->getFlavorType();
71  addParticle((unsigned) iparticle, pdg, type, true);
72 }
73 
74 void ParticleList::bindAntiParticleList(ParticleList& antiList, bool includingAntiList)
75 {
76  m_pdgbar = antiList.getPDGCode();
77  m_antiListName = antiList.getParticleListName();
78 
79  if (abs(m_pdgbar) != abs(m_pdg))
80  B2ERROR("ParticleList::bindAntiParticleList invalid (inconsistent) PDG codes!");
81 
82  if (includingAntiList)
83  antiList.bindAntiParticleList(*this, false);
84 }
85 
86 void ParticleList::addParticle(unsigned iparticle, int pdg, Particle::EFlavorType type, bool includingAntiList)
87 {
88  if (m_isReserved)
89  B2FATAL("ParticleList::addParticle The ParticleList " << m_thisListName <<
90  " is reserved and forbidden to be manipulated.");
91 
92  if (abs(pdg) != abs(getPDGCode())) {
93  B2ERROR("ParticleList::addParticle PDG codes do not match, not added");
94  return;
95  }
96 
97  if (type == Particle::c_Unflavored) {
98  // this is self-conjugated particle
99  // add it to the self-conjugated list of this (and anti-particle list if exists)
100 
101  // check if the particle is already in this list
102  if (std::find(m_scList.begin(), m_scList.end(), iparticle) == m_scList.end()) {
103  m_scList.push_back(iparticle);
104  } else {
105  B2WARNING("ParticleList::addParticle Trying to add Particle with index=" << iparticle
106  << " to the ParticleList=" << m_thisListName << " that is already included!");
107  return;
108  }
109 
110  // add it to the self-conjugated list
111  if (includingAntiList and !m_antiListName.empty())
112  getAntiParticleList().addParticle(iparticle, pdg, type, false);
113  } else if (type == Particle::c_Flavored) {
114  unsigned antiParticle = (pdg == getPDGCode()) ? 0 : 1;
115 
116  if (antiParticle)
117  getAntiParticleList().addParticle(iparticle, pdg, type, false);
118  else {
119  if (std::find(m_fsList.begin(), m_fsList.end(), iparticle) == m_fsList.end()) {
120  m_fsList.push_back(iparticle);
121  } else {
122  B2WARNING("ParticleList::addParticle Trying to add Particle with index=" << iparticle
123  << " to the ParticleList=" << m_thisListName << "that is already included! Particle not added");
124  }
125  }
126  } else {
127  B2ERROR("ParticleList::addParticle invalid flavor type, not added");
128  }
129 }
130 
131 void ParticleList::removeParticles(const std::vector<unsigned int>& toRemove, bool removeFromAntiList)
132 {
133  if (m_isReserved)
134  B2FATAL("ParticleList::removeParticles The ParticleList " << m_thisListName <<
135  " is reserved and forbidden to be manipulated.");
136 
137  std::vector<int> newList;
138  // remove Particles from flavor-specific list of this Particle List
139  for (int i : m_fsList) {
140  if (std::find(toRemove.begin(), toRemove.end(), i) == toRemove.end())
141  newList.push_back(i);
142  }
143  m_fsList = newList;
144 
145  // remove Particles from self-conjugated list of this Particle List
146  newList.clear();
147  for (int i : m_scList) {
148  if (std::find(toRemove.begin(), toRemove.end(), i) == toRemove.end())
149  newList.push_back(i);
150  }
151  m_scList = newList;
152 
153  if (removeFromAntiList and !m_antiListName.empty()) {
154  getAntiParticleList().removeParticles(toRemove, false);
155  }
156 }
157 
158 void ParticleList::clear(bool includingAntiList)
159 {
160  if (m_isReserved)
161  B2FATAL("ParticleList::clear The ParticleList " << m_thisListName <<
162  " is reserved and forbidden to be manipulated.");
163 
164  m_fsList.clear();
165  m_scList.clear();
166 
167  if (includingAntiList and !m_antiListName.empty()) {
168  getAntiParticleList().clear(false);
169  }
170 }
171 
172 Particle* ParticleList::getParticle(unsigned i, bool includingAntiList) const
173 {
174  StoreArray<Particle> Particles(m_particleStore);
175 
176  if (i < m_fsList.size()) {
177  return Particles[m_fsList[i]];
178  } else if (i < m_fsList.size() + m_scList.size()) {
179  i -= m_fsList.size();
180  return Particles[m_scList[i]];
181  }
182 
183  if (includingAntiList and !m_antiListName.empty())
184  return getAntiParticleList().getParticle(i - m_fsList.size() - m_scList.size(), false);
185 
186  return nullptr;
187 }
188 
189 Particle* ParticleList::getParticleWithMdstIdx(unsigned int mdstIdx, bool includingAntiList) const
190 {
191  const unsigned int n = this->getListSize(includingAntiList);
192  for (unsigned i = 0; i < n; i++) {
193 
194  auto particle = this->getParticle(i, includingAntiList);
195 
196  if (particle->getMdstArrayIndex() == mdstIdx) {
197  return particle;
198  }
199  }
200  return nullptr;
201 }
202 
203 unsigned ParticleList::getListSize(bool includingAntiList) const
204 {
205  unsigned size = 0;
206 
207  // FlavorSpecific particles of this list
208  size += m_fsList.size();
209  // SelfConjugated particles of this list = SelfConjugated particles of anti-particle list
210  size += m_scList.size();
211 
212  if (includingAntiList) {
213  // FlavorSpecific particles of anti-particle list
214  size += getNParticlesOfType(EParticleType::c_FlavorSpecificParticle, true);
215  }
216 
217  return size;
218 }
219 
220 const std::vector<int>& ParticleList::getList(EParticleType K, bool forAntiParticle) const
221 {
222  if (!forAntiParticle) {
223  if (K == c_FlavorSpecificParticle)
224  return m_fsList;
225  else
226  return m_scList;
227  } else {
228  const static std::vector<int> emptyList;
229  if (m_antiListName.empty())
230  return emptyList;
231 
232  return getAntiParticleList().getList(K);
233  }
234 }
235 
236 bool ParticleList::contains(const Particle* p, bool includingAntiList) const
237 {
238  const int index = p->getArrayIndex();
239  for (int i = 0; i < 3; i++) {
240  if (i == 1 && !includingAntiList)
241  continue;
242 
243  const std::vector<int>& currentList = getList((i < 2) ? c_FlavorSpecificParticle : c_SelfConjugatedParticle, i == 1);
244  if (std::find(currentList.begin(), currentList.end(), index) != currentList.end())
245  return true;
246  }
247  return false;
248 }
249 
250 int ParticleList::getIndex(const Particle* p, bool includingAntiList) const
251 {
252  const int index = p->getArrayIndex();
253 
254  auto it_fs = std::find(m_fsList.begin(), m_fsList.end(), index);
255  if (it_fs != m_fsList.end()) {
256  return std::distance(m_fsList.begin(), it_fs);
257  }
258 
259  auto it_sc = std::find(m_scList.begin(), m_scList.end(), index);
260  if (it_sc != m_scList.end()) {
261  return std::distance(m_scList.begin(), it_sc) + m_fsList.size();
262  }
263 
264  if (includingAntiList and !m_antiListName.empty()) {
265  int indexAnti = getAntiParticleList().getIndex(p, false);
266  if (indexAnti != -1)
267  return indexAnti + m_fsList.size() + m_scList.size();
268  }
269 
270  return -1;
271 }
272 
273 void ParticleList::print() const
274 {
275  B2INFO(HTML::htmlToPlainText(getInfoHTML()));
276 }
277 
278 std::string ParticleList::getInfoHTML() const
279 {
280  std::stringstream stream;
281  unsigned thisFSCount = getNParticlesOfType(c_FlavorSpecificParticle);
282  unsigned thisSCCount = getNParticlesOfType(c_SelfConjugatedParticle);
283  unsigned antiFSCount = getNParticlesOfType(c_FlavorSpecificParticle, true);
284  unsigned antiSCCount = getNParticlesOfType(c_SelfConjugatedParticle, true);
285 
286  if (!m_antiListName.empty()) {
287  stream << " ParticleLists: " << m_thisListName << " (" << thisFSCount << "+" << thisSCCount << ")"
288  << " + " << m_antiListName << " (" << antiFSCount << "+" << antiSCCount << ")";
289  } else {
290  stream << " ParticleList : " << m_thisListName << " (" << thisFSCount << "+" << thisSCCount << ")";
291  }
292  return HTML::escape(stream.str());
293 }
294 
295 ParticleList& ParticleList::getAntiParticleList() const
296 {
297  if (!m_antiList) {
298  m_antiList = new StoreObjPtr<ParticleList>(m_antiListName);
299  if (!m_antiList->isValid()) {
300  B2FATAL("Anti-particle list " << m_antiListName << " for " << m_thisListName <<
301  " not found, even though one was set via bindAntiParticleList(). Maybe you only saved one list into a .root file?");
302  }
303  }
304  return **m_antiList;
305 }
#define K(x)
macro autogenerated by FFTW
The ParticleType class for identifying different particle types.
Definition: Const.h:399
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:74
int getPDGCode() const
Returns PDG code.
Definition: ParticleList.h:239
std::string getParticleListName() const
Returns the name this ParticleList.
Definition: ParticleList.h:277
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:75
EFlavorType
describes flavor type, see getFlavorType().
Definition: Particle.h:94
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:96
Abstract base class for different kinds of events.