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 <pxd/geometry/SensorInfo.h>
10 #include <framework/gearbox/Unit.h>
11 #include <framework/gearbox/Const.h>
12 #include <framework/geometry/BFieldManager.h>
13 #include <vxd/geometry/GeoCache.h>
14 
15 using namespace std;
16 using namespace Belle2;
17 using namespace Belle2::PXD;
18 
19 
20 double SensorInfo::getElectronMobility(double E) const
21 {
22  // Electron parameters - maximum velocity, critical intensity, beta factor
23  static double vmElec = 1.53 * pow(m_temperature, -0.87) * 1.E9 * Unit::cm
24  / Unit::s;
25  static double EcElec = 1.01 * pow(m_temperature, +1.55) * Unit::V
26  / Unit::cm;
27  static double betaElec = 2.57 * pow(m_temperature, +0.66) * 1.E-2;
28 
29  return (vmElec / EcElec * 1.
30  / (pow(1. + pow((fabs(E) / EcElec), betaElec), (1. / betaElec))));
31 }
32 
33 const ROOT::Math::XYZVector SensorInfo::getEField(const ROOT::Math::XYZVector& point) const
34 {
35  // FIXME: Get rid of the gateDepth
36  double depletionVoltage = 0.5 * Unit::e * m_bulkDoping
37  / Const::permSi * m_thickness * m_thickness;
38  double gateZ = 0.5 * m_thickness - m_gateDepth;
39  double Ez = 2 * depletionVoltage * (point.Z() - gateZ) / m_thickness
40  / m_thickness;
41  ROOT::Math::XYZVector E(0, 0, Ez);
42  return E;
43 }
44 
45 const ROOT::Math::XYZVector SensorInfo::getBField(const ROOT::Math::XYZVector& point) const
46 {
47  ROOT::Math::XYZVector pointGlobal = pointToGlobal(point, true);
48  ROOT::Math::XYZVector bGlobal = BFieldManager::getField(pointGlobal);
49  ROOT::Math::XYZVector bLocal = vectorToLocal(bGlobal, true);
50  return bLocal;
51 }
52 
53 const ROOT::Math::XYZVector
54 SensorInfo::getDriftVelocity(const ROOT::Math::XYZVector& E,
55  const ROOT::Math::XYZVector& B) const
56 {
57  // Set mobility parameters
58  double mobility = -getElectronMobility(E.R());
59  double mobilityH = m_hallFactor * mobility;
60  // Calculate products
61  ROOT::Math::XYZVector EcrossB = E.Cross(B);
62  ROOT::Math::XYZVector BEdotB = E.Dot(B) * B;
63  ROOT::Math::XYZVector v = mobility * E + mobility * mobilityH * EcrossB
64  + mobility * mobilityH * mobilityH * BEdotB;
65  v *= 1.0 / (1.0 + mobilityH * mobilityH * B.Mag2());
66  return v;
67 }
68 
69 int SensorInfo::getPixelKind(const VxdID sensorID, double v) const
70 {
71  const SensorInfo& Info = dynamic_cast<const SensorInfo&>(VXD::GeoCache::get(sensorID));
72  int i_pixelKind = Info.getVPitchID(v);
73  if (Info.getID().getLayerNumber() == 2) i_pixelKind += 4;
74  if (Info.getID().getSensorNumber() == 2) i_pixelKind += 2;
75  return i_pixelKind;
76 }
77 
78 int SensorInfo::getPixelKindNew(const VxdID& sensorID, int vID) const
79 {
80  const SensorInfo& Info = dynamic_cast<const SensorInfo&>(VXD::GeoCache::get(sensorID));
81  double v = Info.getVCellPosition(vID);
82  double vPitch = Info.getVPitch(v);
83  int i_pixelKind = 0;
84 
85  if (std::fabs(vPitch - 0.0055) < 0.0001)
86  i_pixelKind = 0;
87  else if (std::fabs(vPitch - 0.0060) < 0.0001)
88  i_pixelKind = 1;
89  else if (std::fabs(vPitch - 0.0070) < 0.0001)
90  i_pixelKind = 2;
91  else if (std::fabs(vPitch - 0.0085) < 0.0001)
92  i_pixelKind = 3;
93  else
94  B2FATAL("Unexpected pixel vPitch.");
95  return i_pixelKind;
96 }
97 
98 
99 const ROOT::Math::XYZVector SensorInfo::getLorentzShift(double u, double v) const
100 {
101  // Constants for the 5-point Gauss quadrature formula
102  const double alphaGL = 1.0 / 3.0 * sqrt(5.0 + 2.0 * sqrt(10.0 / 7.0));
103  const double betaGL = 1.0 / 3.0 * sqrt(5.0 - 2.0 * sqrt(10.0 / 7.0));
104  const double walpha = (322 - 13.0 * sqrt(70)) / 900;
105  const double wbeta = (322 + 13.0 * sqrt(70)) / 900;
106  const double distanceToPlane = 0.5 * m_thickness - m_gateDepth;
107  const double midpoint = 0.5 * distanceToPlane;
108  const double h = 0.5 * distanceToPlane;
109  const double weightGL[5] = {
110  h * walpha, h * wbeta, h * 128.0 / 225.0, h * wbeta, h* walpha
111  };
112  const double zKnots[5] = {
113  midpoint - alphaGL * h, midpoint - betaGL * h, midpoint, midpoint + betaGL * h, midpoint + alphaGL* h
114  };
115  // Integrate v/v_z from z = 0 to z = distanceToPlane
116  ROOT::Math::XYZVector position(u, v, 0);
117  ROOT::Math::XYZVector currentBField = getBField(position);
118  for (int iz = 0; iz < 5; ++iz) {
119  // This is OK as long as E only depends on z
120  ROOT::Math::XYZVector currentEField = getEField(ROOT::Math::XYZVector(0, 0, zKnots[iz]));
121  ROOT::Math::XYZVector velocity = getDriftVelocity(currentEField, currentBField);
122  position += weightGL[iz] / velocity.Z() * velocity;
123  } // for knots
124  position.SetZ(0);
125  position.SetX(position.X() - u);
126  position.SetY(position.Y() - v);
127  return position;
128 }
129 
130 void SensorInfo::cook()
131 {
132  m_iup = m_uCells / m_width;
133  m_up = m_width / m_uCells;
134 
135  m_vsplit = m_length * (m_splitLength - 0.5);
136 
137  m_vp = m_length * m_splitLength / m_vCells;
138  m_ivp = 1 / m_vp;
139 
140  m_vp2 = m_length * (1 - m_splitLength) / m_vCells2;
141  m_ivp2 = 1 / m_vp2;
142 
143  m_hxIG = 0.5 * m_up - m_clearBorderSmallPitch;
144  m_mIGL = 0.5 * (m_vp - m_sourceBorderLargePitch + m_drainBorderLargePitch);
145  m_sIGL = 0.5 * (m_vp - m_sourceBorderLargePitch - m_drainBorderLargePitch);
146  m_mIGS = 0.5 * (m_vp2 - m_sourceBorderSmallPitch + m_drainBorderSmallPitch);
147  m_sIGS = 0.5 * (m_vp2 - m_sourceBorderSmallPitch - m_drainBorderSmallPitch);
148 }
149 
150 int SensorInfo::getTrappedID(double x, double y) const
151 {
152  double huCells = 0.5 * m_uCells;
153  double ix = floor(x * m_iup + huCells);
154  int jx = ix;
155  double x0 = (ix + 0.5 - huCells) * m_up;
156 
157  if (fabs(x - x0) < m_hxIG) {
158  if ((unsigned)jx >= (unsigned)m_uCells) return -1;
159  double ys = y - m_vsplit;
160  if (ys >= 0) {
161  double iy = floor(ys * m_ivp2);
162  int jy = iy;
163  iy = jy / 2;
164  double y0 = iy * m_vp2 * 2 + m_vp2;
165  double yl = fabs(ys - y0);
166  if (fabs(yl - m_mIGS) < m_sIGS) {
167  if ((unsigned)jy >= (unsigned)m_vCells2) return -1;
168  return jx + m_uCells * (jy + m_vCells);
169  }
170  return -1;
171  } else {
172  ys = y + 0.5 * m_length;
173  double iy = floor(ys * m_ivp);
174  int jy = iy;
175  iy = jy / 2;
176  double y0 = iy * m_vp * 2 + m_vp;
177  double yl = fabs(ys - y0);
178  if (fabs(yl - m_mIGL) < m_sIGL) {
179  if ((unsigned)jy >= (unsigned)m_vCells) return -1;
180  return jx + m_uCells * jy;
181  }
182  return -1;
183  }
184  }
185  return -1;
186 }
R E
internal precision of FFTW codelets
Specific implementation of SensorInfo for PXD Sensors which provides additional pixel specific inform...
Definition: SensorInfo.h:23
double getVCellPosition(int vID) const
Return the position of a specific strip/pixel in v direction.
VxdID getID() const
Return the ID of the Sensor.
double getVPitch(double v=0) const
Return the pitch of the sensor.
int getVPitchID(double v=0) const
Return the pitch ID of the sensor.
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
baseType getSensorNumber() const
Get the sensor id.
Definition: VxdID.h:100
baseType getLayerNumber() const
Get the layer id.
Definition: VxdID.h:96
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Namespace to encapsulate code needed for simulation and reconstrucion of the PXD.
Abstract base class for different kinds of events.