Belle II Software  release-08-01-10
scaleParticleEnergies.h
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 #pragma once
10 
11 #include <mdst/dataobjects/MCParticleGraph.h>
12 #include <Math/Vector3D.h>
13 #include <Math/Vector4D.h>
14 #include <vector>
15 
16 namespace Belle2 {
34  inline double getTotalEnergy(const std::vector<ROOT::Math::PxPyPzMVector>& ps)
35  {
36  double eTot = 0;
37  for (auto p : ps)
38  eTot += p.E();
39  return eTot;
40  }
41 
44  inline double getScaleFactor(const std::vector<ROOT::Math::PxPyPzMVector>& ps, double EcmsTarget)
45  {
46  double s = 0;
47  for (auto p : ps)
48  s += pow(p.P(), 2) / (2 * p.E());
49 
50  double dE = getTotalEnergy(ps) - EcmsTarget;
51  double L = dE / s;
52 
53  return sqrt(1 - L);
54  }
55 
58  inline std::vector<ROOT::Math::PxPyPzMVector> scaleMomenta(const std::vector<ROOT::Math::PxPyPzMVector>& ps, double C)
59  {
60  std::vector<ROOT::Math::PxPyPzMVector> psS(ps.size());
61  for (unsigned i = 0; i < ps.size(); ++i)
62  psS[i].SetCoordinates(C * ps[i].Px(), C * ps[i].Py(), C * ps[i].Pz(), ps[i].M());
63 
64  return psS;
65  }
66 
71  inline void scaleParticleEnergies(MCParticleGraph& mpg, double EcmsTarget)
72  {
73  // scale energy of incoming particles
74  double eIn = EcmsTarget / 2;
75  double pIn = sqrt(pow(eIn, 2) - pow(mpg[0].getMass(), 2));
76 
77  mpg[0].setMomentum(0, 0, pIn);
78  mpg[1].setMomentum(0, 0, -pIn);
79  mpg[0].setEnergy(eIn);
80  mpg[1].setEnergy(eIn);
81 
82 
83  // extract momenta of final state particles
84  std::vector<ROOT::Math::PxPyPzMVector> cmsMomenta(mpg.size() - 2);
85  for (size_t i = 2; i < mpg.size(); ++i) {
86  ROOT::Math::XYZVector p = mpg[i].getMomentum();
87  cmsMomenta[i - 2].SetCoordinates(p.X(), p.Y(), p.Z(), mpg[i].getMass());
88  }
89 
90  // calculate the scaling factor in an iterative way
91  double C = 1;
92  for (int i = 0; i < 10; ++i) {
93  auto cmsMomentaScaled = scaleMomenta(cmsMomenta, C);
94  double dC = getScaleFactor(cmsMomentaScaled, EcmsTarget);
95  C *= dC;
96  if (abs(dC - 1) < 3 * std::numeric_limits<double>::epsilon()) break;
97  }
98 
99  // apply scaling factor on final-state particles
100  auto cmsMomentaScaled = scaleMomenta(cmsMomenta, C);
101 
102  // change momenta in the MCParticleGraph
103  for (unsigned i = 2; i < mpg.size(); ++i) {
104  mpg[i].setMomentum(cmsMomentaScaled[i - 2].Px(), cmsMomentaScaled[i - 2].Py(), cmsMomentaScaled[i - 2].Pz());
105  mpg[i].setEnergy(cmsMomentaScaled[i - 2].E());
106  }
107  }
108 
110 }
R E
internal precision of FFTW codelets
Class to build, validate and sort a particle decay chain.
size_t size() const
Return the number of particles in the graph.
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
double getTotalEnergy(const std::vector< ROOT::Math::PxPyPzMVector > &ps)
Main function scaleParticleEnergies in this header scales momenta in CMS of all particles in the fina...
double getScaleFactor(const std::vector< ROOT::Math::PxPyPzMVector > &ps, double EcmsTarget)
Find approximative value of the momentum scaling factor which makes the total energy of the particles...
void scaleParticleEnergies(MCParticleGraph &mpg, double EcmsTarget)
Scale momenta of the particles by a constant factor such that total energy is changed to EcmsTarget.
std::vector< ROOT::Math::PxPyPzMVector > scaleMomenta(const std::vector< ROOT::Math::PxPyPzMVector > &ps, double C)
Scale momenta of the particles in the vector ps with a factor C.
Abstract base class for different kinds of events.