10#include <analysis/dataobjects/RestOfEvent.h>
12#include <framework/datastore/StoreArray.h>
14#include <analysis/dataobjects/Particle.h>
15#include <mdst/dataobjects/ECLCluster.h>
22 for (
auto* particleToAdd : particlesToAdd) {
23 std::vector<const Particle*> daughters = particleToAdd->getFinalStateDaughters();
24 for (
auto* daughter : daughters) {
27 if (allParticles[myIndex]->isCopyOf(daughter,
true)) {
33 B2DEBUG(10,
"\t\tAdding particle with PDG " << daughter->getPDGCode());
42 std::vector<const Particle*> result;
46 B2DEBUG(10,
"ROE contains no particles, masks are empty too");
53 bool maskFound =
false;
55 if (mask.getName() == maskName) {
57 source = mask.getParticles();
62 B2FATAL(
"No '" << maskName <<
"' mask defined in current ROE!");
65 for (
const int index : source) {
66 if ((allParticles[index]->getParticleSource() == Particle::EParticleSourceObject::c_Composite or
67 allParticles[index]->getParticleSource() == Particle::EParticleSourceObject::c_V0) && unpackComposite) {
68 auto fsdaughters = allParticles[index]->getFinalStateDaughters();
69 for (
auto* daughter : fsdaughters) {
70 result.push_back(daughter);
74 result.push_back(allParticles[index]);
81 auto particles =
getParticles(maskName, unpackComposite);
82 std::vector<const Particle*> photons;
83 for (
auto* particle : particles) {
84 if (particle->getParticleSource() == Particle::EParticleSourceObject::c_ECLCluster) {
85 photons.push_back(particle);
93 auto particles =
getParticles(maskName, unpackComposite);
94 std::vector<const Particle*> hadrons;
95 for (
auto* particle : particles) {
96 if (particle->getParticleSource() == Particle::EParticleSourceObject::c_KLMCluster) {
97 hadrons.push_back(particle);
104 bool unpackComposite)
const
106 auto particles =
getParticles(maskName, unpackComposite);
107 std::vector<const Particle*> charged;
108 for (
auto* particle : particles) {
109 if (particle->getParticleSource() == Particle::EParticleSourceObject::c_Track) {
110 if (pdg == 0 || pdg == abs(particle->getPDGCode())) {
111 charged.push_back(particle);
122 B2FATAL(
"No '" << maskName <<
"' mask defined in current ROE!");
125 std::vector<const Particle*> particlesROE =
getParticles(maskName);
132 B2FATAL(
"Creation of ROE Mask with an empty name is not allowed!");
137 std::regex word_regex(
"^[a-zA-Z][a-zA-Z0-9_]*$");
138 if (!std::regex_match(name, word_regex)) {
139 B2FATAL(
"Mask name '" << name <<
"' contains forbidden characters or it does not start with a letter. "
140 "Only alphanumeric and underscore characters are allowed in ROE mask names.");
143 B2FATAL(
"ROE Mask '" << name <<
"' already exists!");
145 Mask elon(name, origin);
154 "Please check your inputs.");
158 B2FATAL(
"No '" << maskName <<
"' mask defined in current ROE!");
160 std::string maskNameToGetParticles = maskName;
164 std::vector<const Particle*> allROEParticles =
getParticles(maskNameToGetParticles);
165 std::vector<const Particle*> toKeepinROE;
166 for (
auto* roeParticle : allROEParticles) {
170 toKeepinROE.push_back(roeParticle);
174 if (listType != roeParticle->getParticleSource()) {
175 toKeepinROE.push_back(roeParticle);
176 }
else if (discard) {
178 toKeepinROE.push_back(roeParticle);
187 const std::shared_ptr<Variable::Cut>& eclCut,
const std::shared_ptr<Variable::Cut>& klmCut,
bool updateExisting)
191 "Please check your inputs.");
195 B2FATAL(
"ROE Mask '" << maskName <<
"' does not exist!");
198 if (updateExisting) {
200 sourceName = maskName;
203 std::vector<const Particle*> allROEParticles =
getParticles(sourceName,
false);
204 std::vector<const Particle*> maskedParticles;
206 for (
auto* particle : allROEParticles) {
207 if (particle->getParticleSource() == Particle::EParticleSourceObject::c_Track && (!trackCut || trackCut->check(particle))) {
208 maskedParticles.push_back(particle);
210 if (particle->getParticleSource() == Particle::EParticleSourceObject::c_ECLCluster && (!eclCut || eclCut->check(particle))) {
211 maskedParticles.push_back(particle);
213 if (particle->getParticleSource() == Particle::EParticleSourceObject::c_KLMCluster && (!klmCut || klmCut->check(particle))) {
214 maskedParticles.push_back(particle);
217 if (particle->getParticleSource() == Particle::EParticleSourceObject::c_Composite or
218 particle->getParticleSource() == Particle::EParticleSourceObject::c_V0) {
219 maskedParticles.push_back(particle);
230 "Please check your inputs.");
234 B2FATAL(
"ROE Mask '" << name <<
"' does not exist!");
236 std::vector<const Particle*> allROEParticles =
getParticles(name,
false);
237 std::vector<int> indicesToErase;
239 for (
auto* maskParticle : allROEParticles) {
241 for (
auto* daughterV0 : daughtersV0) {
242 if (daughterV0->isCopyOf(maskParticle,
true)) {
247 indicesToErase.push_back(maskParticle->getArrayIndex());
250 if (daughtersV0.size() != indicesToErase.size()) {
251 B2DEBUG(10,
"Only " << indicesToErase.size() <<
" daughters are excluded from mask particles. Abort");
254 std::string toprint =
"We will erase next indices from " + name +
" mask: ";
255 for (
auto& i : indicesToErase) {
256 toprint += std::to_string(i) +
" ";
258 B2DEBUG(10, toprint);
260 mask->
addV0(particleV0, indicesToErase);
267 "Please check your inputs.");
271 B2FATAL(
"ROE Mask '" << name <<
"' does not exist!");
276 if (particleV0->
getParticleSource() != Particle::EParticleSourceObject::c_Composite and
281 for (
auto* daughter : daughtersV0) {
282 if (daughter->getParticleSource() != Particle::EParticleSourceObject::c_Track) {
286 if (mask->
hasV0(particleV0)) {
295 if (mask.getName() == name) {
303 ROOT::Math::PxPyPzEVector roe4Vector;
305 for (
const Particle* particle : myParticles) {
308 if (particle->getParticleSource() == Particle::EParticleSourceObject::c_KLMCluster and !
m_useKLMEnergy) {
311 roe4Vector += particle->get4Vector();
320 if (mask.getName() == name) {
336 int nROEneutralECLClusters =
getPhotons(maskName).size();
337 int nROEchargedECLClusters = 0;
339 if (roeParticle->getECLCluster()) ++nROEchargedECLClusters;
342 return nROEneutralECLClusters + nROEchargedECLClusters;
347 int nROEKLMClusters =
getHadrons(maskName).size();
348 return nROEKLMClusters;
354 ROOT::Math::PxPyPzEVector roe4VectorECLClusters;
357 for (
auto& roeCluster : roeClusters) {
359 roe4VectorECLClusters += roeCluster->get4Vector();
362 return roe4VectorECLClusters;
367 for (
auto* listParticle : particlesToUpdate) {
368 if (roeParticle->
isCopyOf(listParticle,
true)) {
377 std::vector<std::string> maskNames;
380 maskNames.push_back(mask.getName());
388 std::string tab =
" - ";
392 B2WARNING(
"No mask with the name '" << maskName <<
"' exists in this ROE! Nothing else to print");
398 B2INFO(tab <<
"ROE is nested");
401 B2INFO(tab <<
"ROE is build from generated particles");
405 B2WARNING(
"This ROE has KLM energy included into its 4-vector!");
409 unsigned int nPhotons =
getPhotons(maskName, unpackComposite).size();
410 unsigned int nNeutralHadrons =
getHadrons(maskName, unpackComposite).size();
411 B2INFO(tab <<
"No. of Charged particles in ROE: " << nCharged);
412 B2INFO(tab <<
"No. of Photons in ROE: " << nPhotons);
413 B2INFO(tab <<
"No. of K_L0 and neutrons in ROE: " << nNeutralHadrons);
415 unsigned int nParticles =
getParticles(maskName, unpackComposite).size();
416 B2INFO(tab <<
"No. of generated particles in ROE: " << nParticles);
423 auto particles =
getParticles(maskName, unpackComposite);
424 if (particles.size() == 0) {
425 B2INFO(tab <<
"No indices to print");
428 std::string printoutIndex = tab +
"|";
429 std::string printoutPDG = tab +
"|";
430 for (
const auto particle : particles) {
431 printoutIndex += std::to_string(particle->getArrayIndex()) +
" | ";
432 printoutPDG += std::to_string(particle->getPDGCode()) +
" | ";
435 B2INFO(printoutIndex);
441 std::set<int> source;
446 bool maskFound =
false;
448 if (mask.getName() == maskName) {
450 source = mask.getParticles();
455 B2FATAL(
"No '" << maskName <<
"' mask defined in current ROE!");
458 int particlePDG = (pdgCode == 0) ?
getPDGCode() : pdgCode;
465 return particles.appendNew(
get4Vector(maskName), particlePDG, isFlavored, std::vector(source.begin(),
466 source.end()), propertyFlags);
@ c_nPhotons
CR is split into n photons (N1)
Class to store reconstructed particles.
EParticleSourceObject
particle source enumerators
std::vector< const Particle * > getFinalStateDaughters() const
Returns a vector of pointers to Final State daughter particles.
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.
void clearParticles()
Clear selected particles associated to the mask.
bool isValid() const
Get mask validity.
void addParticles(const std::vector< const Particle * > &particles)
Add selected particles to the mask.
bool hasV0(const Particle *v0) const
Has selected particles associated to the mask.
void addV0(const Particle *v0, std::vector< int > &toErase)
Get selected particles associated to the V0 of mask.