Belle II Software development
RestOfEvent.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 <regex>
10#include <analysis/dataobjects/RestOfEvent.h>
11
12#include <framework/datastore/StoreArray.h>
13
14#include <analysis/dataobjects/Particle.h>
15#include <mdst/dataobjects/MCParticle.h>
16#include <mdst/dataobjects/Track.h>
17#include <mdst/dataobjects/ECLCluster.h>
18#include <mdst/dataobjects/KLMCluster.h>
19
20#include <analysis/ClusterUtility/ClusterUtils.h>
21
22using namespace Belle2;
23// New methods:
24void RestOfEvent::addParticles(const std::vector<const Particle*>& particlesToAdd)
25{
26 StoreArray<Particle> allParticles;
27 for (auto* particleToAdd : particlesToAdd) {
28 std::vector<const Particle*> daughters = particleToAdd->getFinalStateDaughters();
29 for (auto* daughter : daughters) {
30 bool toAdd = true;
31 for (auto& myIndex : m_particleIndices) {
32 if (allParticles[myIndex]->isCopyOf(daughter, true)) {
33 toAdd = false;
34 break;
35 }
36 }
37 if (toAdd) {
38 B2DEBUG(10, "\t\tAdding particle with PDG " << daughter->getPDGCode());
39 m_particleIndices.insert(daughter->getArrayIndex());
40 }
41 }
42 }
43}
44
45std::vector<const Particle*> RestOfEvent::getParticles(const std::string& maskName, bool unpackComposite) const
46{
47 std::vector<const Particle*> result;
48 StoreArray<Particle> allParticles;
49 std::set<int> source;
50 if (m_particleIndices.size() == 0) {
51 B2DEBUG(10, "ROE contains no particles, masks are empty too");
52 return result;
53 }
54 if (maskName == RestOfEvent::c_defaultMaskName or maskName.empty()) {
55 // if no mask provided work with internal source
56 source = m_particleIndices;
57 } else {
58 bool maskFound = false;
59 for (auto& mask : m_masks) {
60 if (mask.getName() == maskName) {
61 maskFound = true;
62 source = mask.getParticles();
63 break;
64 }
65 }
66 if (!maskFound) {
67 B2FATAL("No '" << maskName << "' mask defined in current ROE!");
68 }
69 }
70 for (const int index : source) {
71 if ((allParticles[index]->getParticleSource() == Particle::EParticleSourceObject::c_Composite or
72 allParticles[index]->getParticleSource() == Particle::EParticleSourceObject::c_V0) && unpackComposite) {
73 auto fsdaughters = allParticles[index]->getFinalStateDaughters();
74 for (auto* daughter : fsdaughters) {
75 result.push_back(daughter);
76 }
77 continue;
78 }
79 result.push_back(allParticles[index]);
80 }
81 return result;
82}
83
84std::vector<const Particle*> RestOfEvent::getPhotons(const std::string& maskName, bool unpackComposite) const
85{
86 auto particles = getParticles(maskName, unpackComposite);
87 std::vector<const Particle*> photons;
88 for (auto* particle : particles) {
89 if (particle->getParticleSource() == Particle::EParticleSourceObject::c_ECLCluster) {
90 photons.push_back(particle);
91 }
92 }
93 return photons;
94}
95
96std::vector<const Particle*> RestOfEvent::getHadrons(const std::string& maskName, bool unpackComposite) const
97{
98 auto particles = getParticles(maskName, unpackComposite);
99 std::vector<const Particle*> hadrons;
100 for (auto* particle : particles) {
101 if (particle->getParticleSource() == Particle::EParticleSourceObject::c_KLMCluster) {
102 hadrons.push_back(particle);
103 }
104 }
105 return hadrons;
106}
107
108std::vector<const Particle*> RestOfEvent::getChargedParticles(const std::string& maskName, unsigned int pdg,
109 bool unpackComposite) const
110{
111 auto particles = getParticles(maskName, unpackComposite);
112 std::vector<const Particle*> charged;
113 for (auto* particle : particles) {
114 if (particle->getParticleSource() == Particle::EParticleSourceObject::c_Track) {
115 if (pdg == 0 || pdg == abs(particle->getPDGCode())) {
116 charged.push_back(particle);
117 }
118 }
119 }
120 return charged;
121}
122
123
124bool RestOfEvent::hasParticle(const Particle* particle, const std::string& maskName) const
125{
126 if (maskName != RestOfEvent::c_defaultMaskName && !hasMask(maskName) && !maskName.empty()) {
127 B2FATAL("No '" << maskName << "' mask defined in current ROE!");
128 }
129
130 std::vector<const Particle*> particlesROE = getParticles(maskName);
131 return isInParticleList(particle, particlesROE);
132}
133
134void RestOfEvent::initializeMask(const std::string& name, const std::string& origin)
135{
136 if (name == "") {
137 B2FATAL("Creation of ROE Mask with an empty name is not allowed!");
138 }
139 if (name == RestOfEvent::c_defaultMaskName) {
140 B2FATAL("Creation of ROE Mask with a name " << RestOfEvent::c_defaultMaskName << " is not allowed!");
141 }
142 std::regex word_regex("^[a-zA-Z][a-zA-Z0-9_]*$");
143 if (!std::regex_match(name, word_regex)) {
144 B2FATAL("Mask name '" << name << "' contains forbidden characters or it does not start with a letter. "
145 "Only alphanumeric and underscore characters are allowed in ROE mask names.");
146 }
147 if (findMask(name)) {
148 B2FATAL("ROE Mask '" << name << "' already exists!");
149 }
150 Mask elon(name, origin);
151 m_masks.push_back(elon);
152}
153
154void RestOfEvent::excludeParticlesFromMask(const std::string& maskName, const std::vector<const Particle*>& particlesToUpdate,
155 Particle::EParticleSourceObject listType, bool discard)
156{
157 if (maskName == RestOfEvent::c_defaultMaskName) {
158 B2FATAL("ROE Mask name '" << RestOfEvent::c_defaultMaskName << "' is reserved for no mask case! " <<
159 "Please check your inputs.");
160 }
161 Mask* mask = findMask(maskName);
162 if (!mask) {
163 B2FATAL("No '" << maskName << "' mask defined in current ROE!");
164 }
165 std::string maskNameToGetParticles = maskName;
166 if (!mask->isValid()) {
167 maskNameToGetParticles = RestOfEvent::c_defaultMaskName;
168 }
169 std::vector<const Particle*> allROEParticles = getParticles(maskNameToGetParticles);
170 std::vector<const Particle*> toKeepinROE;
171 for (auto* roeParticle : allROEParticles) {
172 if (isInParticleList(roeParticle, particlesToUpdate)) {
173 if (!discard) {
174 // If keep particles option is on, take the equal particles
175 toKeepinROE.push_back(roeParticle);
176 }
177 } else {
178 // Keep all particles which has different type than provided list
179 if (listType != roeParticle->getParticleSource()) {
180 toKeepinROE.push_back(roeParticle);
181 } else if (discard) {
182 // If keep particles option is off, take not equal particles
183 toKeepinROE.push_back(roeParticle);
184 }
185 }
186 }
187 mask->clearParticles();
188 mask->addParticles(toKeepinROE);
189}
190
191void RestOfEvent::updateMaskWithCuts(const std::string& maskName, const std::shared_ptr<Variable::Cut>& trackCut,
192 const std::shared_ptr<Variable::Cut>& eclCut, const std::shared_ptr<Variable::Cut>& klmCut, bool updateExisting)
193{
194 if (maskName == RestOfEvent::c_defaultMaskName) {
195 B2FATAL("ROE Mask name '" << RestOfEvent::c_defaultMaskName << "' is reserved for no mask case! " <<
196 "Please check your inputs.");
197 }
198 Mask* mask = findMask(maskName);
199 if (!mask) {
200 B2FATAL("ROE Mask '" << maskName << "' does not exist!");
201 }
202 std::string sourceName = RestOfEvent::c_defaultMaskName;
203 if (updateExisting) {
204 // if mask already exists, take its particles to update
205 sourceName = maskName;
206 }
207 // get all initial ROE particles, don't touch the possible V0s, otherwise, some daughters may be excluded, and some not... This may be revisited if needed
208 std::vector<const Particle*> allROEParticles = getParticles(sourceName, false);
209 std::vector<const Particle*> maskedParticles;
210 // First check particle type, then check cuts, if no cuts provided, take all particles of this type
211 for (auto* particle : allROEParticles) {
212 if (particle->getParticleSource() == Particle::EParticleSourceObject::c_Track && (!trackCut || trackCut->check(particle))) {
213 maskedParticles.push_back(particle);
214 }
215 if (particle->getParticleSource() == Particle::EParticleSourceObject::c_ECLCluster && (!eclCut || eclCut->check(particle))) {
216 maskedParticles.push_back(particle);
217 }
218 if (particle->getParticleSource() == Particle::EParticleSourceObject::c_KLMCluster && (!klmCut || klmCut->check(particle))) {
219 maskedParticles.push_back(particle);
220 }
221 // don't lose a possible V0 particle
222 if (particle->getParticleSource() == Particle::EParticleSourceObject::c_Composite or
223 particle->getParticleSource() == Particle::EParticleSourceObject::c_V0) {
224 maskedParticles.push_back(particle);
225 }
226 }
227 mask->clearParticles();
228 mask->addParticles(maskedParticles);
229}
230
231void RestOfEvent::updateMaskWithV0(const std::string& name, const Particle* particleV0)
232{
233 if (name == RestOfEvent::c_defaultMaskName) {
234 B2FATAL("ROE Mask name '" << RestOfEvent::c_defaultMaskName << "' is reserved for no mask case! " <<
235 "Please check your inputs.");
236 }
237 Mask* mask = findMask(name);
238 if (!mask) {
239 B2FATAL("ROE Mask '" << name << "' does not exist!");
240 }
241 std::vector<const Particle*> allROEParticles = getParticles(name, false);
242 std::vector<int> indicesToErase;
243 std::vector<const Particle*> daughtersV0 = particleV0->getFinalStateDaughters();
244 for (auto* maskParticle : allROEParticles) {
245 bool toKeep = true;
246 for (auto* daughterV0 : daughtersV0) {
247 if (daughterV0->isCopyOf(maskParticle, true)) {
248 toKeep = false;
249 }
250 }
251 if (!toKeep) {
252 indicesToErase.push_back(maskParticle->getArrayIndex());
253 }
254 }
255 if (daughtersV0.size() != indicesToErase.size()) {
256 B2DEBUG(10, "Only " << indicesToErase.size() << " daughters are excluded from mask particles. Abort");
257 return;
258 }
259 std::string toprint = "We will erase next indices from " + name + " mask: ";
260 for (auto& i : indicesToErase) {
261 toprint += std::to_string(i) + " ";
262 }
263 B2DEBUG(10, toprint);
264 // If everything is good, we add
265 mask->addV0(particleV0, indicesToErase);
266}
267
268bool RestOfEvent::checkCompatibilityOfMaskAndV0(const std::string& name, const Particle* particleV0)
269{
270 if (name == RestOfEvent::c_defaultMaskName) {
271 B2FATAL("ROE Mask name '" << RestOfEvent::c_defaultMaskName << "' is reserved for no mask case! " <<
272 "Please check your inputs.");
273 }
274 Mask* mask = findMask(name);
275 if (!mask) {
276 B2FATAL("ROE Mask '" << name << "' does not exist!");
277 }
278 if (!mask->isValid()) {
279 return false; //We should have particles here!
280 }
281 if (particleV0->getParticleSource() != Particle::EParticleSourceObject::c_Composite and
282 particleV0->getParticleSource() != Particle::EParticleSourceObject::c_V0) {
283 return false;
284 }
285 std::vector<const Particle*> daughtersV0 = particleV0->getFinalStateDaughters();
286 for (auto* daughter : daughtersV0) {
287 if (daughter->getParticleSource() != Particle::EParticleSourceObject::c_Track) {
288 return false; // Non tracks are not supported yet
289 }
290 }
291 if (mask->hasV0(particleV0)) {
292 return false; // We are not going to add another one
293 }
294 return true;
295}
296
297bool RestOfEvent::hasMask(const std::string& name) const
298{
299 for (auto& mask : m_masks) {
300 if (mask.getName() == name) {
301 return true;
302 }
303 }
304 return false;
305}
306ROOT::Math::PxPyPzEVector RestOfEvent::get4Vector(const std::string& maskName) const
307{
308 ROOT::Math::PxPyPzEVector roe4Vector;
309 std::vector<const Particle*> myParticles = RestOfEvent::getParticles(maskName);
310 for (const Particle* particle : myParticles) {
311 // KLMClusters are discarded, because KLM energy estimation is based on hit numbers, therefore it is unreliable
312 // also, enable it as an experimental option:
313 if (particle->getParticleSource() == Particle::EParticleSourceObject::c_KLMCluster and !m_useKLMEnergy) {
314 continue;
315 }
316 roe4Vector += particle->get4Vector();
317 }
318 return roe4Vector;
319}
320
321
323{
324 for (auto& mask : m_masks) {
325 if (mask.getName() == name) {
326 return &mask;
327 }
328 }
329 return nullptr;
330
331}
332
333int RestOfEvent::getNTracks(const std::string& maskName) const
334{
335 int nTracks = getChargedParticles(maskName).size();
336 return nTracks;
337}
338
339int RestOfEvent::getNECLClusters(const std::string& maskName) const
340{
341 int nROEneutralECLClusters = getPhotons(maskName).size();
342 int nROEchargedECLClusters = 0;
343 for (auto& roeParticle : getChargedParticles(maskName)) {
344 if (roeParticle->getECLCluster()) ++nROEchargedECLClusters;
345 }
346
347 return nROEneutralECLClusters + nROEchargedECLClusters;
348}
349
350int RestOfEvent::getNKLMClusters(const std::string& maskName) const
351{
352 int nROEKLMClusters = getHadrons(maskName).size();
353 return nROEKLMClusters;
354}
355
356ROOT::Math::PxPyPzEVector RestOfEvent::get4VectorNeutralECLClusters(const std::string& maskName) const
357{
358 auto roeClusters = getPhotons(maskName);
359 ROOT::Math::PxPyPzEVector roe4VectorECLClusters;
360
361 // Add all momenta from neutral ECLClusters which have the nPhotons hypothesis
362 for (auto& roeCluster : roeClusters) {
363 if (roeCluster->getECLClusterEHypothesisBit() == ECLCluster::EHypothesisBit::c_nPhotons)
364 roe4VectorECLClusters += roeCluster->get4Vector();
365 }
366
367 return roe4VectorECLClusters;
368}
369
370bool RestOfEvent::isInParticleList(const Particle* roeParticle, const std::vector<const Particle*>& particlesToUpdate) const
371{
372 for (auto* listParticle : particlesToUpdate) {
373 if (roeParticle->isCopyOf(listParticle, true)) {
374 return true;
375 }
376 }
377 return false;
378}
379
380std::vector<std::string> RestOfEvent::getMaskNames() const
381{
382 std::vector<std::string> maskNames;
383
384 for (auto& mask : m_masks) {
385 maskNames.push_back(mask.getName());
386 }
387
388 return maskNames;
389}
390
391void RestOfEvent::print(const std::string& maskName, bool unpackComposite) const
392{
393 std::string tab = " - ";
394 if (maskName != RestOfEvent::c_defaultMaskName) {
395 // Disable possible B2FATAL in printing method, might be useful for tests
396 if (!hasMask(maskName)) {
397 B2WARNING("No mask with the name '" << maskName << "' exists in this ROE! Nothing else to print");
398 return;
399 }
400 tab = " - - ";
401 } else {
402 if (m_isNested) {
403 B2INFO(tab << "ROE is nested");
404 }
405 if (m_isFromMC) {
406 B2INFO(tab << "ROE is build from generated particles");
407 }
408 }
409 if (m_useKLMEnergy) {
410 B2WARNING("This ROE has KLM energy included into its 4-vector!");
411 }
412 if (!m_isFromMC) {
413 unsigned int nCharged = getChargedParticles(maskName, 0, unpackComposite).size();
414 unsigned int nPhotons = getPhotons(maskName, unpackComposite).size();
415 unsigned int nNeutralHadrons = getHadrons(maskName, unpackComposite).size();
416 B2INFO(tab << "No. of Charged particles in ROE: " << nCharged);
417 B2INFO(tab << "No. of Photons in ROE: " << nPhotons);
418 B2INFO(tab << "No. of K_L0 and neutrons in ROE: " << nNeutralHadrons);
419 } else {
420 unsigned int nParticles = getParticles(maskName, unpackComposite).size();
421 B2INFO(tab << "No. of generated particles in ROE: " << nParticles);
422 }
423 printIndices(maskName, unpackComposite, tab);
424}
425
426void RestOfEvent::printIndices(const std::string& maskName, bool unpackComposite, const std::string& tab) const
427{
428 auto particles = getParticles(maskName, unpackComposite);
429 if (particles.size() == 0) {
430 B2INFO(tab << "No indices to print");
431 return;
432 }
433 std::string printoutIndex = tab + "|";
434 std::string printoutPDG = tab + "|";
435 for (const auto particle : particles) {
436 printoutIndex += std::to_string(particle->getArrayIndex()) + " | ";
437 printoutPDG += std::to_string(particle->getPDGCode()) + " | ";
438 }
439 B2INFO(printoutPDG);
440 B2INFO(printoutIndex);
441}
442
443Particle* RestOfEvent::convertToParticle(const std::string& maskName, int pdgCode, bool isSelfConjugated)
444{
445 StoreArray<Particle> particles;
446 std::set<int> source;
447 if (maskName == RestOfEvent::c_defaultMaskName) {
448 // if no mask provided work with internal source
449 source = m_particleIndices;
450 } else {
451 bool maskFound = false;
452 for (auto& mask : m_masks) {
453 if (mask.getName() == maskName) {
454 maskFound = true;
455 source = mask.getParticles();
456 break;
457 }
458 }
459 if (!maskFound) {
460 B2FATAL("No '" << maskName << "' mask defined in current ROE!");
461 }
462 }
463 int particlePDG = (pdgCode == 0) ? getPDGCode() : pdgCode;
464 auto isFlavored = (isSelfConjugated) ? Particle::EFlavorType::c_Unflavored : Particle::EFlavorType::c_Flavored;
465 // By default, the ROE-based particles should have unspecified property to simplify the MC-matching
467 // Same properties as for "->" usage in DecayDescriptor
470 return particles.appendNew(get4Vector(maskName), particlePDG, isFlavored, std::vector(source.begin(),
471 source.end()), propertyFlags);
472}
473
@ c_nPhotons
CR is split into n photons (N1)
Class to store reconstructed particles.
Definition: Particle.h:75
std::vector< const Belle2::Particle * > getFinalStateDaughters() const
Returns a vector of pointers to Final State daughter particles.
Definition: Particle.cc:649
EParticleSourceObject
particle source enumerators
Definition: Particle.h:82
bool isCopyOf(const Particle *oParticle, bool doDetailedComparison=false) const
Returns true if this Particle and oParticle are copies of each other.
Definition: Particle.cc:752
EParticleSourceObject getParticleSource() const
Returns particle source as defined with enum EParticleSourceObject.
Definition: Particle.h:478
@ 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
@ c_IsIgnoreRadiatedPhotons
Is the particle MC matched with the ignore radiated photon flag set?
Definition: Particle.h:119
@ c_IsUnspecified
Ordinary particles.
Definition: Particle.h:118
@ c_IsIgnoreIntermediate
Is the particle MC matched with the ignore intermediate resonances flag set?
Definition: Particle.h:120
ROOT::Math::PxPyPzEVector get4Vector(const std::string &maskName=c_defaultMaskName) const
Get 4-momentum vector all (no mask) or a subset (use mask) of all Tracks and ECLClusters in ROE.
Definition: RestOfEvent.cc:306
int getPDGCode() const
Gets the PDG code of the rest of event.
Definition: RestOfEvent.h:211
int getNECLClusters(const std::string &maskName=c_defaultMaskName) const
Get number of all (no mask) or a subset (use mask) of all ECLclusters in ROE.
Definition: RestOfEvent.cc:339
std::set< int > m_particleIndices
StoreArray indices to unused particles.
Definition: RestOfEvent.h:362
std::vector< const Particle * > getParticles(const std::string &maskName=c_defaultMaskName, bool unpackComposite=true) const
Get all Particles from ROE mask.
Definition: RestOfEvent.cc:45
std::vector< const Particle * > getChargedParticles(const std::string &maskName=c_defaultMaskName, unsigned int pdg=0, bool unpackComposite=true) const
Get charged particles from ROE mask.
Definition: RestOfEvent.cc:108
void print(const std::string &maskName=c_defaultMaskName, bool unpackComposite=true) const
Prints the contents of a RestOfEvent object to screen.
Definition: RestOfEvent.cc:391
void initializeMask(const std::string &name, const std::string &origin="unknown")
Initialize new mask.
Definition: RestOfEvent.cc:134
bool checkCompatibilityOfMaskAndV0(const std::string &name, const Particle *particleV0)
Check if V0 can be added, maybe should be moved to private.
Definition: RestOfEvent.cc:268
static constexpr const char * c_defaultMaskName
Default mask name.
Definition: RestOfEvent.h:60
ROOT::Math::PxPyPzEVector get4VectorNeutralECLClusters(const std::string &maskName=c_defaultMaskName) const
Get 4-momentum vector all (no mask) or a subset (use mask) of all ECLClusters in ROE.
Definition: RestOfEvent.cc:356
void printIndices(const std::string &maskName=c_defaultMaskName, bool unpackComposite=true, const std::string &tab=" - ") const
Prints indices in the given set in a single line.
Definition: RestOfEvent.cc:426
void updateMaskWithCuts(const std::string &name, const std::shared_ptr< Variable::Cut > &trackCut=nullptr, const std::shared_ptr< Variable::Cut > &eclCut=nullptr, const std::shared_ptr< Variable::Cut > &klmCut=nullptr, bool updateExisting=false)
Update mask with cuts.
Definition: RestOfEvent.cc:191
int getNTracks(const std::string &maskName=c_defaultMaskName) const
Get number of all (no mask) or a subset (use mask) of all Tracks in ROE.
Definition: RestOfEvent.cc:333
bool hasMask(const std::string &name) const
True if this ROE object has mask.
Definition: RestOfEvent.cc:297
std::vector< const Particle * > getPhotons(const std::string &maskName=c_defaultMaskName, bool unpackComposite=true) const
Get photons from ROE mask.
Definition: RestOfEvent.cc:84
bool m_isFromMC
MC ROE indicator.
Definition: RestOfEvent.h:366
bool hasParticle(const Particle *particle, const std::string &maskName=c_defaultMaskName) const
Check if ROE has StoreArray index of given to the list of unused tracks in the event.
Definition: RestOfEvent.cc:124
Mask * findMask(const std::string &name)
Helper method to find ROE mask.
Definition: RestOfEvent.cc:322
Particle * convertToParticle(const std::string &maskName=c_defaultMaskName, int pdgCode=0, bool isSelfConjugated=true)
Converts ROE to Particle and adds it to StoreArray.
Definition: RestOfEvent.cc:443
void addParticles(const std::vector< const Particle * > &particle)
Add StoreArray indices of given Particles to the list of unused particles in the event.
Definition: RestOfEvent.cc:24
int getNKLMClusters(const std::string &maskName=c_defaultMaskName) const
Get number of all remaining KLM clusters.
Definition: RestOfEvent.cc:350
std::vector< std::string > getMaskNames() const
Get vector of all mask names of the ROE object.
Definition: RestOfEvent.cc:380
void updateMaskWithV0(const std::string &name, const Particle *particleV0)
Update mask with composite particle.
Definition: RestOfEvent.cc:231
bool m_useKLMEnergy
Include KLM energy into ROE 4-vector.
Definition: RestOfEvent.h:367
std::vector< const Particle * > getHadrons(const std::string &maskName=c_defaultMaskName, bool unpackComposite=true) const
Get hadrons from ROE mask.
Definition: RestOfEvent.cc:96
std::vector< Mask > m_masks
List of the ROE masks.
Definition: RestOfEvent.h:363
void excludeParticlesFromMask(const std::string &maskName, const std::vector< const Particle * > &particles, Particle::EParticleSourceObject listType, bool discard)
Update mask by keeping or excluding particles.
Definition: RestOfEvent.cc:154
bool isInParticleList(const Particle *roeParticle, const std::vector< const Particle * > &particlesToUpdate) const
Checks if a particle has its copy in the provided list.
Definition: RestOfEvent.cc:370
bool m_isNested
Nested ROE indicator.
Definition: RestOfEvent.h:365
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
Abstract base class for different kinds of events.
Structure of Rest of Event mask.
Definition: RestOfEvent.h:68