10#include <analysis/dataobjects/RestOfEvent.h>
12#include <framework/datastore/StoreArray.h>
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>
20#include <analysis/ClusterUtility/ClusterUtils.h>
27 for (
auto* particleToAdd : particlesToAdd) {
28 std::vector<const Particle*> daughters = particleToAdd->getFinalStateDaughters();
29 for (
auto* daughter : daughters) {
32 if (allParticles[myIndex]->isCopyOf(daughter,
true)) {
38 B2DEBUG(10,
"\t\tAdding particle with PDG " << daughter->getPDGCode());
47 std::vector<const Particle*> result;
51 B2DEBUG(10,
"ROE contains no particles, masks are empty too");
58 bool maskFound =
false;
60 if (mask.getName() == maskName) {
62 source = mask.getParticles();
67 B2FATAL(
"No '" << maskName <<
"' mask defined in current ROE!");
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);
79 result.push_back(allParticles[index]);
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);
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);
109 bool unpackComposite)
const
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);
127 B2FATAL(
"No '" << maskName <<
"' mask defined in current ROE!");
130 std::vector<const Particle*> particlesROE =
getParticles(maskName);
137 B2FATAL(
"Creation of ROE Mask with an empty name is not allowed!");
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.");
148 B2FATAL(
"ROE Mask '" << name <<
"' already exists!");
150 Mask elon(name, origin);
159 "Please check your inputs.");
163 B2FATAL(
"No '" << maskName <<
"' mask defined in current ROE!");
165 std::string maskNameToGetParticles = maskName;
166 if (!mask->isValid()) {
169 std::vector<const Particle*> allROEParticles =
getParticles(maskNameToGetParticles);
170 std::vector<const Particle*> toKeepinROE;
171 for (
auto* roeParticle : allROEParticles) {
175 toKeepinROE.push_back(roeParticle);
179 if (listType != roeParticle->getParticleSource()) {
180 toKeepinROE.push_back(roeParticle);
181 }
else if (discard) {
183 toKeepinROE.push_back(roeParticle);
187 mask->clearParticles();
188 mask->addParticles(toKeepinROE);
192 const std::shared_ptr<Variable::Cut>& eclCut,
const std::shared_ptr<Variable::Cut>& klmCut,
bool updateExisting)
196 "Please check your inputs.");
200 B2FATAL(
"ROE Mask '" << maskName <<
"' does not exist!");
203 if (updateExisting) {
205 sourceName = maskName;
208 std::vector<const Particle*> allROEParticles =
getParticles(sourceName,
false);
209 std::vector<const Particle*> maskedParticles;
211 for (
auto* particle : allROEParticles) {
212 if (particle->getParticleSource() == Particle::EParticleSourceObject::c_Track && (!trackCut || trackCut->check(particle))) {
213 maskedParticles.push_back(particle);
215 if (particle->getParticleSource() == Particle::EParticleSourceObject::c_ECLCluster && (!eclCut || eclCut->check(particle))) {
216 maskedParticles.push_back(particle);
218 if (particle->getParticleSource() == Particle::EParticleSourceObject::c_KLMCluster && (!klmCut || klmCut->check(particle))) {
219 maskedParticles.push_back(particle);
222 if (particle->getParticleSource() == Particle::EParticleSourceObject::c_Composite or
223 particle->getParticleSource() == Particle::EParticleSourceObject::c_V0) {
224 maskedParticles.push_back(particle);
227 mask->clearParticles();
228 mask->addParticles(maskedParticles);
235 "Please check your inputs.");
239 B2FATAL(
"ROE Mask '" << name <<
"' does not exist!");
241 std::vector<const Particle*> allROEParticles =
getParticles(name,
false);
242 std::vector<int> indicesToErase;
244 for (
auto* maskParticle : allROEParticles) {
246 for (
auto* daughterV0 : daughtersV0) {
247 if (daughterV0->isCopyOf(maskParticle,
true)) {
252 indicesToErase.push_back(maskParticle->getArrayIndex());
255 if (daughtersV0.size() != indicesToErase.size()) {
256 B2DEBUG(10,
"Only " << indicesToErase.size() <<
" daughters are excluded from mask particles. Abort");
259 std::string toprint =
"We will erase next indices from " + name +
" mask: ";
260 for (
auto& i : indicesToErase) {
261 toprint += std::to_string(i) +
" ";
263 B2DEBUG(10, toprint);
265 mask->addV0(particleV0, indicesToErase);
272 "Please check your inputs.");
276 B2FATAL(
"ROE Mask '" << name <<
"' does not exist!");
278 if (!mask->isValid()) {
281 if (particleV0->
getParticleSource() != Particle::EParticleSourceObject::c_Composite and
286 for (
auto* daughter : daughtersV0) {
287 if (daughter->getParticleSource() != Particle::EParticleSourceObject::c_Track) {
291 if (mask->hasV0(particleV0)) {
300 if (mask.getName() == name) {
308 ROOT::Math::PxPyPzEVector roe4Vector;
310 for (
const Particle* particle : myParticles) {
313 if (particle->getParticleSource() == Particle::EParticleSourceObject::c_KLMCluster and !
m_useKLMEnergy) {
316 roe4Vector += particle->get4Vector();
325 if (mask.getName() == name) {
341 int nROEneutralECLClusters =
getPhotons(maskName).size();
342 int nROEchargedECLClusters = 0;
344 if (roeParticle->getECLCluster()) ++nROEchargedECLClusters;
347 return nROEneutralECLClusters + nROEchargedECLClusters;
352 int nROEKLMClusters =
getHadrons(maskName).size();
353 return nROEKLMClusters;
359 ROOT::Math::PxPyPzEVector roe4VectorECLClusters;
362 for (
auto& roeCluster : roeClusters) {
364 roe4VectorECLClusters += roeCluster->get4Vector();
367 return roe4VectorECLClusters;
372 for (
auto* listParticle : particlesToUpdate) {
373 if (roeParticle->
isCopyOf(listParticle,
true)) {
382 std::vector<std::string> maskNames;
385 maskNames.push_back(mask.getName());
393 std::string tab =
" - ";
397 B2WARNING(
"No mask with the name '" << maskName <<
"' exists in this ROE! Nothing else to print");
403 B2INFO(tab <<
"ROE is nested");
406 B2INFO(tab <<
"ROE is build from generated particles");
410 B2WARNING(
"This ROE has KLM energy included into its 4-vector!");
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);
420 unsigned int nParticles =
getParticles(maskName, unpackComposite).size();
421 B2INFO(tab <<
"No. of generated particles in ROE: " << nParticles);
428 auto particles =
getParticles(maskName, unpackComposite);
429 if (particles.size() == 0) {
430 B2INFO(tab <<
"No indices to print");
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()) +
" | ";
440 B2INFO(printoutIndex);
446 std::set<int> source;
451 bool maskFound =
false;
453 if (mask.getName() == maskName) {
455 source = mask.getParticles();
460 B2FATAL(
"No '" << maskName <<
"' mask defined in current ROE!");
463 int particlePDG = (pdgCode == 0) ?
getPDGCode() : pdgCode;
470 return particles.appendNew(
get4Vector(maskName), particlePDG, isFlavored, std::vector(source.begin(),
471 source.end()), propertyFlags);
@ c_nPhotons
CR is split into n photons (N1)
Class to store reconstructed particles.
std::vector< const Belle2::Particle * > getFinalStateDaughters() const
Returns a vector of pointers to Final State daughter particles.
EParticleSourceObject
particle source enumerators
bool isCopyOf(const Particle *oParticle, bool doDetailedComparison=false) const
Returns true if this Particle and oParticle are copies of each other.
EParticleSourceObject getParticleSource() const
Returns particle source as defined with enum EParticleSourceObject.
@ c_Unflavored
Is its own antiparticle or we don't know whether it is a particle/antiparticle.
@ c_Flavored
Is either particle or antiparticle.
@ c_IsIgnoreRadiatedPhotons
Is the particle MC matched with the ignore radiated photon flag set?
@ c_IsUnspecified
Ordinary particles.
@ c_IsIgnoreIntermediate
Is the particle MC matched with the ignore intermediate resonances flag set?
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.
int getPDGCode() const
Gets the PDG code of the rest of event.
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.
std::set< int > m_particleIndices
StoreArray indices to unused particles.
std::vector< const Particle * > getParticles(const std::string &maskName=c_defaultMaskName, bool unpackComposite=true) const
Get all Particles from ROE mask.
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.
void print(const std::string &maskName=c_defaultMaskName, bool unpackComposite=true) const
Prints the contents of a RestOfEvent object to screen.
void initializeMask(const std::string &name, const std::string &origin="unknown")
Initialize new mask.
bool checkCompatibilityOfMaskAndV0(const std::string &name, const Particle *particleV0)
Check if V0 can be added, maybe should be moved to private.
static constexpr const char * c_defaultMaskName
Default mask name.
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.
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.
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.
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.
bool hasMask(const std::string &name) const
True if this ROE object has mask.
std::vector< const Particle * > getPhotons(const std::string &maskName=c_defaultMaskName, bool unpackComposite=true) const
Get photons from ROE mask.
bool m_isFromMC
MC ROE indicator.
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.
Mask * findMask(const std::string &name)
Helper method to find ROE mask.
Particle * convertToParticle(const std::string &maskName=c_defaultMaskName, int pdgCode=0, bool isSelfConjugated=true)
Converts ROE to Particle and adds it to StoreArray.
void addParticles(const std::vector< const Particle * > &particle)
Add StoreArray indices of given Particles to the list of unused particles in the event.
int getNKLMClusters(const std::string &maskName=c_defaultMaskName) const
Get number of all remaining KLM clusters.
std::vector< std::string > getMaskNames() const
Get vector of all mask names of the ROE object.
void updateMaskWithV0(const std::string &name, const Particle *particleV0)
Update mask with composite particle.
bool m_useKLMEnergy
Include KLM energy into ROE 4-vector.
std::vector< const Particle * > getHadrons(const std::string &maskName=c_defaultMaskName, bool unpackComposite=true) const
Get hadrons from ROE mask.
std::vector< Mask > m_masks
List of the ROE masks.
void excludeParticlesFromMask(const std::string &maskName, const std::vector< const Particle * > &particles, Particle::EParticleSourceObject listType, bool discard)
Update mask by keeping or excluding particles.
bool isInParticleList(const Particle *roeParticle, const std::vector< const Particle * > &particlesToUpdate) const
Checks if a particle has its copy in the provided list.
bool m_isNested
Nested ROE indicator.
Accessor to arrays stored in the data store.
Abstract base class for different kinds of events.
Structure of Rest of Event mask.