Belle II Software  release-06-01-15
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 <TLorentzRotation.h>
13 
14 namespace Belle2 {
25  class MCInitialParticles: public TObject {
26 
27  public:
28 
32  c_generateCMS = 1 << 0,
40  c_smearVertex = 1 << 3,
43  };
44 
46  MCInitialParticles(): TObject() {}
47 
51 
54  {
55  m_her = b.m_her; m_ler = b.m_ler; m_vertex = b.m_vertex;
56  m_validFlag = b.m_validFlag; m_generationFlags = b.m_generationFlags;
57  resetBoost();
58  return *this;
59  }
60 
62  bool operator==(const MCInitialParticles& b) const
63  {
64  // FIXME: sin(x) returns slightly different values on
65  // different platforms in some cases so we cannot just do an equality
66  // comparison. We need to do this more elegantly, this is just for
67  // testing if it solves all problems
68 #if defined(MCP_DBL_CMP) || defined(MCP_VEC3_CMP) || defined(MCP_VEC4_CMP)
69 #error Macro already defined, cannot continue
70 #endif
71 #define MCP_DBL_CMP(a,b,x) ((a.x()==b.x())||(std::abs(a.x()-b.x())<1e-10))
72 #define MCP_VEC3_CMP(a,b) (MCP_DBL_CMP(a,b,X) && MCP_DBL_CMP(a,b,Y) && MCP_DBL_CMP(a,b,Z))
73 #define MCP_VEC4_CMP(a,b) (MCP_VEC3_CMP(a,b) && MCP_DBL_CMP(a,b,E))
74  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)
75  && m_validFlag == b.m_validFlag &&
76  m_generationFlags == b.m_generationFlags;
77 #undef MCP_DBL_CMP
78 #undef MCP_VEC3_CMP
79 #undef MCP_VEC4_CMP
80  }
81 
84 
91  void set(const TLorentzVector& her, const TLorentzVector& ler, const TVector3& vertex)
92  {
93  m_her = her;
94  m_ler = ler;
95  m_vertex = vertex;
96  m_validFlag = true;
97  resetBoost();
98  }
99 
101  void setHER(const TLorentzVector& her)
102  {
103  m_her = her;
104  resetBoost();
105  }
106 
108  void setLER(const TLorentzVector& ler)
109  {
110  m_ler = ler;
111  resetBoost();
112  }
113 
115  void setVertex(const TVector3& vertex)
116  {
117  m_vertex = vertex;
118  }
119 
121  void setTime(double time) {m_time = time;}
122 
124  void setGenerationFlags(int flags) { m_generationFlags = flags; }
125 
127  const TLorentzVector& getHER() const { return m_her; }
128 
130  const TLorentzVector& getLER() const { return m_ler; }
131 
133  const TVector3& getVertex() const { return m_vertex; }
134 
136  double getTime() const {return m_time;}
137 
139  double getEnergy() const { return (m_her + m_ler).E(); }
140 
142  double getMass() const { calculateBoost(); return m_invariantMass; }
143 
145  const TLorentzRotation& getLabToCMS() const
146  {
147  calculateBoost(); return *m_labToCMS;
148  }
149 
151  const TLorentzRotation& getCMSToLab() const
152  {
153  calculateBoost(); return *m_CMSToLab;
154  }
155 
157  bool getValidFlag() const { return m_validFlag; }
158 
160  int getGenerationFlags() const { return m_generationFlags; }
161 
163  bool hasGenerationFlags(int flags) const { return (m_generationFlags & flags) == flags; }
164 
167  std::string getGenerationFlagString(const std::string& separator = " ") const;
168 
169  private:
170 
172  void calculateBoost() const;
174  void resetBoost();
176  TLorentzVector m_her;
178  TLorentzVector m_ler;
180  TVector3 m_vertex;
182  double m_time = 0;
184  mutable TLorentzRotation* m_labToCMS{nullptr};
186  mutable TLorentzRotation* m_CMSToLab{nullptr};
188  mutable double m_invariantMass{0.0};
190  bool m_validFlag = false;
195  };
196 
198  {
199  if (m_labToCMS)
200  return;
201 
202  TLorentzVector beam = m_her + m_ler;
203  // Save the invariant mass because it's used very often in analysis
204  m_invariantMass = beam.M();
205 
206  // If we generate events in CMS we already are in CMS and there is no
207  // transformation so let's use the identity
209  m_labToCMS = new TLorentzRotation();
210  m_CMSToLab = new TLorentzRotation();
211  return;
212  }
213 
214  // Transformation from Lab system to CMS system
215  m_labToCMS = new TLorentzRotation(-beam.BoostVector());
216  // boost HER e- from Lab system to CMS system
217  const TLorentzVector electronCMS = (*m_labToCMS) * m_her;
218  // now rotate CMS such that incoming e- is parallel to z-axis
219  const TVector3 zaxis(0., 0., 1.);
220  TVector3 rotaxis = zaxis.Cross(electronCMS.Vect()) * (1. / electronCMS.Vect().Mag());
221  double rotangle = TMath::ASin(rotaxis.Mag());
222  m_labToCMS->Rotate(-rotangle, rotaxis);
223 
224  //cache derived quantities
225  m_CMSToLab = new TLorentzRotation(m_labToCMS->Inverse());
226  }
227 
229  {
230  delete m_labToCMS;
231  delete m_CMSToLab;
232  m_labToCMS = nullptr;
233  m_CMSToLab = nullptr;
234  m_invariantMass = 0.0;
235  }
236 
238 } //Belle2 namespace
This class contains the initial state for the given event.
ClassDef(MCInitialParticles, 3)
ROOT Dictionary.
int m_generationFlags
Flags to be used when generating events.
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 setLER(const TLorentzVector &ler)
Set the Low Energy Beam 4-momentum.
const TLorentzRotation & getLabToCMS() const
Return the LorentzRotation to convert from lab to CMS frame.
void setVertex(const TVector3 &vertex)
Set the vertex position.
double m_time
collision time
void setTime(double time)
Set collison time.
void setHER(const TLorentzVector &her)
Set the High Energy Beam 4-momentum.
double getEnergy() const
Get the the actual collision energy (in lab system)
const TLorentzRotation & getCMSToLab() const
Return the LorentzRotation to convert from CMS to lab frame.
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)
void set(const TLorentzVector &her, const TLorentzVector &ler, const TVector3 &vertex)
Set the initial event values, i.e.
TLorentzVector m_her
HER 4vector.
const TLorentzVector & getLER() const
Get 4vector of the low energy beam.
const TVector3 & getVertex() const
Get the position of the collision.
MCInitialParticles & operator=(const MCInitialParticles &b)
Assignment operator.
TLorentzRotation * m_labToCMS
Boost from Lab into CMS.
std::string getGenerationFlagString(const std::string &separator=" ") const
Return string representation of all active flags for printing.
TVector3 m_vertex
collision position
MCInitialParticles()
Default constructor.
TLorentzRotation * m_CMSToLab
transient
bool hasGenerationFlags(int flags) const
Check if a certain set of EGenerationFlags is set.
MCInitialParticles(const MCInitialParticles &b)
Copy constructor.
TLorentzVector m_ler
LER 4vector.
virtual ~MCInitialParticles()
Free memory of the LorentzRotation if it was created.
const TLorentzVector & getHER() const
Get 4vector of the high energy beam.
void setGenerationFlags(int flags)
Set the generation flags to be used for event generation (ORed combination of EGenerationFlags)
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.