Belle II Software  release-08-01-10
SVDRecoHit2D.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 <framework/logging/Logger.h>
10 #include <framework/geometry/VectorUtil.h>
11 #include <svd/reconstruction/SVDRecoHit2D.h>
12 #include <svd/geometry/SensorInfo.h>
13 #include <vxd/geometry/SensorPlane.h>
14 #include <vxd/geometry/GeoCache.h>
15 
16 #include <genfit/DetPlane.h>
17 #include <TVector3.h>
18 #include <TRandom.h>
19 #include <cmath>
20 
21 using namespace std;
22 using namespace Belle2;
23 
24 SVDRecoHit2D::SVDRecoHit2D():
25  genfit::PlanarMeasurement(HIT_DIMENSIONS), m_sensorID(0), m_trueHit(0), m_uCluster(0), m_vCluster(0),
26  m_energyDep(0)//, m_energyDepError(0)
27 {}
28 
29 SVDRecoHit2D::SVDRecoHit2D(const SVDTrueHit* hit, const genfit::TrackCandHit*, float sigmaU, float sigmaV):
30  genfit::PlanarMeasurement(HIT_DIMENSIONS), m_sensorID(0), m_trueHit(hit), m_uCluster(0), m_vCluster(0),
31  m_energyDep(0)//, m_energyDepError(0)
32 {
33  if (!gRandom) B2FATAL("gRandom not initialized, please set up gRandom first");
34 
35  // Set the sensor UID
36  m_sensorID = hit->getSensorID();
37 
38  //If no error is given, estimate the error by dividing the pixel size by sqrt(12)
39  if (sigmaU < 0 || sigmaV < 0) {
40  const SVD::SensorInfo& geometry = dynamic_cast<const SVD::SensorInfo&>(VXD::GeoCache::get(m_sensorID));
41  sigmaU = geometry.getUPitch(hit->getV()) / sqrt(12);
42  sigmaV = geometry.getVPitch(hit->getV()) / sqrt(12);
43  }
44 
45  // Set positions
46  rawHitCoords_(0) = gRandom->Gaus(hit->getU(), sigmaU);
47  rawHitCoords_(1) = gRandom->Gaus(hit->getV(), sigmaV);
48  // Set the error covariance matrix
49  rawHitCov_(0, 0) = sigmaU * sigmaU;
50  rawHitCov_(0, 1) = 0;
51  rawHitCov_(1, 0) = 0;
52  rawHitCov_(1, 1) = sigmaV * sigmaV;
53  // Set physical parameters
54  m_energyDep = hit->getEnergyDep();
55  // Setup geometry information
57 }
58 
59 SVDRecoHit2D::SVDRecoHit2D(VxdID::baseType vxdid, const double u, const double v, double sigmaU, double sigmaV):
60  genfit::PlanarMeasurement(HIT_DIMENSIONS), m_sensorID(vxdid), m_trueHit(nullptr), m_uCluster(0), m_vCluster(0),
61  m_energyDep(0)//, m_energyDepError(0)
62 {
63  //If no error is given, estimate the error by dividing the pixel size by sqrt(12)
64  if (sigmaU < 0 || sigmaV < 0) {
65  const SVD::SensorInfo& geometry = dynamic_cast<const SVD::SensorInfo&>(VXD::GeoCache::get(m_sensorID));
66  sigmaU = geometry.getUPitch(v) / sqrt(12);
67  sigmaV = geometry.getVPitch(v) / sqrt(12);
68  }
69  // Set positions
70  rawHitCoords_(0) = u;
71  rawHitCoords_(1) = v;
72  // Set the error covariance matrix
73  rawHitCov_(0, 0) = sigmaU * sigmaU;
74  rawHitCov_(0, 1) = 0;
75  rawHitCov_(1, 0) = 0;
76  rawHitCov_(1, 1) = sigmaV * sigmaV;
77  // Setup geometry information
79 }
80 
82  genfit::PlanarMeasurement(HIT_DIMENSIONS), m_trueHit(nullptr), m_uCluster(&uHit), m_vCluster(&vHit),
83  m_energyDep(0)
84 {
85  if ((uHit.getRawSensorID() != vHit.getRawSensorID()) || !uHit.isUCluster() || vHit.isUCluster())
86  B2FATAL("Error in SVDRecoHit2D: Incorrect SVDCluster instances on input!");
87 
88  m_sensorID = uHit.getRawSensorID();
89 
90  // Now that we have a v coordinate, we can rescale u.
91  const SVD::SensorInfo& info =
92  dynamic_cast<const SVD::SensorInfo&>(VXD::GeoCache::get(m_sensorID));
93 
94  double DeltaU =
95  (info.getForwardWidth() - info.getBackwardWidth()) / info.getLength() / info.getWidth(0);
96  double scaleFactorU = 1 + DeltaU * vHit.getPosition();
97  double tan_phi = DeltaU * uHit.getPosition(); // need u at v=0!
98  double one_over_cos_phi_sqr = 1 + tan_phi * tan_phi;
99 
100  rawHitCoords_[0] = uHit.getPosition() * scaleFactorU;
101  rawHitCoords_[1] = vHit.getPosition();
102 
103  double sigmaU = uHit.getPositionSigma() * scaleFactorU;
104  double sigmaU_sq = sigmaU * sigmaU;
105  double sigmaV = vHit.getPositionSigma();
106  double sigmaV_sq = sigmaV * sigmaV;
107 
108  m_energyDep = 0.5 * (uHit.getCharge() + vHit.getCharge());
109 
110  rawHitCov_(0, 0) = sigmaV_sq * tan_phi * tan_phi + sigmaU_sq * one_over_cos_phi_sqr;
111  rawHitCov_(0, 1) = sigmaV_sq * tan_phi;
112  rawHitCov_(1, 0) = sigmaV_sq * tan_phi;
113  rawHitCov_(1, 1) = sigmaV_sq;
114  // Setup geometry information
115  setDetectorPlane();
116 }
117 
118 SVDRecoHit2D::SVDRecoHit2D(const SVDRecoHit& uRecoHit, const SVDRecoHit& vRecoHit):
119  genfit::PlanarMeasurement(HIT_DIMENSIONS), m_trueHit(nullptr), m_uCluster(0), m_vCluster(0), m_energyDep(0)
120 {
121  const SVDCluster& uHit = *(uRecoHit.getCluster());
122  const SVDCluster& vHit = *(vRecoHit.getCluster());
123  if ((uHit.getRawSensorID() != vHit.getRawSensorID()) || !uHit.isUCluster() || vHit.isUCluster())
124  B2FATAL("Error in SVDRecoHit2D: Incorrect SVDCluster instances on input!");
125 
126  m_sensorID = uHit.getRawSensorID();
127  m_uCluster = &uHit;
128  m_vCluster = &vHit;
129 
130  // Now that we have a v coordinate, we can rescale u.
131  const SVD::SensorInfo& info =
132  dynamic_cast<const SVD::SensorInfo&>(VXD::GeoCache::get(m_sensorID));
133 
134  double DeltaU =
135  (info.getForwardWidth() - info.getBackwardWidth()) / info.getLength() / info.getWidth(0);
136  double scaleFactorU = 1 + DeltaU * vHit.getPosition();
137  double tan_phi = DeltaU * uHit.getPosition(); // need u at v=0!
138  double one_over_cos_phi_sqr = 1 + tan_phi * tan_phi;
139 
140  rawHitCoords_[0] = uHit.getPosition() * scaleFactorU;
141  rawHitCoords_[1] = vHit.getPosition();
142 
143  double sigmaU = uHit.getPositionSigma() * scaleFactorU;
144  double sigmaU_sq = sigmaU * sigmaU;
145  double sigmaV = vHit.getPositionSigma();
146  double sigmaV_sq = sigmaV * sigmaV;
147 
148  m_energyDep = 0.5 * (uHit.getCharge() + vHit.getCharge());
149 
150  rawHitCov_(0, 0) = sigmaV_sq * tan_phi * tan_phi + sigmaU_sq * one_over_cos_phi_sqr;
151  rawHitCov_(0, 1) = sigmaV_sq * tan_phi;
152  rawHitCov_(1, 0) = sigmaV_sq * tan_phi;
153  rawHitCov_(1, 1) = sigmaV_sq;
154  // Setup geometry information
156 }
157 
159 {
160  // Construct a finite detector plane and set it.
161  const SVD::SensorInfo& geometry = dynamic_cast<const SVD::SensorInfo&>(VXD::GeoCache::get(m_sensorID));
162 
163  // Construct vectors o, u, v
164  ROOT::Math::XYZVector origin = geometry.pointToGlobal(ROOT::Math::XYZVector(0, 0, 0), true);
165  ROOT::Math::XYZVector uGlobal = geometry.vectorToGlobal(ROOT::Math::XYZVector(1, 0, 0), true);
166  ROOT::Math::XYZVector vGlobal = geometry.vectorToGlobal(ROOT::Math::XYZVector(0, 1, 0), true);
167 
168  //Construct the detector plane
169  genfit::SharedPlanePtr detPlane(new genfit::DetPlane(XYZToTVector(origin), XYZToTVector(uGlobal), XYZToTVector(vGlobal),
170  new VXD::SensorPlane(m_sensorID, 20, 20)));
171  setPlane(detPlane, m_sensorID);
172 }
173 
174 TVectorD SVDRecoHit2D::applyPlanarDeformation(TVectorD rawHit, std::vector<double> planarParameters,
175  const genfit::StateOnPlane& state) const
176 {
177  // Legendre parametrization of deformation
178  auto L1 = [](double x) {return x;};
179  auto L2 = [](double x) {return (3 * x * x - 1) / 2;};
180  auto L3 = [](double x) {return (5 * x * x * x - 3 * x) / 2;};
181  auto L4 = [](double x) {return (35 * x * x * x * x - 30 * x * x + 3) / 8;};
182 
183  const SVD::SensorInfo& geometry = dynamic_cast<const SVD::SensorInfo&>(VXD::GeoCache::get(m_sensorID));
184 
185  double u = rawHit[0]; // U coordinate of hit
186  double v = rawHit[1]; // V coordinate of hit
187  double width = geometry.getWidth(v); // Width of sensor (U side)
188  double length = geometry.getLength(); // Length of sensor (V side)
189  u = u * 2 / width; // Legendre parametrization required U in (-1, 1)
190  v = v * 2 / length; // Legendre parametrization required V in (-1, 1)
191 
192  /* Planar deformation using Legendre parametrization
193  w(u, v) = L_{31} * L2(u) + L_{32} * L1(u) * L1(v) + L_{33} * L2(v) +
194  L_{41} * L3(u) + L_{42} * L2(u) * L1(v) + L_{43} * L1(u) * L2(v) + L_{44} * L3(v) +
195  L_{51} * L4(u) + L_{52} * L3(u) * L1(v) + L_{53} * L2(u) * L2(v) + L_{54} * L1(u) * L3(v) + L_{55} * L4(v); */
196  double dw =
197  planarParameters[0] * L2(u) + planarParameters[1] * L1(u) * L1(v) + planarParameters[2] * L2(v) +
198  planarParameters[3] * L3(u) + planarParameters[4] * L2(u) * L1(v) + planarParameters[5] * L1(u) * L2(v) + planarParameters[6] * L3(
199  v) +
200  planarParameters[7] * L4(u) + planarParameters[8] * L3(u) * L1(v) + planarParameters[9] * L2(u) * L2(v) + planarParameters[10] * L1(
201  u) * L3(v) + planarParameters[11] * L4(v);
202 
203  double du_dw = state.getState()[1]; // slope in U direction
204  double dv_dw = state.getState()[2]; // slope in V direction
205 
206  u = u * width / 2; // from Legendre to Local parametrization
207  v = v * length / 2; // from Legendre to Local parametrization
208 
209  TVectorD pos(2);
210 
211  pos[0] = u + dw * du_dw;
212  pos[1] = v + dw * dv_dw;
213 
214  return pos;
215 }
216 
217 std::vector<genfit::MeasurementOnPlane*> SVDRecoHit2D::constructMeasurementsOnPlane(const genfit::StateOnPlane& state) const
218 {
219  // Apply planar deformation
220  TVectorD pos = applyPlanarDeformation(rawHitCoords_, VXD::GeoCache::get(m_sensorID).getSurfaceParameters(), state);
221 
222  return std::vector<genfit::MeasurementOnPlane*>(1, new genfit::MeasurementOnPlane(pos, rawHitCov_, state.getPlane(),
223  state.getRep(), this->constructHMatrix(state.getRep())));
224 }
225 
227 {
228  return new SVDRecoHit2D(*this);
229 }
The SVD Cluster class This class stores all information about reconstructed SVD clusters.
Definition: SVDCluster.h:29
float getCharge() const
Get collected charge.
Definition: SVDCluster.h:144
bool isUCluster() const
Get the direction of strips.
Definition: SVDCluster.h:110
float getPosition(double v=0) const
Get the coordinate of reconstructed hit.
Definition: SVDCluster.h:117
float getPositionSigma() const
Get the error of the reconstructed hit coordinate.
Definition: SVDCluster.h:129
unsigned short getRawSensorID() const
Get raw sensor ID.
Definition: SVDCluster.h:105
virtual std::vector< genfit::MeasurementOnPlane * > constructMeasurementsOnPlane(const genfit::StateOnPlane &state) const override
Get deposited energy error.
TVectorD applyPlanarDeformation(TVectorD rawHit, std::vector< double > planarParameters, const genfit::StateOnPlane &state) const
Apply planar deformation of sensors.
float m_energyDep
deposited energy.
Definition: SVDRecoHit2D.h:140
unsigned short m_sensorID
Unique sensor identifier.
Definition: SVDRecoHit2D.h:135
const SVDCluster * m_uCluster
Pointer to mother uCluster.
Definition: SVDRecoHit2D.h:137
void setDetectorPlane()
Set up Detector plane information.
genfit::AbsMeasurement * clone() const override
Creating a deep copy of this hit.
SVDRecoHit2D()
Default constructor for ROOT IO.
Definition: SVDRecoHit2D.cc:24
const SVDCluster * m_vCluster
Pointer to mother vCluster.
Definition: SVDRecoHit2D.h:138
SVDRecoHit - an extended form of SVDHit containing geometry information.
Definition: SVDRecoHit.h:47
const SVDCluster * getCluster() const
Get pointer to the Cluster used when creating this RecoHit, can be nullptr if created from something ...
Definition: SVDRecoHit.h:88
Class SVDTrueHit - Records of tracks that either enter or leave the sensitive volume.
Definition: SVDTrueHit.h:33
Specific implementation of SensorInfo for SVD Sensors which provides additional sensor specific infor...
Definition: SensorInfo.h:25
static const SensorInfoBase & get(Belle2::VxdID id)
Return a reference to the SensorInfo of a given SensorID.
Definition: GeoCache.h:139
A Finite plane of one VXD Sensor.
Definition: SensorPlane.h:34
unsigned short baseType
The base integer type for VxdID.
Definition: VxdID.h:36
Contains the measurement and covariance in raw detector coordinates.
Detector plane.
Definition: DetPlane.h:59
Measured coordinates on a plane.
A state with arbitrary dimension defined in a DetPlane.
Definition: StateOnPlane.h:47
Hit object for use in TrackCand.
Definition: TrackCandHit.h:34
static constexpr auto XYZToTVector
Helper function to convert XYZVector to TVector3.
Definition: VectorUtil.h:24
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.
Defines for I/O streams used for error and debug printing.
std::shared_ptr< genfit::DetPlane > SharedPlanePtr
Shared Pointer to a DetPlane.