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.