Belle II Software development
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
16namespace 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 getTotalEnergy(const std::vector< ROOT::Math::PxPyPzMVector > &ps)
Main function scaleParticleEnergies in this header scales momenta in CMS of all particles in the fina...
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.
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.
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.