10 #include <analysis/modules/KlongDecayReconstructor/KlongDecayReconstructorExpertModule.h>
13 #include <framework/logging/Logger.h>
16 #include <analysis/DecayDescriptor/DecayDescriptorParticle.h>
19 #include <analysis/DecayDescriptor/ParticleListName.h>
42 Module(), m_pdgCode(0), m_isSelfConjugatedParticle(false)
46 setDescription(
"This module is used to employ kinematic constraints to determine the momentum of Klongs for two body B decays containing a K_L0 and something else. The module creates a list of K_L0 candidates whose K_L0 momentum is reconstructed by combining the reconstructed direction (from either the ECL or KLM) of the K_L0 and kinematic constraints of the initial state.");
47 setPropertyFlags(c_ParallelProcessingCertified);
50 addParam(
"decayString", m_decayString,
51 "Input DecayDescriptor string.");
52 addParam(
"cut", m_cutParameter,
"Selection criteria to be applied", std::string(
""));
53 addParam(
"maximumNumberOfCandidates", m_maximumNumberOfCandidates,
54 "Don't reconstruct channel if more candidates than given are produced.", -1);
55 addParam(
"decayMode", m_decayModeID,
"User-specified decay mode identifier (saved in 'decayModeID' extra-info for each Particle)",
57 addParam(
"writeOut", m_writeOut,
58 "If true, the output ParticleList will be saved by RootOutput. If false, it will be ignored when writing the file.",
false);
59 addParam(
"recoList", m_recoList,
60 "Suffix attached to the original K_L input list to identify the output list of the FindKlongMomentum module; this is the input for this module, if not defined it is set to '_reco' \n",
61 std::string(
"_reco"));
65 void KlongDecayReconstructorExpertModule::initialize()
67 m_particles.isRequired();
71 m_generator =
nullptr;
74 bool valid = m_decaydescriptor.init(m_decayString);
76 B2ERROR(
"Invalid input DecayString: " << m_decayString);
81 m_pdgCode = mother->getPDGCode();
82 m_listName = mother->getFullName();
84 m_antiListName = ParticleListName::antiParticleListName(m_listName);
85 m_isSelfConjugatedParticle = (m_listName == m_antiListName);
87 std::string newDecayString;
88 std::string kListName;
89 newDecayString = m_listName +
" -> ";
94 int nProducts = m_decaydescriptor.getNDaughters();
95 for (
int i = 0; i < nProducts; ++i) {
97 if (daughter->getPDGCode() != Const::Klong.getPDGCode()) {
99 newDecayString = newDecayString + daughter->getFullName() +
" ";
102 kListName = daughter->getFullName() + m_recoList;
108 B2FATAL(
"This module is meant to reconstruct decays with a K_L0 in the final state. There is no K_L0 in this decay!");
109 newDecayString = newDecayString + kListName;
111 m_generator = std::make_unique<ParticleGenerator>(newDecayString, m_cutParameter);
114 m_outputList.registerInDataStore(m_listName, flags);
115 if (!m_isSelfConjugatedParticle) {
116 m_outputAntiList.registerInDataStore(m_antiListName, flags);
119 m_cut = Variable::Cut::compile(m_cutParameter);
123 void KlongDecayReconstructorExpertModule::event()
125 m_outputList.create();
126 m_outputList->initialize(m_pdgCode, m_listName);
128 if (!m_isSelfConjugatedParticle) {
129 m_outputAntiList.create();
130 m_outputAntiList->initialize(-1 * m_pdgCode, m_antiListName);
132 m_outputList->bindAntiParticleList(*(m_outputAntiList));
137 int numberOfCandidates = 0;
138 while (m_generator->loadNext()) {
140 Particle particle = m_generator->getCurrentParticle();
142 bool is_physical =
true;
144 const std::vector<Particle*> daughters = particle.getDaughters();
146 if (daughters.size() < 2)
147 B2FATAL(
"Reconstructing particle as a daughter of a decay with less than 2 daughters!");
149 if (daughters.size() > 3)
150 B2FATAL(
"Higher multiplicity (>2) missing momentum decays not implemented yet!");
153 TLorentzVector pDaughters;
154 for (
auto daughter : daughters) {
155 if (daughter->getPDGCode() != Const::Klong.getPDGCode()) {
156 pDaughters += daughter->get4Vector();
157 e_check = daughter->getArrayIndex() + e_check * 100;
162 TLorentzVector klDaughters;
163 for (
auto daughter : daughters) {
164 if (daughter->getPDGCode() == Const::Klong.getPDGCode()) {
165 klDaughters += daughter->get4Vector();
166 if (e_check != daughter->getExtraInfo(
"permID")) {
171 double m_b = particle.getPDGMass();
173 TLorentzVector mom = pDaughters + klDaughters;
174 mom.SetE(TMath::Sqrt(mom.Vect().Mag2() + m_b * m_b));
175 if ((!isnan(mom.Vect().Mag())) && is_physical)
176 particle.set4Vector(mom);
177 if (isnan(mom.Vect().Mag()))
180 if (!m_cut->check(&particle))
186 numberOfCandidates++;
188 if (m_maximumNumberOfCandidates > 0 and numberOfCandidates > m_maximumNumberOfCandidates) {
189 m_outputList->clear();
193 Particle* newParticle = m_particles.appendNew(particle);
195 m_outputList->addParticle(newParticle);
196 newParticle->
addExtraInfo(
"decayModeID", m_decayModeID);
EStoreFlags
Flags describing behaviours of objects etc.
Represents a particle in the DecayDescriptor.
Class to store reconstructed particles.
void addExtraInfo(const std::string &name, float value)
Sets the user-defined data of given name to the given value.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
Type-safe access to single objects in the data store.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.