Belle II Software  light-2205-abys
MCInitialParticles.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 <TLorentzVector.h>
12 #include <Math/AxisAngle.h>
13 #include <Math/Boost.h>
14 #include <Math/LorentzRotation.h>
15 #include <Math/Vector3D.h>
16 #include <Math/Vector4D.h>
17 
18 #include <framework/geometry/B2Vector3.h>
19 
20 namespace Belle2 {
31  class MCInitialParticles: public TObject {
32 
33  public:
34 
38  c_generateCMS = 1 << 0,
46  c_smearVertex = 1 << 3,
49  };
50 
52  MCInitialParticles(): TObject() {}
53 
57 
60  {
61  m_her = b.m_her; m_ler = b.m_ler; m_vertex = b.m_vertex;
62  m_validFlag = b.m_validFlag; m_generationFlags = b.m_generationFlags;
63  resetBoost();
64  return *this;
65  }
66 
68  bool operator==(const MCInitialParticles& b) const
69  {
70  // FIXME: sin(x) returns slightly different values on
71  // different platforms in some cases so we cannot just do an equality
72  // comparison. We need to do this more elegantly, this is just for
73  // testing if it solves all problems
74 #if defined(MCP_DBL_CMP) || defined(MCP_VEC3_CMP) || defined(MCP_VEC4_CMP)
75 #error Macro already defined, cannot continue
76 #endif
77 #define MCP_DBL_CMP(a,b,x) ((a.x()==b.x())||(std::abs(a.x()-b.x())<1e-10))
78 #define MCP_VEC3_CMP(a,b) (MCP_DBL_CMP(a,b,X) && MCP_DBL_CMP(a,b,Y) && MCP_DBL_CMP(a,b,Z))
79 #define MCP_VEC4_CMP(a,b) (MCP_VEC3_CMP(a,b) && MCP_DBL_CMP(a,b,E))
80  return MCP_VEC4_CMP(m_her, b.m_her) && MCP_VEC4_CMP(m_ler, b.m_ler) && MCP_VEC3_CMP(m_vertex, b.m_vertex)
81  && m_validFlag == b.m_validFlag &&
82  m_generationFlags == b.m_generationFlags;
83 #undef MCP_DBL_CMP
84 #undef MCP_VEC3_CMP
85 #undef MCP_VEC4_CMP
86  }
87 
90 
97  void set(const ROOT::Math::PxPyPzEVector& her, const ROOT::Math::PxPyPzEVector& ler, const B2Vector3D& vertex)
98  {
99  m_her = her;
100  m_ler = ler;
101  m_vertex = vertex;
102  m_validFlag = true;
103  resetBoost();
104  }
105 
107  void setHER(const ROOT::Math::PxPyPzEVector& her)
108  {
109  m_her = her;
110  resetBoost();
111  }
112 
114  void setLER(const ROOT::Math::PxPyPzEVector& ler)
115  {
116  m_ler = ler;
117  resetBoost();
118  }
119 
121  void setVertex(const B2Vector3D& vertex)
122  {
123  m_vertex = vertex;
124  }
125 
127  void setTime(double time) {m_time = time;}
128 
130  virtual void setGenerationFlags(int flags) { m_generationFlags = flags; }
131 
133  const ROOT::Math::PxPyPzEVector& getHER() const { return m_her; }
134 
136  const ROOT::Math::PxPyPzEVector& getLER() const { return m_ler; }
137 
139  const B2Vector3D& getVertex() const { return m_vertex; }
140 
142  double getTime() const {return m_time;}
143 
145  double getEnergy() const { return (m_her + m_ler).E(); }
146 
148  double getMass() const { calculateBoost(); return m_invariantMass; }
149 
151  const ROOT::Math::LorentzRotation& getLabToCMS() const
152  {
153  calculateBoost(); return *m_labToCMS;
154  }
155 
157  const ROOT::Math::LorentzRotation& getCMSToLab() const
158  {
159  calculateBoost(); return *m_CMSToLab;
160  }
161 
163  bool getValidFlag() const { return m_validFlag; }
164 
166  int getGenerationFlags() const { return m_generationFlags; }
167 
169  bool hasGenerationFlags(int flags) const { return (m_generationFlags & flags) == flags; }
170 
173  std::string getGenerationFlagString(const std::string& separator = " ") const;
174 
175  private:
176 
178  void calculateBoost() const;
180  void resetBoost();
182  ROOT::Math::PxPyPzEVector m_her;
184  ROOT::Math::PxPyPzEVector m_ler;
188  double m_time = 0;
190  mutable ROOT::Math::LorentzRotation* m_labToCMS{nullptr};
192  mutable ROOT::Math::LorentzRotation* m_CMSToLab{nullptr};
194  mutable double m_invariantMass{0.0};
196  bool m_validFlag = false;
197 
198  protected:
199 
202 
203  private:
204 
207  };
208 
210  {
211  if (m_labToCMS)
212  return;
213 
214  ROOT::Math::PxPyPzEVector beam = m_her + m_ler;
215  // Save the invariant mass because it's used very often in analysis
216  m_invariantMass = beam.M();
217 
218  // If we generate events in CMS we already are in CMS and there is no
219  // transformation so let's use the identity
221  m_labToCMS = new ROOT::Math::LorentzRotation();
222  m_CMSToLab = new ROOT::Math::LorentzRotation();
223  return;
224  }
225 
226  // Transformation from Lab system to CMS system
227  m_labToCMS = new ROOT::Math::LorentzRotation(ROOT::Math::Boost(beam.BoostToCM()));
228  // boost HER e- from Lab system to CMS system
229  const ROOT::Math::PxPyPzEVector electronCMS = (*m_labToCMS) * m_her;
230  // now rotate CMS such that incoming e- is parallel to z-axis
231  const ROOT::Math::XYZVector zaxis(0., 0., 1.);
232  ROOT::Math::XYZVector rotaxis = zaxis.Cross(electronCMS.Vect()) / electronCMS.P();
233  double rotangle = TMath::ASin(rotaxis.R());
234  const ROOT::Math::LorentzRotation rotation(ROOT::Math::AxisAngle(rotaxis, -rotangle));
235  *m_labToCMS = rotation * (*m_labToCMS);
236 
237  //cache derived quantities
238  m_CMSToLab = new ROOT::Math::LorentzRotation(m_labToCMS->Inverse());
239  }
240 
242  {
243  delete m_labToCMS;
244  delete m_CMSToLab;
245  m_labToCMS = nullptr;
246  m_CMSToLab = nullptr;
247  m_invariantMass = 0.0;
248  }
249 
251 } //Belle2 namespace
This class contains the initial state for the given event.
const ROOT::Math::PxPyPzEVector & getLER() const
Get 4vector of the low energy beam.
int m_generationFlags
Flags to be used when generating events.
ROOT::Math::LorentzRotation * m_CMSToLab
transient
bool operator==(const MCInitialParticles &b) const
Equality operator.
int getGenerationFlags() const
Get the generation flags to be used for event generation (ORed combination of EGenerationFlags)
bool getValidFlag() const
Get the flag to check if a valid MCInitialParticles object was already generated and filled in an eve...
void set(const ROOT::Math::PxPyPzEVector &her, const ROOT::Math::PxPyPzEVector &ler, const B2Vector3D &vertex)
Set the initial event values, i.e.
const ROOT::Math::PxPyPzEVector & getHER() const
Get 4vector of the high energy beam.
double m_time
collision time
ROOT::Math::PxPyPzEVector m_ler
LER 4vector.
void setTime(double time)
Set collison time.
double getEnergy() const
Get the the actual collision energy (in lab system)
ROOT::Math::PxPyPzEVector m_her
HER 4vector.
EGenerationFlags
Possible Flags for initial event generation.
@ c_smearBeam
smear the full beam momentum (energy and direction)
@ c_generateCMS
generate initial event in CMS instead of lab
@ c_smearBeamEnergy
smear energy of HER and LER (but not direction)
@ c_smearBeamDirection
smear direction of HER and LER (but not energy)
ROOT::Math::LorentzRotation * m_labToCMS
Boost from Lab into CMS.
void setVertex(const B2Vector3D &vertex)
Set the vertex position.
MCInitialParticles & operator=(const MCInitialParticles &b)
Assignment operator.
std::string getGenerationFlagString(const std::string &separator=" ") const
Return string representation of all active flags for printing.
virtual void setGenerationFlags(int flags)
Set the generation flags to be used for event generation (ORed combination of EGenerationFlags)
B2Vector3D m_vertex
collision position
MCInitialParticles()
Default constructor.
const ROOT::Math::LorentzRotation & getLabToCMS() const
Return the LorentzRotation to convert from lab to CMS frame.
bool hasGenerationFlags(int flags) const
Check if a certain set of EGenerationFlags is set.
ClassDef(MCInitialParticles, 4)
ROOT Dictionary.
void setHER(const ROOT::Math::PxPyPzEVector &her)
Set the High Energy Beam 4-momentum.
MCInitialParticles(const MCInitialParticles &b)
Copy constructor.
void setLER(const ROOT::Math::PxPyPzEVector &ler)
Set the Low Energy Beam 4-momentum.
virtual ~MCInitialParticles()
Free memory of the LorentzRotation if it was created.
const ROOT::Math::LorentzRotation & getCMSToLab() const
Return the LorentzRotation to convert from CMS to lab frame.
const B2Vector3D & getVertex() const
Get the position of the collision.
double getMass() const
Get the invariant mass of the collision (= energy in CMS)
double getTime() const
Get collison time.
void resetBoost()
Reset cached transformations after changing parameters.
void calculateBoost() const
Calculate the boost if necessary.
Abstract base class for different kinds of events.
Definition: ClusterUtils.h:23