Belle II Software  release-08-01-10
SensorInfo.cc
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 #include <svd/geometry/SensorInfo.h>
10 #include <framework/gearbox/Unit.h>
11 #include <framework/geometry/BFieldManager.h>
12 
13 #include <Math/Vector3D.h>
14 #include <math.h>
15 
16 using namespace std;
17 using namespace Belle2;
18 using namespace Belle2::SVD;
19 
20 
21 double SensorInfo::getElectronMobility(double E) const
22 {
23  // Electron parameters - maximum velocity, critical intensity, beta factor
24  static double vmElec = 1.53 * pow(m_temperature, -0.87) * 1.E9 * Unit::cm
25  / Unit::s;
26  static double EcElec = 1.01 * pow(m_temperature, +1.55) * Unit::V
27  / Unit::cm;
28  static double betaElec = 2.57 * pow(m_temperature, +0.66) * 1.E-2;
29 
30  return (vmElec / EcElec * 1.
31  / (pow(1. + pow((fabs(E) / EcElec), betaElec), (1. / betaElec))));
32 }
33 
34 double SensorInfo::getHoleMobility(double E) const
35 {
36  // Hole parameters - maximum velocity, critical intensity, beta factor
37  static double vmHole = 1.62 * pow(m_temperature, -0.52) * 1.E8 * Unit::cm
38  / Unit::s;
39  static double EcHole = 1.24 * pow(m_temperature, +1.68) * Unit::V
40  / Unit::cm;
41  static double betaHole = 0.46 * pow(m_temperature, +0.17);
42 
43  return (vmHole / EcHole * 1.
44  / (pow(1. + pow((fabs(E) / EcHole), betaHole), (1. / betaHole))));
45 }
46 
47 const ROOT::Math::XYZVector SensorInfo::getEField(const ROOT::Math::XYZVector& point) const
48 {
49 
50  ROOT::Math::XYZVector E(0, 0,
51  + 2.0 * m_depletionVoltage / m_thickness
52  * ((+point.Z() - 0.5 * m_thickness) / m_thickness)
53  - (m_biasVoltage - m_depletionVoltage) / m_thickness);
54 
55  return E;
56 }
57 
58 const ROOT::Math::XYZVector& SensorInfo::getBField(const ROOT::Math::XYZVector& point) const
59 {
60  // useful just for testing:
61  // static ROOT::Math::XYZVector noBfield(0,0,0);
62  // return noBfield;
63 
64  static ROOT::Math::XYZVector oldPoint(0, 0, 1000 * Unit::cm);
65  static ROOT::Math::XYZVector oldField(0, 0, 0);
66  static double bRadius = 0.5 * Unit::cm;
67  if ((point - oldPoint).R() > bRadius) { // renew if far point
68  ROOT::Math::XYZVector pointGlobal = pointToGlobal(point, true);
69  ROOT::Math::XYZVector bGlobal = BFieldManager::getField(pointGlobal);
70  ROOT::Math::XYZVector bLocal = vectorToLocal(bGlobal, true);
71  oldPoint = point;
72  oldField = bLocal;
73  }
74  return oldField;
75 }
76 
77 const ROOT::Math::XYZVector
78 SensorInfo::getVelocity(CarrierType carrier, const ROOT::Math::XYZVector& point) const
79 {
80  ROOT::Math::XYZVector E = getEField(point);
81  // This is what makes the digitizer slow.
82  ROOT::Math::XYZVector B = getBField(point);
83  // Set mobility parameters
84  double mobility = 0;
85  double hallFactor = getHallFactor(carrier);
86 
87  if (carrier == electron) {
88  mobility = -getElectronMobility(E.R());
89  } else {
90  mobility = getHoleMobility(E.R());
91  }
92 
93  double mobilityH = hallFactor * fabs(mobility);
94 
95  // Calculate products
96  ROOT::Math::XYZVector EcrossB = E.Cross(B);
97  ROOT::Math::XYZVector BEdotB = E.Dot(B) * B;
98  ROOT::Math::XYZVector velocity = mobility * E + mobility * mobilityH * EcrossB
99  + mobility * mobilityH * mobilityH * BEdotB;
100  velocity *= 1.0 / (1.0 + mobilityH * mobilityH * B.Mag2());
101  return velocity;
102 }
103 
104 const ROOT::Math::XYZVector& SensorInfo::getLorentzShift(double uCoord, double vCoord) const
105 {
106  static ROOT::Math::XYZVector result;
107  double distanceToFrontPlane = 0.5 * m_thickness;
108  double distanceToBackPlane = 0.5 * m_thickness;
109 
110  // Approximation: calculate drift velocity at the point halfway towards
111  // the respective sensor surface.
112  ROOT::Math::XYZVector v_e = getVelocity(electron, ROOT::Math::XYZVector(uCoord, vCoord, +0.5 * distanceToFrontPlane));
113  ROOT::Math::XYZVector v_h = getVelocity(hole, ROOT::Math::XYZVector(uCoord, vCoord, -0.5 * distanceToBackPlane));
114 
115  // Calculate drift directions
116  ROOT::Math::XYZVector center_e = fabs(distanceToFrontPlane / v_e.Z()) * v_e;
117  ROOT::Math::XYZVector center_h = fabs(distanceToBackPlane / v_h.Z()) * v_h;
118  result.SetXYZ(center_h.X(), center_e.Y(), 0.0);
119  return result;
120 }
121 
122 double SensorInfo::getLorentzShift(bool isUCoordinate, double position) const
123 {
124  if (isUCoordinate)
125  return getLorentzShift(position, 0.0).X();
126  else
127  return getLorentzShift(0.0, position).Y();
128 }
129 
R E
internal precision of FFTW codelets
double R
typedef autogenerated by FFTW
CarrierType
Enum to flag charge carriers.
Definition: SensorInfo.h:38
Namespace to encapsulate code needed for simulation and reconstrucion of the SVD.
Definition: GeoSVDCreator.h:23
Abstract base class for different kinds of events.