Belle II Software development
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
22using namespace std;
23using namespace Belle2;
24
25ParticleList::~ParticleList()
26{
27 delete m_antiList;
28}
29
30void 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
44void ParticleList::setParticleCollectionName(const std::string& name, bool forAntiParticle)
45{
46 m_particleStore = name;
47
48 if (forAntiParticle and !m_antiListName.empty())
50}
51
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
74void ParticleList::bindAntiParticleList(ParticleList& antiList, bool includingAntiList)
75{
76 m_pdgbar = antiList.getPDGCode();
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
86void 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
131void 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
158void 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
172Particle* ParticleList::getParticle(unsigned i, bool includingAntiList) const
173{
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
189Particle* 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
203unsigned 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
220const 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
236bool 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
250int 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
274{
276}
277
278std::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
296{
297 if (!m_antiList) {
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:408
static const ParticleSet finalStateParticlesSet
set of final set particles that can be created by the ParticleLoader
Definition: Const.h:657
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 m_antiListName
name of ParticleList for anti-particles
Definition: ParticleList.h:382
Particle * getParticle(unsigned i, bool includingAntiList=true) const
Returns i-th particle from the list and anti list if requested.
void addParticle(const Particle *particle)
Adds a new particle to the list (safe method)
Definition: ParticleList.cc:52
bool m_isReserved
transient
Definition: ParticleList.h:387
bool contains(const Particle *p, bool includingAntiList=true) const
Returns true if and only if 'p' is already in this list.
const std::vector< int > & getList(EParticleType K, bool forAntiParticle=false) const
Returns list of StoreArray<Particle> indices.
ParticleList & getAntiParticleList() const
Returns bound anti-particle list.
unsigned getListSize(bool includingAntiList=true) const
Returns total number of particles in this list and anti list if requested.
void setParticleCollectionName(const std::string &name, bool forAntiParticle=true)
Sets Particle store array name to which particle list refers.
Definition: ParticleList.cc:44
int m_pdg
PDG code of Particle.
Definition: ParticleList.h:373
std::string m_particleStore
name of Particle store array
Definition: ParticleList.h:379
int getIndex(const Particle *p, bool includingAntiList=true) const
Returns index of the given particle 'p' in this list.
std::string m_thisListName
name of this ParticleList
Definition: ParticleList.h:381
void clear(bool includingAntiList=true)
Remove all elements from list, afterwards getListSize() will be 0.
StoreObjPtr< ParticleList > * m_antiList
keep anti-list around for performance.
Definition: ParticleList.h:385
std::vector< int > m_fsList
list of 0-based indices of flavor-specific Particles (particles that have an anti-particle)
Definition: ParticleList.h:375
std::string getParticleListName() const
Returns the name this ParticleList.
Definition: ParticleList.h:277
unsigned getNParticlesOfType(EParticleType K, bool forAntiParticle=false) const
Returns the number of flavor-specific particles or self-conjugated particles in this list or its anti...
Definition: ParticleList.h:310
int m_pdgbar
PDG code of antiparticle.
Definition: ParticleList.h:374
EParticleType
Type of Particle (determines in which of the two internal lists the particle is stored).
Definition: ParticleList.h:149
void print() const
Prints the list.
std::string getInfoHTML() const
Return a short summary of this object's contents in HTML format.
std::vector< int > m_scList
list of 0-based indices of self-conjugated Particles (particles that do not have an anti-particle)
Definition: ParticleList.h:377
Particle * getParticleWithMdstIdx(unsigned int mdstIdx, bool includingAntiList=true) const
Returns the particle from the list matching the given mdst array index, if any is found.
void initialize(int pdg, const std::string &name, const std::string &particleStoreName="Particles")
Sets the PDG code and name of this ParticleList.
Definition: ParticleList.cc:30
void removeParticles(const std::vector< unsigned int > &toRemove, bool removeFromAntiList=true)
Remove given elements from list.
Class to store reconstructed particles.
Definition: Particle.h:75
EFlavorType
describes flavor type, see getFlavorType().
Definition: Particle.h:94
@ c_Unflavored
Is its own antiparticle or we don't know whether it is a particle/antiparticle.
Definition: Particle.h:95
@ c_Flavored
Is either particle or antiparticle.
Definition: Particle.h:96
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
std::string escape(const std::string &str)
Convert &, <, > etc.
Definition: HTML.cc:159
std::string htmlToPlainText(const std::string &html)
Reformat given HTML string into terminal-friendly plain text.
Definition: HTML.cc:138
Abstract base class for different kinds of events.
STL namespace.