Belle II Software development
EventShapeCalculatorModule.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/utility/PCmsLabTransform.h>
10
11#include <analysis/modules/EventShapeCalculator/EventShapeCalculatorModule.h>
12
13#include <analysis/dataobjects/ParticleList.h>
14#include <analysis/dataobjects/Particle.h>
15#include <mdst/dataobjects/MCParticle.h>
16
17#include <framework/logging/Logger.h>
18
19#include <analysis/ContinuumSuppression/Thrust.h>
20#include <analysis/ContinuumSuppression/HarmonicMoments.h>
21#include <analysis/ContinuumSuppression/CleoCones.h>
22#include <analysis/ContinuumSuppression/FoxWolfram.h>
23#include <analysis/ContinuumSuppression/SphericityEigenvalues.h>
24
25#include <Math/Vector4D.h>
26
27
28using namespace std;
29using namespace Belle2;
30
31//-----------------------------------------------------------------
32// Register the Module
33//-----------------------------------------------------------------
34REG_MODULE(EventShapeCalculator);
35
36//-----------------------------------------------------------------
37// Implementation
38//-----------------------------------------------------------------
39
41{
42 // Set module properties
43 setDescription("Module to compute event shape attributes starting from particlelists. The core algorithms are not implemented in this module, but in dedicated basf2 classes.");
45 // Parameter definitions
46 addParam("particleListNames", m_particleListNames, "List of the ParticleLists to be used for the calculation of the EventShapes.",
47 vector<string>());
48 addParam("enableThrust", m_enableThrust, "Enables the calculation of thrust-related quantities.", true);
49 addParam("enableCollisionAxis", m_enableCollisionAxis, "Enables the calculation of the quantities related to the collision axis.",
50 true);
51 addParam("enableFoxWolfram", m_enableFW, "Enables the calculation of the Fox-Wolfram moments.", true);
52 addParam("enableHarmonicMoments", m_enableHarmonicMoments, "Enables the calculation of the Harmonic moments.", true);
53 addParam("enableJets", m_enableJets, "Enables the calculation of jet-related quantities.", true);
54 addParam("enableSphericity", m_enableSphericity, "Enables the calculation of the sphericity-related quantities.", true);
55 addParam("enableCleoCones", m_enableCleoCones, "Enables the calculation of the CLEO cones.", true);
56 addParam("enableAllMoments", m_enableAllMoments, "Enables the calculation of FW and harmonic moments from 5 to 8", false);
57 addParam("checkForDuplicates", m_checkForDuplicates,
58 "Enables the check for duplicates in the input list. If a duplicate entry is found, the first one is kept.", false);
59}
60
61
63{
64 m_eventShapeContainer.registerInDataStore();
65 if (m_enableJets and not m_enableThrust) {
66 B2WARNING("The jet-related quantities can only be calculated if the thrust calculation is activated as well.");
67 m_enableThrust = true;
68 }
70 B2WARNING("The CLEO cones can only be calculated if either the thrust or the collision axis calculation are activated as well.");
72 B2WARNING("The harmonic moments can only be calculated if either the thrust or the collision axis calculation are activated as well.");
73}
74
75
77{
78
80 double sqrtS = T.getCMSEnergy();
81
83
84 const int nPart = parseParticleLists(m_particleListNames);
85 if (nPart == 0) return;
86
87 // --------------------
88 // Calculates the FW moments
89 // --------------------
90 if (m_enableFW) {
94 for (short i = 0; i < 9; i++) {
95 m_eventShapeContainer->setFWMoment(i, fw.getH(i));
96 }
97 } else {
99 for (short i = 0; i < 5; i++) {
100 m_eventShapeContainer->setFWMoment(i, fw.getH(i));
101 }
102 }
103 }
104
105 // --------------------
106 // Calculates the sphericity quantities
107 // --------------------
108 if (m_enableSphericity) {
111 if (Sph.getEigenvalue(0) < Sph.getEigenvalue(1) || Sph.getEigenvalue(0) < Sph.getEigenvalue(2)
112 || Sph.getEigenvalue(1) < Sph.getEigenvalue(2))
113 B2WARNING("Eigenvalues not ordered!!!!!!!!!!");
114
115 for (short i = 0; i < 3; i++) {
116 m_eventShapeContainer->setSphericityEigenvalue(i, Sph.getEigenvalue(i));
117 m_eventShapeContainer->setSphericityEigenvector(i, Sph.getEigenvector(i));
118 }
119 }
120
121
122 // --------------------
123 // Calculates thrust and thrust-related quantities
124 // --------------------
125 if (m_enableThrust) {
126 ROOT::Math::XYZVector thrust = Thrust::calculateThrust(m_p4List);
127 float thrustVal = thrust.R();
128 thrust = thrust.Unit();
129 m_eventShapeContainer->setThrustAxis(thrust);
130 m_eventShapeContainer->setThrust(thrustVal);
131
132 // --- If required, calculates the HarmonicMoments ---
134 HarmonicMoments MM(m_p4List, thrust);
135 if (m_enableAllMoments) {
137 for (short i = 0; i < 9; i++) {
138 auto moment = MM.getMoment(i, sqrtS);
139 m_eventShapeContainer->setHarmonicMomentThrust(i, moment);
140 }
141 } else {
143 for (short i = 0; i < 5; i++) {
144 auto moment = MM.getMoment(i, sqrtS);
145 m_eventShapeContainer->setHarmonicMomentThrust(i, moment);
146 }
147 }
148 }
149
150 // --- If required, calculates the cleo cones w/ respect to the thrust axis ---
151 if (m_enableCleoCones) {
152 // Cleo cone class constructor. Unfortunately this class is designed
153 // to use the ROE, so the constructor takes two std::vector of momenta ("all" and "ROE"),
154 // then a vector to be used as axis, and finally two flags that determine if the cleo cones
155 // are calculated using the ROE, all the particles or both. Here we use the m_p4List as dummy
156 // list of the ROE momenta, that is however not used at all since the calculate only the
157 // cones with all the particles. This whole class would need some heavy restructuring...
158 CleoCones cleoCones(m_p4List, m_p4List, thrust, true, false);
159 std::vector<float> cones;
160 cones = cleoCones.cleo_cone_with_all();
161 for (short i = 0; i < 10; i++) {
162 m_eventShapeContainer->setCleoConeThrust(i, cones[i]);
163 }
164 } // end of if m_enableCleoCones
165
166
167 // --- If required, calculates the jet 4-momentum using the thrust axis ---
168 if (m_enableJets) {
169 ROOT::Math::PxPyPzEVector p4FWD;
170 ROOT::Math::PxPyPzEVector p4BKW;
171 for (const auto& p4 : m_p4List) {
172 if (p4.Vect().Dot(thrust) > 0)
173 p4FWD += p4;
174 else
175 p4BKW += p4;
176 }
177 m_eventShapeContainer->setForwardHemisphere4Momentum(p4FWD);
178 m_eventShapeContainer->setBackwardHemisphere4Momentum(p4BKW);
179 } // end of if m_enableJets
180 }// end of if m_enableThrust
181
182
183
184 // --------------------
185 // Calculates the collision axis quantities
186 // --------------------
188
189 ROOT::Math::XYZVector collisionAxis(0., 0., 1.);
190
191 // --- If required, calculates the cleo cones w/ respect to the collision axis ---
192 if (m_enableCleoCones) {
193 CleoCones cleoCones(m_p4List, m_p4List, collisionAxis, true, false);
194 std::vector<float> cones;
195 cones = cleoCones.cleo_cone_with_all();
196 for (short i = 0; i < 10; i++) {
197 m_eventShapeContainer->setCleoConeCollision(i, cones[i]);
198 }
199 }
200
201 // --- If required, calculates the HarmonicMoments ---
203 HarmonicMoments MM(m_p4List, collisionAxis);
204 if (m_enableAllMoments) {
206 for (short i = 0; i < 9; i++) {
207 auto moment = MM.getMoment(i, sqrtS);
208 m_eventShapeContainer->setHarmonicMomentCollision(i, moment);
209 }
210 } else {
212 for (short i = 0; i < 5; i++) {
213 auto moment = MM.getMoment(i, sqrtS);
214 m_eventShapeContainer->setHarmonicMomentCollision(i, moment);
215 }
216 }
217 } // end of m_enableHarmonicMoments
218 } // end of m_enableCollisionAxis
219} // end of event()
220
221
222
223int EventShapeCalculatorModule::parseParticleLists(vector<string> particleListNames)
224{
226 m_p4List.clear();
227
228 unsigned int nParticlesInAllLists = 0;
229 unsigned short nParticleLists = particleListNames.size();
230 if (nParticleLists == 0)
231 B2WARNING("No particle lists found. EventShape calculation not performed.");
232
233 // This vector temporarily stores the mdstSource of particle objects
234 // that have been processed so far (not only the momenta)
235 // in order to check for duplicates before pushing the 3- and 4- vectors
236 // in the corresponding lists
237 std::vector<int> usedMdstSources;
238
239 // Loops over the number of particle lists
240 for (unsigned short iList = 0; iList < nParticleLists; iList++) {
241 string particleListName = particleListNames[iList];
242 StoreObjPtr<ParticleList> particleList(particleListName);
243
244 // Loops over the number of particles in the list
245 nParticlesInAllLists += particleList->getListSize();
246
247 for (unsigned int iPart = 0; iPart < particleList->getListSize(); iPart++) {
248 const Particle* part = particleList->getParticle(iPart);
249 const MCParticle* mcParticle = part->getMCParticle();
250 if (mcParticle and mcParticle->isInitial()) continue;
251
253
254 std::vector<const Belle2::Particle*> finalStateDaughters = part->getFinalStateDaughters();
255
256 for (const auto fsp : finalStateDaughters) {
257 int mdstSource = fsp->getMdstSource();
258 auto result = std::find(usedMdstSources.begin(), usedMdstSources.end(), mdstSource);
259 if (result == usedMdstSources.end()) {
260 usedMdstSources.push_back(mdstSource);
261 ROOT::Math::PxPyPzEVector p4CMS = T.rotateLabToCms() * fsp->get4Vector();
262 m_p4List.push_back(p4CMS);
263 B2DEBUG(19, "non-duplicate has pdgCode " << fsp->getPDGCode() << " and mdstSource " << mdstSource);
264 } else {
265 B2DEBUG(19, "duplicate has pdgCode " << fsp->getPDGCode() << " and mdstSource " << mdstSource);
266 B2DEBUG(19, "Duplicate particle found. The new one won't be used for the calculation of the event shape variables. "
267 "Please, double check your input lists and try to make them mutually exclusive.");
268 }
269 }
270 } else {
271 ROOT::Math::PxPyPzEVector p4CMS = T.rotateLabToCms() * part->get4Vector();
272 m_p4List.push_back(p4CMS);
273 }
274 }
275 }
276
277 return nParticlesInAllLists;
278}
279
Class to calculate the Cleo clone variables.
Definition: CleoCones.h:23
int parseParticleLists(std::vector< std::string >)
Turns the ParticleLists provided as inputs into std::vector of PxPyPzEVector, after boosting them int...
bool m_enableCollisionAxis
Enables the calculation of the quantities related to the collision axis.
virtual void initialize() override
Define the physical parameters.
virtual void event() override
Main method, called for each events.
bool m_enableHarmonicMoments
Enables the calculation of the Harmonic moments.
std::vector< std::string > m_particleListNames
Names of the ParticleLists (inputs).
bool m_enableAllMoments
Enables the calculation of the FW moments from 5 to 8.
bool m_enableThrust
Enables the calculation of thrust-related quantities.
bool m_enableCleoCones
Enables the calculation of the Cleo Cones.
bool m_enableJets
Enables the calculation of the Jet-related quantities.
std::vector< ROOT::Math::PxPyPzEVector > m_p4List
vector containing all the 4-momenta of the particles contained in the input lists.
bool m_enableFW
Enables the calculation of the FW moments.
bool m_checkForDuplicates
Enables the check for the duplicates in the input list.
EventShapeCalculatorModule()
Constructor: Sets the description, the properties and the parameters of the module.
StoreObjPtr< EventShapeContainer > m_eventShapeContainer
event shape container object pointer
bool m_enableSphericity
Enables the calculation of the Sphericity matrix.
Class to calculate the Fox-Wolfram moments up to order 8.
Definition: FoxWolfram.h:28
void calculateAllMoments()
Method to perform the calculation of the moments up to order 8.
Definition: FoxWolfram.cc:58
void calculateBasicMoments()
Method to perform the calculation of the moments up to order 4, which are the most relevant ones.
Definition: FoxWolfram.cc:14
double getH(int i) const
Returns the i-th moment.
Definition: FoxWolfram.h:83
Class to calculate the Harmonic moments up to order 8 with respect to a given axis.
void calculateAllMoments()
Calculates the moments up to order 8.
double getMoment(short i, double sqrts) const
Returns the moment of order i.
void calculateBasicMoments()
Calculates the moments up to order 4.
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:32
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 hold Lorentz transformations from/to CMS and boost vector.
double getCMSEnergy() const
Returns CMS energy of e+e- (aka.
const ROOT::Math::LorentzRotation rotateLabToCms() const
Returns Lorentz transformation from Lab to CMS.
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
const MCParticle * getMCParticle() const
Returns the pointer to the MCParticle object that was used to create this Particle (ParticleType == c...
Definition: Particle.cc:1027
ROOT::Math::PxPyPzEVector get4Vector() const
Returns Lorentz vector.
Definition: Particle.h:567
Class to calculate the Sphericity tensor eigenvalues and eigenvectors starting from an array of 3-mom...
void calculateEigenvalues()
Calculates eigenvalues and eigenvectors.
ROOT::Math::XYZVector getEigenvector(short i) const
Returns the i-th Eigenvector.
double getEigenvalue(short i) const
Returns the i-th Eigenvalue.
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:95
static ROOT::Math::XYZVector calculateThrust(const std::vector< ROOT::Math::PxPyPzEVector > &momenta)
calculates the thrust axis
Definition: Thrust.cc:71
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
bool isInitial() const
Check if particle is an initial particle such as ISR.
Definition: MCParticle.h:580
Abstract base class for different kinds of events.
STL namespace.