10#include <analysis/modules/ParticleListManipulator/ParticleListManipulatorModule.h>
14#include <framework/datastore/DataStore.h>
17#include <framework/logging/Logger.h>
20#include <analysis/DecayDescriptor/ParticleListName.h>
21#include <analysis/utility/ValueIndexPairSorting.h>
22#include <analysis/VariableManager/Utility.h>
41 setDescription(
"Manipulates ParticleLists: copies/merges/performs particle selection");
47 vector<string> defaultList;
49 "list of input ParticleList names", defaultList);
53 addParam(
"variable",
m_variableName,
"Variable which defines the best duplicate (see ``selectLowest`` for ordering)",
54 std::string(
"mdstIndex"));
56 "If true, duplicate with lowest value of ``variable`` is accepted, otherwise higher one.",
true);
59 "If true, the output ParticleList will be saved by RootOutput. If false, it will be ignored when writing the file.",
false);
62 "If true, the flavor of the mother particle is ignored.",
false);
78 B2ERROR(
"ParticleListManipulatorModule::initialize Invalid output ParticleList name: " <<
m_outputListName);
88 string listLabel = mother->
getLabel();
93 " but the label 'all' is forbidden for user-defined lists of final-state particles." <<
94 " It could introduce *very* dangerous bugs.");
95 }
else if (listLabel ==
"V0" and
100 " but the label " << listLabel <<
" is not allowed for merged or copied particle lists.");
103 if (listLabel ==
"V0" and
113 B2ERROR(
"ParticleListManipulatorModule: cannot copy Particles from " << listName <<
114 " to itself! Use applyCuts() (ParticleSelector module) instead.");
116 B2ERROR(
"Invalid input ParticleList name: " << listName);
130 B2ERROR(
"Variable '" <<
m_variableName <<
"' is not available in Variable::Manager!");
132 if (!(
m_variable->variabletype == Variable::Manager::VariableDataType::c_double
133 or
m_variable->variabletype == Variable::Manager::VariableDataType::c_int)) {
134 B2ERROR(
"Variable '" <<
m_variableName <<
"' has wrong data type! It must be either double or integer.");
164 std::vector<int> idSeq;
174 typedef std::pair<double, unsigned int> ValueIndexPair;
175 std::vector<ValueIndexPair> valueToIndex;
180 if (!inPList.
isValid())
continue;
182 std::vector<int> fsParticles = inPList->getList(ParticleList::EParticleType::c_FlavorSpecificParticle,
false);
183 const std::vector<int>& scParticles = inPList->getList(ParticleList::EParticleType::c_SelfConjugatedParticle,
false);
184 const std::vector<int>& fsAntiParticles = inPList->getList(ParticleList::EParticleType::c_FlavorSpecificParticle,
true);
186 fsParticles.insert(fsParticles.end(), scParticles.begin(), scParticles.end());
187 fsParticles.insert(fsParticles.end(), fsAntiParticles.begin(), fsAntiParticles.end());
189 for (
int fsParticle : fsParticles) {
192 if (
m_cut->check(part)) {
193 double value = std::numeric_limits<double>::quiet_NaN();;
194 if (std::holds_alternative<double>(
m_variable->function(part))) {
195 value = std::get<double>(
m_variable->function(part));
196 }
else if (std::holds_alternative<int>(
m_variable->function(part))) {
197 value = std::get<int>(
m_variable->function(part));
207 std::stable_sort(valueToIndex.begin(), valueToIndex.end(), ValueIndexPairSorting::lowerPair<ValueIndexPair>);
209 std::stable_sort(valueToIndex.begin(), valueToIndex.end(), ValueIndexPairSorting::higherPair<ValueIndexPair>);
213 for (
const auto& candidate : valueToIndex) {
216 std::vector<int> idSeq;
233 if (ignoreMotherFlavor or abs(p->getPDGCode()) ==
Const::neutron.getPDGCode()) idSequence.push_back(abs(p->getPDGCode()));
234 else idSequence.push_back(p->getPDGCode());
236 if (p->getNDaughters() == 0) {
237 idSequence.push_back(p->getMdstSource());
239 idSequence.push_back(p->getNDaughters());
240 auto daughters = p->getDaughters();
242 sort(daughters.begin(), daughters.end(), [](
const auto a,
const auto b) {
243 return a->getPDGCode() > b->getPDGCode();
246 for (
const auto& daughter : daughters)
254 bool sameSeq = (idSeqIN == idSeqOUT);
The ParticleType class for identifying different particle types.
static const ParticleType neutron
neutron particle
static const ParticleSet finalStateParticlesSet
set of final set particles that can be created by the ParticleLoader
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 getLabel() const
The label of this particle, "default" returned, when no label set.
static std::unique_ptr< GeneralCut > compile(const std::string &cut)
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...
bool m_isSelfConjugatedParticle
flag that indicates whether an anti-particle does not exist and therefore the output anti-ParticleLis...
ParticleListManipulatorModule()
Constructor.
bool m_preferLowest
Select the duplicate with the lowest value (instead of highest).
virtual void initialize() override
Initialize the Module.
virtual void event() override
Event processor.
std::string m_variableName
Variable which defines the best duplicate.
std::vector< std::string > m_inputListNames
input ParticleList names
StoreArray< Particle > m_particles
StoreArray of Particles.
std::vector< std::vector< int > > m_particlesInTheList
This vector holds unique identifiers (vector of ints) of all particles that are already included in t...
std::unique_ptr< Variable::Cut > m_cut
cut object which performs the cuts
bool m_ignoreMotherFlavor
flag whether flavor of mother particle should be ignored
bool isUnique(const std::vector< int > &idSequence)
Compares input idSequence to all sequences already included in the list.
const Variable::Manager::Var * m_variable
Variable which defines the best duplicate selection.
void fillUniqueIdentifier(const Particle *p, std::vector< int > &idSequence, bool ignoreMotherFlavor)
Fills unique identifier for the input particle.
std::string m_cutParameter
selection criteria
DecayDescriptor m_decaydescriptor
Decay descriptor of the particle being selected.
bool m_exceptionForV0B2BII
true if the output List is V0 and input is K_S0:mdst, Lambda0:mdst, or gamma:v0mdst
bool m_writeOut
toggle Particle List btw.
int m_pdgCode
PDG code of the particles.
StoreObjPtr< ParticleList > m_particleList
output particle list
std::string m_outputAntiListName
output anti-particle list name
StoreObjPtr< ParticleList > m_antiParticleList
output anti-particle list
std::string m_outputListName
output ParticleList name
Class to store reconstructed particles.
int getArrayIndex() const
Returns this object's array index (in StoreArray), or -1 if not found.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
Type-safe access to single objects in the data store.
bool isValid() const
Check whether the object was created.
const Var * getVariable(std::string name)
Get the variable belonging to the given key.
static Manager & Instance()
get singleton instance.
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.