10 #include <analysis/modules/ParticleCombiner/ParticleCombinerModule.h>
13 #include <framework/logging/Logger.h>
16 #include <analysis/DecayDescriptor/DecayDescriptorParticle.h>
19 #include <analysis/DecayDescriptor/ParticleListName.h>
20 #include <analysis/utility/EvtPDLUtil.h>
21 #include <analysis/utility/PCmsLabTransform.h>
48 setDescription(
"Makes particle combinations");
49 setPropertyFlags(c_ParallelProcessingCertified);
52 addParam(
"decayString", m_decayString,
53 "Input DecayDescriptor string (see :ref:`DecayString`).");
54 addParam(
"cut", m_cutParameter,
"Selection criteria to be applied", std::string(
""));
55 addParam(
"maximumNumberOfCandidates", m_maximumNumberOfCandidates,
56 "Max. number of candidates reconstructed. By default, if the limit is reached no candidates will be produced.\n"
57 "This behaviour can be changed by \'ignoreIfTooManyCandidates\' flag.", 10000);
59 addParam(
"ignoreIfTooManyCandidates", m_ignoreIfTooManyCandidates,
60 "Don't reconstruct channel if more candidates than given by \'maximumNumberOfCandidates\' are produced.",
true);
62 addParam(
"decayMode", m_decayModeID,
"User-specified decay mode identifier (saved in 'decayModeID' extra-info for each Particle)",
64 addParam(
"writeOut", m_writeOut,
65 "If true, the output ParticleList will be saved by RootOutput. If false, it will be ignored when writing the file.",
false);
66 addParam(
"recoilParticleType", m_recoilParticleType,
67 "If not equal 0, the mother Particle is reconstructed in the recoil against the daughter particles.\n"
68 "In the case of the following decay chain M -> D1 D2 ... Dn and\n\n"
70 " a) recoilParticleType = 1: \n\n"
71 " - the mother momentum is given by: p(M) = p(e+e-) - p(D1) - p(D2) - ... - p(DN)\n"
72 " - D1, D2, ..., DN are attached as daughters of M\n\n"
73 " b) recoilParticleType = 2: \n\n"
74 " - the mother momentum is given by: p(M) = p(D1) - p(D2) - ... - p(DN)\n"
75 " - D1, D2, ..., DN are attached as daughters of M\n\n" , 0);
76 addParam(
"chargeConjugation", m_chargeConjugation,
77 "If true, the charge-conjugated mode will be reconstructed as well",
true);
78 addParam(
"allowChargeViolation", m_allowChargeViolation,
79 "If true the decay string does not have to conserve electric charge",
false);
83 m_isSelfConjugatedParticle =
false;
84 m_generator =
nullptr;
87 void ParticleCombinerModule::initialize()
94 bool valid = m_decaydescriptor.init(m_decayString);
96 B2ERROR(
"Invalid input DecayString: " << m_decayString);
101 m_pdgCode = mother->getPDGCode();
102 m_listName = mother->getFullName();
104 m_antiListName = ParticleListName::antiParticleListName(m_listName);
105 m_isSelfConjugatedParticle = (m_listName == m_antiListName);
108 int nProducts = m_decaydescriptor.getNDaughters();
109 int daughtersNetCharge = 0;
110 for (
int i = 0; i < nProducts; ++i) {
112 m_decaydescriptor.getDaughter(i)->getMother();
114 int daughterPDGCode = daughter->getPDGCode();
115 if (m_recoilParticleType == 2 && i == 0) {
116 daughtersNetCharge -= EvtPDLUtil::charge(daughterPDGCode);
118 daughtersNetCharge += EvtPDLUtil::charge(daughterPDGCode);
122 if (daughtersNetCharge != EvtPDLUtil::charge(m_pdgCode)) {
123 if (!m_allowChargeViolation) {
124 B2FATAL(
"Your decay string " << m_decayString <<
" violates electric charge conservation!\n"
125 "If you want to allow this you can set the argument 'allowChargeViolation' to True. Something like:\n"
126 "modularAnalysis.reconstructDecay(" << m_decayString <<
", your_cuts, allowChargeViolation=True, path=mypath)");
128 B2WARNING(
"Your decay string " << m_decayString <<
" violates electric charge conservation!\n"
129 "Processing is continued assuming that you allowed this deliberately, e.g. for systematic studies etc.");
132 m_generator = std::make_unique<ParticleGenerator>(m_decayString, m_cutParameter);
135 m_outputList.registerInDataStore(m_listName, flags);
136 if (!m_isSelfConjugatedParticle && m_chargeConjugation) {
137 m_outputAntiList.registerInDataStore(m_antiListName, flags);
140 if (m_recoilParticleType != 0 && m_recoilParticleType != 1 && m_recoilParticleType != 2)
141 B2FATAL(
"Invalid recoil particle type = " << m_recoilParticleType <<
142 "! Valid values are 0 (not a recoil), 1 (recoiling against e+e- and daughters), 2 (daughter of a recoil)");
145 void ParticleCombinerModule::event()
147 m_outputList.create();
148 m_outputList->initialize(m_pdgCode, m_listName);
150 if (!m_isSelfConjugatedParticle && m_chargeConjugation) {
151 m_outputAntiList.create();
152 m_outputAntiList->initialize(-1 * m_pdgCode, m_antiListName);
154 m_outputList->bindAntiParticleList(*(m_outputAntiList));
159 int numberOfCandidates = 0;
160 while (m_generator->loadNext(m_chargeConjugation)) {
162 Particle&& particle = m_generator->getCurrentParticle();
173 if (m_recoilParticleType == 1) {
176 particle.set4Vector(recoilMomentum);
177 }
else if (m_recoilParticleType == 2) {
178 const std::vector<Particle*> daughters = particle.getDaughters();
180 if (daughters.size() < 2)
181 B2FATAL(
"Reconstructing particle as a daughter of a recoil with less then 2 daughters!");
183 TLorentzVector pDaughters;
184 for (
unsigned i = 1; i < daughters.size(); i++) {
185 pDaughters += daughters[i]->get4Vector();
188 TLorentzVector mom = daughters[0]->get4Vector() - pDaughters;
189 particle.set4Vector(mom);
192 numberOfCandidates++;
194 if (m_maximumNumberOfCandidates > 0 and numberOfCandidates > m_maximumNumberOfCandidates) {
195 if (m_ignoreIfTooManyCandidates) {
196 B2WARNING(
"Maximum number of " << m_maximumNumberOfCandidates <<
" candidates reached, skipping event");
197 m_outputList->clear();
199 B2WARNING(
"Maximum number of " << m_maximumNumberOfCandidates <<
" candidates reached. Ignoring others");
204 Particle* newParticle = m_particles.appendNew(particle);
206 m_outputList->addParticle(newParticle);
209 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.