Belle II Software development
InclusiveBtagReconstructionModule.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <analysis/modules/InclusiveBtagReconstruction/InclusiveBtagReconstructionModule.h>
10
11#include <analysis/DecayDescriptor/ParticleListName.h>
12
13#include <unordered_set>
14#include <map>
15#include <vector>
16#include <Math/Vector4D.h>
17
18using namespace Belle2;
19
20//-----------------------------------------------------------------
21// Register the Module
22//-----------------------------------------------------------------
23REG_MODULE(InclusiveBtagReconstruction);
24
25//-----------------------------------------------------------------
26// Implementation
27//-----------------------------------------------------------------
28
30{
31 // Set module properties
32 setDescription("Inclusive Btag reconstruction");
34
35 // Parameter definitions
36 addParam("upsilonListName", m_upsilonListName, "Name of the ParticleList to be filled with Upsilon(4S) -> B:sig anti-B:tag",
37 std::string("Upsilon(4S)"));
38 addParam("bsigListName", m_bsigListName, "Name of the Bsig ParticleList", std::string(""));
39 addParam("btagListName", m_btagListName, "Name of the Btag ParticleList", std::string(""));
40 addParam("inputListsNames", m_inputListsNames, "List of names of the ParticleLists which are used to reconstruct Btag from");
41}
42
44
46{
47 m_bsigList.isRequired(m_bsigListName);
48
49 for (const std::string& inputListName : m_inputListsNames) {
50 StoreObjPtr<ParticleList> inputList(inputListName);
51 inputList.isRequired();
52 }
53
54 m_btagList.registerInDataStore(m_btagListName);
56 m_upsilonList.registerInDataStore(m_upsilonListName);
57}
58
60{
62 if (!valid)
63 B2ERROR("Invalid Bsig list name: " << m_bsigListName);
64
66 int pdgCode = mother->getPDGCode();
67
68 m_btagList.create();
69 m_btagList->initialize(-pdgCode, m_btagList.getName());
70
71 m_antiBtagList.create();
72 m_antiBtagList->initialize(pdgCode, m_antiBtagList.getName());
73 m_btagList->bindAntiParticleList(*m_antiBtagList);
74
75 m_upsilonList.create();
76 m_upsilonList->initialize(300553, m_upsilonList.getName());
77
78 const unsigned int n = m_bsigList->getListSize();
79 for (unsigned i = 0; i < n; i++) { // find Btag(s) for each Bsig
80 const Particle* bsig = m_bsigList->getParticle(i);
81 const std::vector<const Particle*>& bsigFinalStateDaughters = bsig->getFinalStateDaughters();
82 std::unordered_set<int> mdstSourcesOfBsigFinalStateDaughters;
83 std::map<int, std::vector<int>> btagDaughtersMap;
84
85 for (const Particle* daughter : bsigFinalStateDaughters) {
86 mdstSourcesOfBsigFinalStateDaughters.insert(daughter->getMdstSource());
87 }
88 auto mdstSourcesEnd = mdstSourcesOfBsigFinalStateDaughters.end();
89
90 // make a map of Btag daughters
91 for (const std::string& inputListName : m_inputListsNames) {
92 StoreObjPtr<ParticleList> inputList(inputListName);
93 const unsigned int m = inputList->getListSize();
94 for (unsigned j = 0; j < m; j++) {
95 const Particle* particle = inputList->getParticle(j);
96 const std::vector<const Particle*>& particleFinalStateDaughters = particle->getFinalStateDaughters();
97
98 // check if particle shares something with bsig...
99 for (const Particle* daughter : particleFinalStateDaughters) {
100 int mdstSource = daughter->getMdstSource();
101 if (mdstSourcesOfBsigFinalStateDaughters.find(mdstSource) != mdstSourcesEnd) {
102 break;
103 }
104 auto it = btagDaughtersMap.find(mdstSource);
105 if (it != btagDaughtersMap.end()) { // check for mdstSource overlaps
106 it->second.push_back(particle->getArrayIndex());
107 } else {
108 btagDaughtersMap[mdstSource] = {particle->getArrayIndex()};
109 }
110 }
111 }
112 }
113
114 // combine map entries to form Btag candidates
115 Map2Vector map2vector;
116 std::vector<std::vector<int>> btagCandidates;
117 map2vector.convert(btagDaughtersMap, btagCandidates);
118
119 for (std::vector<int> daughterIndices : btagCandidates) {
120 std::map<int, size_t> nonFinalStateIndicesCount;
121 ROOT::Math::PxPyPzEVector momentum;
122 for (int index : daughterIndices) {
123 // check if there are non-final-state particles. If yes, the momentum should be added just once.
124 if ((m_particles[index]->getFinalStateDaughters()).size() > 1) {
125 auto it = nonFinalStateIndicesCount.find(index);
126 if (it != nonFinalStateIndicesCount.end()) {
127 nonFinalStateIndicesCount[index]++;
128 continue;
129 } else {
130 nonFinalStateIndicesCount[index] = 1;
131 }
132 }
133 momentum += m_particles[index]->get4Vector();
134 }
135 // check the number of the daughters to make sure that the not-final-state particles are not mixed with the other particles that come from the same mdstSource
136 bool rightDaughtersCount = true;
137 for (auto& it : nonFinalStateIndicesCount) {
138 if (it.second != (m_particles[(it.first)]->getFinalStateDaughters()).size()) {
139 rightDaughtersCount = false;
140 break;
141 }
142 }
143 if (rightDaughtersCount == false) {
144 continue;
145 }
146
147 //remove repeated index in daughterIndices
148 std::vector<int>::iterator it;
149 std::sort(daughterIndices.begin(), daughterIndices.end());
150 it = std::unique(daughterIndices.begin(), daughterIndices.end());
151 daughterIndices.resize(std::distance(daughterIndices.begin(), it));
152
153 Particle btagCandidate(momentum, -1 * bsig->getPDGCode(), bsig->getFlavorType(), daughterIndices, bsig->getArrayPointer());
154 Particle* btag = m_particles.appendNew(btagCandidate);
155 m_btagList->addParticle(btag);
156
157 Particle upsilon(momentum + bsig->get4Vector(), 300553, Particle::c_Unflavored, { bsig->getArrayIndex(), btag->getArrayIndex() },
158 bsig->getArrayPointer());
159 m_upsilonList->addParticle(m_particles.appendNew(upsilon));
160 }
161 }
162}
163
164void Map2Vector::convert(std::map<int, std::vector<int>>& input, std::vector<std::vector<int>>& output)
165{
166 makeEntries(input.begin(), input.end(), 0, output);
167}
168
169void Map2Vector::makeEntries(std::map<int, std::vector<int>>::iterator positionOnTheMap,
170 const std::map<int, std::vector<int>>::const_iterator& end,
171 unsigned i, std::vector<std::vector<int>>& output)
172{
173 if (positionOnTheMap == end) {
174 output.push_back(m_combination);
175 } else {
176 std::vector<int>& v = positionOnTheMap->second;
177 ++positionOnTheMap;
178 for (int k : v) {
179 if (i < m_combination.size()) m_combination[i] = k;
180 else m_combination.push_back(k);
181 makeEntries(positionOnTheMap, end, i + 1, output);
182 }
183 }
184};
Represents a particle in the DecayDescriptor.
int getPDGCode() const
Return PDG code.
bool init(const std::string &str)
Initialise the DecayDescriptor from given string.
const DecayDescriptorParticle * getMother() const
return mother.
virtual void initialize() override
initialize the module (setup the data store)
StoreObjPtr< ParticleList > m_btagList
particle list of tag B
StoreArray< Particle > m_particles
StoreArray of Particles.
virtual ~InclusiveBtagReconstructionModule()
Destructor.
StoreObjPtr< ParticleList > m_upsilonList
particle list of Y(4S)
std::vector< std::string > m_inputListsNames
Names of the ParticleLists to be used to reconstruct Btag.
StoreObjPtr< ParticleList > m_bsigList
particle list of signal B
DecayDescriptor m_decaydescriptor
Decay descriptor for parsing the user specified DecayString.
std::string m_upsilonListName
Name of the ParticleList to be filled with Upsilon(4S) -> B:sig anti-B:tag
std::string m_bsigListName
Name of the Bsig ParticleList.
std::string m_btagListName
Name of the Btag ParticleList.
StoreObjPtr< ParticleList > m_antiBtagList
particle list of tag anti-B
Helper class to make a vector of all possible combinations of int numbers contained in the input vect...
void convert(std::map< int, std::vector< int > > &input, std::vector< std::vector< int > > &output)
Do the conversion using makeEntries().
void makeEntries(std::map< int, std::vector< int > >::iterator positionOnTheMap, const std::map< int, std::vector< int > >::const_iterator &end, unsigned i, std::vector< std::vector< int > > &output)
Recursively iterates over a map until the end is reached, then the output is ready.
std::vector< int > m_combination
Vector containing current combination of numbers (e.g.
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
Class to store reconstructed particles.
Definition: Particle.h:76
std::vector< const Belle2::Particle * > getFinalStateDaughters() const
Returns a vector of pointers to Final State daughter particles.
Definition: Particle.cc:680
EFlavorType getFlavorType() const
Returns flavor type of the decay (for FS particles: flavor type of particle)
Definition: Particle.h:480
int getPDGCode(void) const
Returns PDG code.
Definition: Particle.h:465
TClonesArray * getArrayPointer() const
Returns the pointer to the store array which holds the daughter particles.
Definition: Particle.h:981
ROOT::Math::PxPyPzEVector get4Vector() const
Returns Lorentz vector.
Definition: Particle.h:567
@ c_Unflavored
Is its own antiparticle or we don't know whether it is a particle/antiparticle.
Definition: Particle.h:97
T * appendNew()
Construct a new T object at the end of the array.
Definition: StoreArray.h:246
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:95
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:649
std::string antiParticleListName(const std::string &listName)
Returns name of anti-particle-list corresponding to listName.
Abstract base class for different kinds of events.