9 #include <analysis/dataobjects/ParticleList.h>
12 #include <framework/datastore/StoreArray.h>
13 #include <framework/datastore/StoreObjPtr.h>
16 #include <framework/logging/Logger.h>
17 #include <framework/utilities/HTML.h>
25 ParticleList::~ParticleList()
30 void ParticleList::initialize(
int pdg,
const std::string& name,
const std::string& particleStoreName)
34 m_particleStore = particleStoreName;
36 m_thisListName = name;
37 m_antiListName.clear();
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")
44 void ParticleList::setParticleCollectionName(
const std::string& name,
bool forAntiParticle)
46 m_particleStore = name;
48 if (forAntiParticle and !m_antiListName.empty())
49 getAntiParticleList().setParticleCollectionName(name,
false);
52 void ParticleList::addParticle(
const Particle* particle)
55 B2FATAL(
"ParticleList::addParticle The ParticleList " << m_thisListName <<
56 " is reserved and forbidden to be manipulated.");
58 if (particle->getArrayName() != m_particleStore) {
59 B2ERROR(
"ParticleList::addParticle particle is from different store array, not added");
63 int iparticle = particle->getArrayIndex();
65 B2ERROR(
"ParticleList::addParticle particle is not in a store array, not added");
69 int pdg = particle->getPDGCode();
71 addParticle((
unsigned) iparticle, pdg, type,
true);
74 void ParticleList::bindAntiParticleList(
ParticleList& antiList,
bool includingAntiList)
79 if (abs(m_pdgbar) != abs(m_pdg))
80 B2ERROR(
"ParticleList::bindAntiParticleList invalid (inconsistent) PDG codes!");
82 if (includingAntiList)
89 B2FATAL(
"ParticleList::addParticle The ParticleList " << m_thisListName <<
90 " is reserved and forbidden to be manipulated.");
92 if (abs(pdg) != abs(getPDGCode())) {
93 B2ERROR(
"ParticleList::addParticle PDG codes do not match, not added");
97 if (type == Particle::c_Unflavored) {
102 if (std::find(m_scList.begin(), m_scList.end(), iparticle) == m_scList.end()) {
103 m_scList.push_back(iparticle);
105 B2WARNING(
"ParticleList::addParticle Trying to add Particle with index=" << iparticle
106 <<
" to the ParticleList=" << m_thisListName <<
" that is already included!");
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;
117 getAntiParticleList().addParticle(iparticle, pdg, type,
false);
119 if (std::find(m_fsList.begin(), m_fsList.end(), iparticle) == m_fsList.end()) {
120 m_fsList.push_back(iparticle);
122 B2WARNING(
"ParticleList::addParticle Trying to add Particle with index=" << iparticle
123 <<
" to the ParticleList=" << m_thisListName <<
"that is already included! Particle not added");
127 B2ERROR(
"ParticleList::addParticle invalid flavor type, not added");
131 void ParticleList::removeParticles(
const std::vector<unsigned int>& toRemove,
bool removeFromAntiList)
134 B2FATAL(
"ParticleList::removeParticles The ParticleList " << m_thisListName <<
135 " is reserved and forbidden to be manipulated.");
137 std::vector<int> newList;
139 for (
int i : m_fsList) {
140 if (std::find(toRemove.begin(), toRemove.end(), i) == toRemove.end())
141 newList.push_back(i);
147 for (
int i : m_scList) {
148 if (std::find(toRemove.begin(), toRemove.end(), i) == toRemove.end())
149 newList.push_back(i);
153 if (removeFromAntiList and !m_antiListName.empty()) {
154 getAntiParticleList().removeParticles(toRemove,
false);
158 void ParticleList::clear(
bool includingAntiList)
161 B2FATAL(
"ParticleList::clear The ParticleList " << m_thisListName <<
162 " is reserved and forbidden to be manipulated.");
167 if (includingAntiList and !m_antiListName.empty()) {
168 getAntiParticleList().clear(
false);
172 Particle* ParticleList::getParticle(
unsigned i,
bool includingAntiList)
const
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]];
183 if (includingAntiList and !m_antiListName.empty())
184 return getAntiParticleList().getParticle(i - m_fsList.size() - m_scList.size(),
false);
189 Particle* ParticleList::getParticleWithMdstIdx(
unsigned int mdstIdx,
bool includingAntiList)
const
191 const unsigned int n = this->getListSize(includingAntiList);
192 for (
unsigned i = 0; i < n; i++) {
194 auto particle = this->getParticle(i, includingAntiList);
196 if (particle->getMdstArrayIndex() == mdstIdx) {
203 unsigned ParticleList::getListSize(
bool includingAntiList)
const
208 size += m_fsList.size();
210 size += m_scList.size();
212 if (includingAntiList) {
214 size += getNParticlesOfType(EParticleType::c_FlavorSpecificParticle,
true);
220 const std::vector<int>& ParticleList::getList(
EParticleType K,
bool forAntiParticle)
const
222 if (!forAntiParticle) {
223 if (
K == c_FlavorSpecificParticle)
228 const static std::vector<int> emptyList;
229 if (m_antiListName.empty())
232 return getAntiParticleList().getList(
K);
236 bool ParticleList::contains(
const Particle* p,
bool includingAntiList)
const
238 const int index = p->getArrayIndex();
239 for (
int i = 0; i < 3; i++) {
240 if (i == 1 && !includingAntiList)
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())
250 int ParticleList::getIndex(
const Particle* p,
bool includingAntiList)
const
252 const int index = p->getArrayIndex();
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);
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();
264 if (includingAntiList and !m_antiListName.empty()) {
265 int indexAnti = getAntiParticleList().getIndex(p,
false);
267 return indexAnti + m_fsList.size() + m_scList.size();
273 void ParticleList::print()
const
275 B2INFO(HTML::htmlToPlainText(getInfoHTML()));
278 std::string ParticleList::getInfoHTML()
const
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);
286 if (!m_antiListName.empty()) {
287 stream <<
" ParticleLists: " << m_thisListName <<
" (" << thisFSCount <<
"+" << thisSCCount <<
")"
288 <<
" + " << m_antiListName <<
" (" << antiFSCount <<
"+" << antiSCCount <<
")";
290 stream <<
" ParticleList : " << m_thisListName <<
" (" << thisFSCount <<
"+" << thisSCCount <<
")";
292 return HTML::escape(stream.str());
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?");
The ParticleType class for identifying different particle types.
ParticleList is a container class that stores a collection of Particle objects.
void bindAntiParticleList(ParticleList &antiList, bool includingAntiList=true)
Binds particle and anti-particle ParticleLists.
int getPDGCode() const
Returns PDG code.
std::string getParticleListName() const
Returns the name this ParticleList.
EParticleType
Type of Particle (determines in which of the two internal lists the particle is stored).
Class to store reconstructed particles.
EFlavorType
describes flavor type, see getFlavorType().
Accessor to arrays stored in the data store.
Type-safe access to single objects in the data store.
Abstract base class for different kinds of events.