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;
 
  464   auto isFlavored = (isSelfConjugated) ? Particle::EFlavorType::c_Unflavored : Particle::EFlavorType::c_Flavored;
 
  466   int propertyFlags = Particle::PropertyFlags::c_IsUnspecified;
 
  468   propertyFlags |= Particle::PropertyFlags::c_IsIgnoreIntermediate;
 
  469   propertyFlags |= Particle::PropertyFlags::c_IsIgnoreRadiatedPhotons;
 
  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.
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.