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;
161 if (!mask->isValid()) {
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);
182 mask->clearParticles();
183 mask->addParticles(toKeepinROE);
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);
222 mask->clearParticles();
223 mask->addParticles(maskedParticles);
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!");
273 if (!mask->isValid()) {
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.
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.