10 #include <analysis/modules/ParticleLoader/ParticleLoaderModule.h> 
   13 #include <framework/logging/Logger.h> 
   14 #include <framework/core/ModuleParam.templateDetails.h> 
   17 #include <analysis/DecayDescriptor/ParticleListName.h> 
   18 #include <analysis/utility/PCmsLabTransform.h> 
   35 ParticleLoaderModule::ParticleLoaderModule() : 
Module()
 
   38   setDescription(
"Loads MDST dataobjects as Particle objects to the StoreArray<Particle> and collects them in specified ParticleList.");
 
   43            "List of decay strings (see :ref:`DecayString` for syntax) that specify all output ParticleLists to be created by the module.",
 
   47            "Use MCParticles instead of reconstructed MDST dataobjects (tracks, ECL, KLM, clusters, V0s, ...)", 
false);
 
   50            "Use ROE instead of reconstructed MDST dataobjects (tracks, ECL, KLM, clusters, V0s, ...)", 
false);
 
   56            "Particle list name from which we need to get ROEs", std::string(
""));
 
   59            "If true, the Particle List will be filled with missing momentum from the ROE and signal particle.", 
false);
 
   62            "If true, the output ParticleList will be saved by RootOutput. If false, it will be ignored when writing the file.", 
false);
 
   65            "If true, the secondary MC particle will be skipped, default is false",
 
   69            "If true, the particles from the bottom part of the selected particle's decay chain will also be created in the datastore and mother-daughter relations are recursively set",
 
   73            "If true, the secondary MC daughters will be skipped, default is false",
 
   77            "Track hypothesis to use when loading the particle. By default, use the particle's own hypothesis.",
 
   81            "If true, a Particle is only created if a track fit with the particle hypothesis passed to the ParticleLoader is available.",
 
   87   B2INFO(
"ParticleLoader's Summary of Actions:");
 
  108     B2WARNING(
"Obsolete usage of the ParticleLoader module (load all MDST objects as all possible Particle object types). Specify the particle type via decayStrings module parameter instead.");
 
  115         B2ERROR(
"ParticleLoaderModule::initialize Invalid input DecayString: " << decayString);
 
  123       string listName = mother->
getName() + 
":all";
 
  129       else if (nProducts > 0) listName = mother->
getName() + 
":V0";
 
  132       bool isSelfConjugatedParticle = (listName == antiListName);
 
  136       if (!particleList.isOptional()) {
 
  138         particleList.registerInDataStore(flags);
 
  139         if (!isSelfConjugatedParticle) {
 
  146         B2ERROR(
"Invalid particle type requested to be loaded. Set a valid decayString module parameter.");
 
  149       bool mdstSourceIsV0 = 
false;
 
  153         mdstSourceIsV0 = 
true;
 
  155       if (mdstSourceIsV0 == 
false) {
 
  158             B2ERROR(
"ParticleLoaderModule::initialize Invalid input DecayString " << decayString
 
  159                     << 
". DecayString should not contain any daughters, only the mother particle.");
 
  161             B2INFO(
"ParticleLoaderModule: Replacing the source particle list name by " <<
 
  163                    << 
" all other daughters will be ignored.");
 
  169           B2ERROR(
"ParticleLoaderModule::initialize Invalid input DecayString " << decayString
 
  170                   << 
". MDST source of the particle list is V0, DecayString should contain exactly two daughters, as well as the mother particle.");
 
  173             B2ERROR(
"MDST source of the particle list is V0, the two daughters should have opposite charge");
 
  178       B2INFO(
" o) creating (anti-)ParticleList with name: " << listName << 
" (" << antiListName << 
")");
 
  180         B2INFO(
"   -> MDST source: RestOfEvents");
 
  181         m_ROE2Plists.emplace_back(pdgCode, listName, antiListName, isSelfConjugatedParticle);
 
  183         B2INFO(
"   -> MDST source: MCParticles");
 
  188           B2INFO(
"   -> MDST source: Tracks");
 
  189           m_Tracks2Plists.emplace_back(pdgCode, listName, antiListName, isSelfConjugatedParticle);
 
  195             B2INFO(
"   -> MDST source: ECLClusters and KLMClusters");
 
  197             B2INFO(
"   -> MDST source: V0");
 
  198             m_V02Plists.emplace_back(pdgCode, listName, antiListName, isSelfConjugatedParticle);
 
  203           B2INFO(
"   -> MDST source: V0");
 
  204           m_V02Plists.emplace_back(pdgCode, listName, antiListName, isSelfConjugatedParticle);
 
  208           B2INFO(
"   -> MDST source: exclusively KLMClusters or exclusively ECLClusters (matching between those not used)");
 
  213           B2INFO(
"   -> MDST source: V0");
 
  214           m_V02Plists.emplace_back(pdgCode, listName, antiListName, isSelfConjugatedParticle);
 
  249                 << 
" tracks skipped because of zero charge for " 
  250                 << get<c_PListName>(track2Plist));
 
  257                 << 
" v0s skipped because of same charge daughters for " 
  258                 << get<c_PListName>(v02Plist));
 
  268   string listName = get<c_PListName>(roe2Plist);
 
  269   string antiListName = get<c_AntiPListName>(roe2Plist);
 
  270   int pdgCode = get<c_PListPDGCode>(roe2Plist);
 
  271   bool isSelfConjugatedParticle = get<c_IsPListSelfConjugated>(roe2Plist);
 
  279   plist->initialize(pdgCode, listName);
 
  281   if (!isSelfConjugatedParticle) {
 
  284     antiPlist->initialize(-1 * pdgCode, antiListName);
 
  285     antiPlist->bindAntiParticleList(*(plist));
 
  292     for (
unsigned int i = 0; i < pList->getListSize(); i++) {
 
  303     for (
int i = 0; i < 
m_roes.getEntries(); i++) {
 
  322     ROOT::Math::PxPyPzEVector signal4Vector = signalSideParticle->get4Vector();
 
  324     ROOT::Math::PxPyPzEVector missing4Vector = boost4Vector - signal4Vector - roe4Vector;
 
  325     auto isFlavored = (isSelfConjugatedParticle) ? Particle::EFlavorType::c_Unflavored : Particle::EFlavorType::c_Flavored;
 
  326     newPart = 
m_particles.appendNew(missing4Vector, pdgCode, isFlavored, Particle::EParticleSourceObject::c_Undefined, mdstIndex);
 
  330     string listName = get<c_PListName>(roe2Plist);
 
  332     plist->addParticle(newPart);
 
  343   bool matchingDaughtersOrder = 
true;
 
  346     matchingDaughtersOrder = 
false;
 
  349   for (
size_t ilist = 0; ilist < 
m_V02Plists.size(); ilist++) {
 
  351     string listName = get<c_PListName>(v02Plist);
 
  352     string antiListName = get<c_AntiPListName>(v02Plist);
 
  353     int pdgCode = get<c_PListPDGCode>(v02Plist);
 
  354     bool isSelfConjugatedParticle = get<c_IsPListSelfConjugated>(v02Plist);
 
  362     plist->initialize(pdgCode, listName);
 
  364     if (!isSelfConjugatedParticle) {
 
  367       antiPlist->initialize(-1 * pdgCode, antiListName);
 
  369       antiPlist->bindAntiParticleList(*(plist));
 
  373     for (
int i = 0; i < 
m_v0s.getEntries(); i++) {
 
  382         B2DEBUG(19, 
"V0 with same charge daughters skipped!");
 
  406         B2WARNING(
"Unknown V0 hypothesis!");
 
  412       bool correctOrder = matchingDaughtersOrder;
 
  415         correctOrder = !correctOrder;
 
  417       std::pair<Track*, Track*> v0Tracks = v0->
getTracks();
 
  418       std::pair<TrackFitResult*, TrackFitResult*> v0TrackFitResults = v0->
getTrackFitResults();
 
  420       Particle daugP((v0Tracks.first)->getArrayIndex(), v0TrackFitResults.first, pTypeP);
 
  421       Particle daugM((v0Tracks.second)->getArrayIndex(), v0TrackFitResults.second, pTypeM);
 
  423       const PIDLikelihood* pidP = (v0Tracks.first)->getRelated<PIDLikelihood>();
 
  424       const PIDLikelihood* pidM = (v0Tracks.second)->getRelated<PIDLikelihood>();
 
  426       const auto& mcParticlePWithWeight = (v0Tracks.first)->getRelatedToWithWeight<MCParticle>();
 
  427       const auto& mcParticleMWithWeight = (v0Tracks.second)->getRelatedToWithWeight<MCParticle>();
 
  444       if (mcParticlePWithWeight.first)
 
  445         newDaugP->
addRelationTo(mcParticlePWithWeight.first, mcParticlePWithWeight.second);
 
  450       if (mcParticleMWithWeight.first)
 
  451         newDaugM->
addRelationTo(mcParticleMWithWeight.first, mcParticleMWithWeight.second);
 
  471       plist->addParticle(newPart);
 
  484     string listName = get<c_PListName>(track2Plist);
 
  485     string antiListName = get<c_AntiPListName>(track2Plist);
 
  486     int pdgCode = get<c_PListPDGCode>(track2Plist);
 
  487     bool isSelfConjugatedParticle = get<c_IsPListSelfConjugated>(track2Plist);
 
  495     plist->initialize(pdgCode, listName);
 
  498     if (!isSelfConjugatedParticle) {
 
  501       antiPlist->initialize(-1 * pdgCode, antiListName);
 
  503       antiPlist->bindAntiParticleList(*(plist));
 
  508     for (
int i = 0; i < 
m_tracks.getEntries(); i++) {
 
  511       const auto& mcParticleWithWeight = track->getRelatedToWithWeight<
MCParticle>();
 
  519       const TrackFitResult* trackFit = track->getTrackFitResultWithClosestMass(type);
 
  522         B2WARNING(
"Track returned null TrackFitResult pointer for ChargedStable::getPDGCode()  = " << type.getPDGCode());
 
  535         B2DEBUG(19, 
"Track with charge = 0 skipped!");
 
  541       Particle particle(track->getArrayIndex(), trackFit, type);
 
  548         if (mcParticleWithWeight.first)
 
  549           newPart->
addRelationTo(mcParticleWithWeight.first, mcParticleWithWeight.second);
 
  552         plist->addParticle(newPart);
 
  566     string listName = get<c_PListName>(eclKLMCluster2Plist);
 
  567     string antiListName = get<c_AntiPListName>(eclKLMCluster2Plist);
 
  568     int pdgCode = get<c_PListPDGCode>(eclKLMCluster2Plist);
 
  569     bool isSelfConjugatedParticle = get<c_IsPListSelfConjugated>(eclKLMCluster2Plist);
 
  577     plist->initialize(pdgCode, listName);
 
  580     if (!isSelfConjugatedParticle) {
 
  583       antiPlist->initialize(-1 * pdgCode, antiListName);
 
  585       antiPlist->bindAntiParticleList(*(plist));
 
  595       if (!cluster->isNeutral()) 
continue;
 
  605       std::vector<std::pair<int, double>> weightsAndIndices;
 
  606       for (
unsigned int iMCParticle = 0; iMCParticle < mcRelations.
size(); iMCParticle++) {
 
  607         const MCParticle* relMCParticle = mcRelations[iMCParticle];
 
  608         double weight = mcRelations.
weight(iMCParticle);
 
  610           weightsAndIndices.emplace_back(relMCParticle->
getArrayIndex(), weight);
 
  613       std::sort(weightsAndIndices.begin(), weightsAndIndices.end(),
 
  614       [](
const std::pair<int, double>& left, 
const std::pair<int, double>& right) {
 
  615         return left.second > right.second;
 
  639       Particle particle(cluster, thisType);
 
  641         B2FATAL(
"Particle created from ECLCluster does not have ECLCluster type.");
 
  647       for (
auto& weightsAndIndex : weightsAndIndices) {
 
  649         double weight = weightsAndIndex.second;
 
  656               && weight / relMCParticle->
getEnergy() > 0.30)
 
  661       plist->addParticle(newPart);
 
  668       if (std::isnan(cluster->getMomentumMag())) {
 
  669         B2DEBUG(19, 
"Skipping KLMCluster because its momentum is NaN. " 
  670                 "This can happen if the timing calibration is missing or wrong, so that the velocity is calculated to be negative.");
 
  677       Particle particle(cluster, pdgCode);
 
  678       if (particle.getParticleSource() != Particle::c_KLMCluster) {
 
  679         B2FATAL(
"Particle created from KLMCluster does not have KLMCluster type.");
 
  687       plist->addParticle(newPart);
 
  699     string listName = get<c_PListName>(mcParticle2Plist);
 
  700     string antiListName = get<c_AntiPListName>(mcParticle2Plist);
 
  701     int pdgCode = get<c_PListPDGCode>(mcParticle2Plist);
 
  702     bool isSelfConjugatedParticle = get<c_IsPListSelfConjugated>(mcParticle2Plist);
 
  710     plist->initialize(pdgCode, listName);
 
  712     if (!isSelfConjugatedParticle) {
 
  715       antiPlist->initialize(-1 * pdgCode, antiListName);
 
  717       antiPlist->bindAntiParticleList(*(plist));
 
  723       if (abs(pdgCode) != abs(mcParticle->
getPDG()))
 
  736       plist->addParticle(newPart);
 
  774   vector<MCParticle*> mcdaughters = mcmother->
getDaughters();
 
  776   for (
auto& mcdaughter : mcdaughters) {
 
  780     daughter->addRelationTo(mcdaughter);
 
  783     if (mcdaughter->getNDaughters() > 0)
 
Provides a type-safe way to pass members of the chargedStableSet set.
bool contains(const ParticleType &p) const
Returns true if and only if the set contains 'p'.
The ParticleType class for identifying different particle types.
int getPDGCode() const
PDG code.
static const ParticleType neutron
neutron particle
static const ParticleType Lambda
Lambda particle.
static const ParticleSet chargedStableSet
set of charged stable particles
static const ChargedStable pion
charged pion particle
static const ParticleType Klong
K^0_L particle.
static const ParticleType antiLambda
Anti-Lambda particle.
static const ChargedStable proton
proton particle
static const ParticleType invalidParticle
Invalid particle, used internally.
static const ParticleType Kshort
K^0_S particle.
static const ParticleType photon
photon particle
static const ChargedStable electron
electron particle
EStoreFlags
Flags describing behaviours of objects etc.
@ c_WriteOut
Object/array should be saved by output modules.
@ c_DontWriteOut
Object/array should be NOT saved by output modules.
Represents a particle in the DecayDescriptor.
int getPDGCode() const
Return PDG code.
std::string getFullName() const
returns the full name of the particle full_name = name:label
std::string getName() const
evt.pdl name of the particle.
bool init(const std::string &str)
Initialise the DecayDescriptor from given string.
const DecayDescriptorParticle * getMother() const
return mother.
int getNDaughters() const
return number of direct daughters.
const DecayDescriptor * getDaughter(int i) const
return i-th daughter (0 based index).
@ c_nPhotons
CR is split into n photons (N1)
@ c_neutralHadron
CR is reconstructed as a neutral hadron (N2)
A Class to store the Monte Carlo particle information.
float getEnergy() const
Return particle energy in GeV.
@ c_PrimaryParticle
bit 0: Particle is primary particle.
std::vector< Belle2::MCParticle * > getDaughters() const
Get vector of all daughter particles, empty vector if none.
bool hasStatus(unsigned short int bitmask) const
Return if specific status bit is set.
int getArrayIndex() const
Get 0-based index of the particle in the corresponding MCParticle list.
int getPDG() const
Return PDG code of particle.
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Class to collect log likelihoods from TOP, ARICH, dEdx, ECL and KLM aimed for output to mdst includes...
std::vector< PList > m_ECLKLMClusters2Plists
Collection of PLists that will collect Particles created from ECLClusters and KLMClusters.
void mcParticlesToParticles()
Loads specified MCParticles as Particle to StoreArray<Particle>
void v0sToParticles()
Loads V0 object as Particle of specified type to StoreArray<Particle> and adds it to the ParticleList...
StoreArray< TrackFitResult > m_trackfitresults
StoreArray of TrackFitResults.
std::vector< std::string > m_decayStrings
Input decay strings specifying the particles being created/loaded.
void roeToParticles()
Loads ROE object as Particle of specified type to StoreArray<Particle> and adds it to the ParticleLis...
virtual void initialize() override
Initialize the Module.
int m_trackHypothesis
pdg code for track hypothesis that should be used to create the particle
StoreArray< KLMCluster > m_klmclusters
StoreArray of KLMCluster.
std::vector< int > m_sameChargeDaughtersV0Counts
internally used to count the number of V0s with same charge daughters
StoreArray< V0 > m_v0s
StoreArray of V0s.
void addROEToParticleList(RestOfEvent *roe, int mdstIndex, int pdgCode=0, bool isSelfConjugatedParticle=true)
Helper method to load ROE object as Particle.
virtual void event() override
Event processor.
std::string m_sourceParticleListName
Particle list name from which we need to get related ROEs.
bool isValidPDGCode(const int pdgCode)
returns true if the PDG code determined from the decayString is valid
StoreArray< MCParticle > m_mcparticles
StoreArray of MCParticles.
StoreArray< Particle > m_particles
StoreArray of Particles.
std::string m_roeMaskName
ROE mask name to load.
virtual void terminate() override
Terminate the Module.
void tracksToParticles()
Loads Track object as Particle to StoreArray<Particle> and adds it to the ParticleList.
StoreObjPtr< ParticleExtraInfoMap > m_particleExtraInfoMap
object pointer to extra info map
bool m_addDaughters
toggle addition of the bottom part of the particle's decay chain
StoreArray< PIDLikelihood > m_pidlikelihoods
StoreArray of PIDLikelihoods.
bool m_skipNonPrimaryDaughters
toggle skip of secondary MC daughters
StoreArray< Track > m_tracks
StoreArray of Tracks.
bool m_enforceFitHypothesis
If true, a Particle is only created if a track fit with the particle hypothesis passed to the Particl...
std::vector< PList > m_ROE2Plists
Collection of PLists that will collect Particles created from V0.
StoreArray< RestOfEvent > m_roes
StoreArray of ROEs.
void appendDaughtersRecursive(Particle *mother)
recursively append bottom of a particle's decay chain (daughters of mother, granddaughters of daughte...
std::vector< PList > m_MCParticles2Plists
Collection of PLists that will collect Particles created from MCParticles.
std::vector< PList > m_V02Plists
Collection of PLists that will collect Particles created from V0.
DecayDescriptor m_decaydescriptor
Decay descriptor for parsing the user specified DecayString.
bool m_writeOut
toggle particle list btw.
std::vector< int > m_chargeZeroTrackCounts
internally used to count number of tracks with charge zero
std::vector< PList > m_Tracks2Plists
Collection of PLists that will collect Particles created from Tracks.
StoreObjPtr< EventExtraInfo > m_eventExtraInfo
object pointer to event extra info
StoreArray< ECLCluster > m_eclclusters
StoreArray of ECLCluster.
bool m_skipNonPrimary
toggle skip of secondary MC particle
bool m_useROEs
Switch to load ROE as Particle.
bool m_useMissing
Use missing momentum to build a particle.
void eclAndKLMClustersToParticles()
Loads ECLCluster and KLMCluster object as Particle to StoreArray<Particle> and adds it to the Particl...
bool m_useMCParticles
Load MCParticle as Particle instead of the corresponding MDST dataobject.
Class to store reconstructed particles.
ROOT::Math::PxPyPzEVector get4Vector() const
Returns Lorentz vector.
EParticleSourceObject getParticleSource() const
Returns particle source as defined with enum EParticleSourceObject.
EFlavorType
describes flavor type, see getFlavorType().
@ c_Unflavored
Is its own antiparticle or we don't know whether it is a particle/antiparticle.
@ c_Flavored
Is either particle or antiparticle.
double getECLClusterEnergy() const
Returns the energy of the ECLCluster for the particle.
void appendDaughter(const Particle *daughter, const bool updateType=true)
Appends index of daughter to daughters index array.
Class for type safe access to objects that are referred to in relations.
size_t size() const
Get number of relations.
float weight(int index) const
Get weight with index.
void addRelationTo(const RelationsInterface< BASE > *object, float weight=1.0, const std::string &namedRelation="") const
Add a relation from this object to another object (with caching).
int getArrayIndex() const
Returns this object's array index (in StoreArray), or -1 if not found.
FROM * getRelatedFrom(const std::string &name="", const std::string &namedRelation="") const
Get the object from which this object has a relation.
T * getRelated(const std::string &name="", const std::string &namedRelation="") const
Get the object to or from which this object has a relation.
This is a general purpose class for collecting reconstructed MDST data objects that are not used in r...
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.
static constexpr const char * c_defaultMaskName
Default mask name.
Particle * convertToParticle(const std::string &maskName=c_defaultMaskName, int pdgCode=0, bool isSelfConjugated=true)
Converts ROE to Particle and adds it to StoreArray.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
bool create(bool replace=false)
Create a default object in the data store.
Type-safe access to single objects in the data store.
bool isValid() const
Check whether the object was created.
Values of the result of a track fit with a given particle hypothesis.
short getChargeSign() const
Return track charge (1 or -1).
Const::ParticleType getParticleType() const
Getter for ParticleType of the mass hypothesis of the track fit.
Class that bundles various TrackFitResults.
Object holding information for V0s.
std::pair< TrackFitResult *, TrackFitResult * > getTrackFitResults() const
Get pair of the TrackFitResults, that are part of the V0 particle.
std::pair< Track *, Track * > getTracks() const
Get pair of yhe Tracks, that are part of the V0 particle.
Const::ParticleType getV0Hypothesis() const
Get the hypothesis under which the V0 particle was created.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
std::string antiParticleListName(const std::string &listName)
Returns name of anti-particle-list corresponding to listName.
Abstract base class for different kinds of events.