Belle II Software  release-05-02-19
EventShapeCalculatorModule.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2018 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Umberto Tamponi (tamponi@to.infn.it) *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 #include <analysis/utility/PCmsLabTransform.h>
12 
13 #include <analysis/modules/EventShapeCalculator/EventShapeCalculatorModule.h>
14 
15 #include <analysis/dataobjects/ParticleList.h>
16 #include <analysis/dataobjects/Particle.h>
17 #include <analysis/dataobjects/EventShapeContainer.h>
18 
19 #include <framework/datastore/StoreObjPtr.h>
20 
21 #include <framework/logging/Logger.h>
22 
23 #include <iostream>
24 
25 #include <analysis/ContinuumSuppression/Thrust.h>
26 #include <analysis/ContinuumSuppression/HarmonicMoments.h>
27 #include <analysis/ContinuumSuppression/CleoCones.h>
28 #include <analysis/ContinuumSuppression/FoxWolfram.h>
29 #include <analysis/ContinuumSuppression/SphericityEigenvalues.h>
30 
31 #include <TVector3.h>
32 #include <TLorentzVector.h>
33 
34 
35 using namespace std;
36 using namespace Belle2;
37 
38 //-----------------------------------------------------------------
39 // Register the Module
40 //-----------------------------------------------------------------
41 REG_MODULE(EventShapeCalculator)
42 
43 //-----------------------------------------------------------------
44 // Implementation
45 //-----------------------------------------------------------------
46 
48 {
49  // Set module properties
50  setDescription("Module to compute event shape attributes starting from particlelists. The core algorithms are not implemented in this module, but in dedicated basf2 classes.");
51  setPropertyFlags(c_ParallelProcessingCertified);
52  // Parameter definitions
53  addParam("particleListNames", m_particleListNames, "List of the ParticleLists to be used for the calculation of the EventShapes.",
54  vector<string>());
55  addParam("enableThrust", m_enableThrust, "Enables the calculation of thust-related quantities.", true);
56  addParam("enableCollisionAxis", m_enableCollisionAxis, "Enables the calculation of the quantities related to the collision axis.",
57  true);
58  addParam("enableFoxWolfram", m_enableFW, "Enables the calculation of the Fox-Wolfram moments.", true);
59  addParam("enableHarmonicMoments", m_enableHarmonicMoments, "Enables the calculation of the Harmonic moments.", true);
60  addParam("enableJets", m_enableJets, "Enables the calculation of jet-related quantities.", true);
61  addParam("enableSphericity", m_enableSphericity, "Enables the calculation of the sphericity-related quantities.", true);
62  addParam("enableCleoCones", m_enableCleoCones, "Enables the calculation of the CLEO cones.", true);
63  addParam("enableAllMoments", m_enableAllMoments, "Enables the calculation of FW and harmonic moments from 5 to 8", false);
64  addParam("checkForDuplicates", m_checkForDuplicates,
65  "Enables the check for duplicates in the input list. If a duplicate entry is found, the first one is kept.", false);
66 }
67 
68 
69 void EventShapeCalculatorModule::initialize()
70 {
71  StoreObjPtr<EventShapeContainer> evtShapeContainer;
72  evtShapeContainer.registerInDataStore();
73 }
74 
75 
76 void EventShapeCalculatorModule::event()
77 {
78 
80  double sqrtS = T.getCMSEnergy();
81 
82  StoreObjPtr<EventShapeContainer> eventShapeContainer;
83  if (!eventShapeContainer) eventShapeContainer.create();
84 
85  parseParticleLists(m_particleListNames);
86 
87 
88  // --------------------
89  // Calculates the FW moments
90  // --------------------
91  if (m_enableFW) {
92  FoxWolfram fw(m_p3List);
93  if (m_enableAllMoments) {
95  for (short i = 0; i < 9; i++) {
96  eventShapeContainer->setFWMoment(i, fw.getH(i));
97  }
98  } else {
100  for (short i = 0; i < 5; i++) {
101  eventShapeContainer->setFWMoment(i, fw.getH(i));
102  }
103  }
104  }
105 
106  // --------------------
107  // Calculates the sphericity quantities
108  // --------------------
109  if (m_enableSphericity) {
110  SphericityEigenvalues Sph(m_p3List);
111  Sph.calculateEigenvalues();
112  if (Sph.getEigenvalue(0) < Sph.getEigenvalue(1) || Sph.getEigenvalue(0) < Sph.getEigenvalue(2)
113  || Sph.getEigenvalue(1) < Sph.getEigenvalue(2))
114  B2WARNING("Eigenvalues not ordered!!!!!!!!!!");
115 
116  for (short i = 0; i < 3; i++) {
117  eventShapeContainer->setSphericityEigenvalue(i, Sph.getEigenvalue(i));
118  eventShapeContainer->setSphericityEigenvector(i, Sph.getEigenvector(i));
119  }
120  }
121 
122 
123  // --------------------
124  // Calculates thrust and thrust-related quantities
125  // --------------------
126  if (m_enableThrust) {
127  TVector3 thrust = Thrust::calculateThrust(m_p3List);
128  float thrustVal = thrust.Mag();
129  thrust = (1. / thrustVal) * thrust;
130  eventShapeContainer->setThrustAxis(thrust);
131  eventShapeContainer->setThrust(thrustVal);
132 
133  // --- If required, calculates the HarmonicMoments ---
134  if (m_enableHarmonicMoments) {
135  HarmonicMoments MM(m_p3List, thrust);
136  if (m_enableAllMoments) {
137  MM.calculateAllMoments();
138  for (short i = 0; i < 9; i++) {
139  auto moment = MM.getMoment(i, sqrtS);
140  eventShapeContainer->setHarmonicMomentThrust(i, moment);
141  }
142  } else {
143  MM.calculateBasicMoments();
144  for (short i = 0; i < 5; i++) {
145  auto moment = MM.getMoment(i, sqrtS);
146  eventShapeContainer->setHarmonicMomentThrust(i, moment);
147  }
148  }
149  }
150 
151  // --- If required, calculates the cleo cones w/ respect to the thrust axis ---
152  if (m_enableCleoCones) {
153  // Cleo cone class constructor. Unfortunately this class is designed
154  // to use the ROE, so the constructor takes two std::vector of momenta ("all" and "ROE"),
155  // then a vector to be used as axis, and finally two flags that determine if the cleo cones
156  // are calculated using the ROE, all the particles or both. Here we use the m_p3List as dummy
157  // list of the ROE momenta, that is however not used at all since the calculate only the
158  // cones with all the particles. This whole class would need some heavy restructuring...
159  CleoCones cleoCones(m_p3List, m_p3List, thrust, true, false);
160  std::vector<float> cones;
161  cones = cleoCones.cleo_cone_with_all();
162  for (short i = 0; i < 10; i++) {
163  eventShapeContainer->setCleoConeThrust(i, cones[i]);
164  }
165  } // end of if m_enableCleoCones
166 
167 
168  // --- If required, calculates the jet 4-momentum using the thrust axis ---
169  if (m_enableJets) {
170  TLorentzVector p4FWD(0., 0., 0., 0.);
171  TLorentzVector p4BKW(0., 0., 0., 0.);
172  for (const auto& p4 : m_p4List) {
173  if (p4.Vect().Dot(thrust) > 0)
174  p4FWD += p4;
175  else
176  p4BKW += p4;
177  }
178  eventShapeContainer->setForwardHemisphere4Momentum(p4FWD);
179  eventShapeContainer->setBackwardHemisphere4Momentum(p4BKW);
180  } // end of if m_enableJets
181  }// end of if m_enableThrust
182 
183 
184 
185  // --------------------
186  // Calculates the collision axis quantities
187  // --------------------
188  if (m_enableCollisionAxis) {
189 
190  TVector3 collisionAxis(0., 0., 1.);
191 
192  // --- If required, calculates the cleo cones w/ respect to the collision axis ---
193  if (m_enableCleoCones) {
194  CleoCones cleoCones(m_p3List, m_p3List, collisionAxis, true, false);
195  std::vector<float> cones;
196  cones = cleoCones.cleo_cone_with_all();
197  for (short i = 0; i < 10; i++) {
198  eventShapeContainer->setCleoConeCollision(i, cones[i]);
199  }
200  }
201 
202  // --- If required, calculates the HarmonicMoments ---
203  if (m_enableHarmonicMoments) {
204  HarmonicMoments MM(m_p3List, collisionAxis);
205  if (m_enableAllMoments) {
206  MM.calculateAllMoments();
207  for (short i = 0; i < 9; i++) {
208  auto moment = MM.getMoment(i, sqrtS);
209  eventShapeContainer->setHarmonicMomentCollision(i, moment);
210  }
211  } else {
212  MM.calculateBasicMoments();
213  for (short i = 0; i < 5; i++) {
214  auto moment = MM.getMoment(i, sqrtS);
215  eventShapeContainer->setHarmonicMomentCollision(i, moment);
216  }
217  }
218  } // end of m_enableHarmonicMoments
219  } // end of m_enableCollisionAxis
220 } // end of event()
221 
222 
223 
224 int EventShapeCalculatorModule::parseParticleLists(vector<string> particleListNames)
225 {
226  int nPart = 0; // number of particles
227 
229  m_p4List.clear();
230  m_p3List.clear();
231 
232  unsigned short nParticleLists = particleListNames.size();
233  if (nParticleLists == 0)
234  B2ERROR("No particle lists found. EventShape calculation not performed.");
235 
236  // This vector temporary stores the particle objects
237  // that have been processed so far (not only the momenta)
238  // in order to check for duplicates before pushing the 3- and 4- vectors
239  // in the corresponding lists
240  std::vector<Particle> tmpParticles;
241 
242  // Loops over the number of particle lists
243  for (unsigned short iList = 0; iList < nParticleLists; iList++) {
244  string particleListName = particleListNames[iList];
245  StoreObjPtr<ParticleList> particleList(particleListName);
246 
247  // Loops over the number of particles in the list
248  for (unsigned int iPart = 0; iPart < particleList->getListSize(); iPart++) {
249  const Particle* part = particleList->getParticle(iPart);
250 
251  // Flag to check for duplicates across the lists.
252  // It can be true only if m_checkForDuplicates is enabled
253  bool isDuplicate = false;
254 
255  if (m_checkForDuplicates) {
256  // loops over all the particles loaded so far
257  for (const auto& testPart : tmpParticles) {
258  if (testPart.isCopyOf(part)) {
259  B2WARNING("Duplicate particle found. The new one won't be used for the calculation of the event shape variables. Please, double check your input lists and try to make them mutually exclusive.");
260  isDuplicate = true;
261  break;
262  }
263  }
264  tmpParticles.push_back(*part);
265  }
266 
267  if (!isDuplicate) {
268  TLorentzVector p4CMS = T.rotateLabToCms() * part->get4Vector();
269  // it need to fill an std::vector of TVector3 to use the current FW rutines.
270  // It will hopefully change in release 3
271  m_p4List.push_back(p4CMS);
272  m_p3List.push_back(p4CMS.Vect());
273  }
274  }
275  }
276  return nPart;
277 }
278 
REG_MODULE
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:652
Belle2::PCmsLabTransform::getCMSEnergy
double getCMSEnergy() const
Returns CMS energy of e+e- (aka.
Definition: PCmsLabTransform.h:57
Belle2::FoxWolfram::calculateBasicMoments
void calculateBasicMoments()
Method to perform the calculation of the moments up to order 4, which are the most relevant ones.
Definition: FoxWolfram.cc:20
Belle2::Module
Base class for Modules.
Definition: Module.h:74
Belle2::SphericityEigenvalues::calculateEigenvalues
void calculateEigenvalues()
Calculates eigenvalues and eigenvectors.
Definition: SphericityEigenvalues.cc:21
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::StoreObjPtr
Type-safe access to single objects in the data store.
Definition: ParticleList.h:33
Belle2::SphericityEigenvalues::getEigenvector
TVector3 getEigenvector(short i) const
Returns the i-th Eigenvector.
Definition: SphericityEigenvalues.h:80
Belle2::FoxWolfram::getH
double getH(int i) const
Returns the i-th moment.
Definition: FoxWolfram.h:103
Belle2::FoxWolfram::calculateAllMoments
void calculateAllMoments()
Method to perform the calculation of the moments up to order 8.
Definition: FoxWolfram.cc:64
Belle2::SphericityEigenvalues
Class to calculate the Sphericity tensor eigenvalues and eigenvectors starting from an array of 3-mom...
Definition: SphericityEigenvalues.h:33
Belle2::Particle
Class to store reconstructed particles.
Definition: Particle.h:77
Belle2::EventShapeCalculatorModule
Module to compute event shape variables starting from three lists of particle objects (tracks,...
Definition: EventShapeCalculatorModule.h:43
Belle2::PCmsLabTransform
Class to hold Lorentz transformations from/to CMS and boost vector.
Definition: PCmsLabTransform.h:37
Belle2::PCmsLabTransform::rotateLabToCms
const TLorentzRotation rotateLabToCms() const
Returns Lorentz transformation from Lab to CMS.
Definition: PCmsLabTransform.h:74
Belle2::CleoCones
Class to calculate the Cleo clone variables.
Definition: CleoCones.h:32
Belle2::SphericityEigenvalues::getEigenvalue
double getEigenvalue(short i) const
Returns the i-th Eigenvalue.
Definition: SphericityEigenvalues.h:72
Belle2::FoxWolfram
Class to calculate the Fox-Wolfram moments up to order 8.
Definition: FoxWolfram.h:48
Belle2::HarmonicMoments
Class to calculate the Harmonic moments up to order 8 with respect to a given axis.
Definition: HarmonicMoments.h:38