Belle II Software  release-08-01-10
PXDRecoHit.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 <pxd/reconstruction/PXDRecoHit.h>
12 #include <pxd/reconstruction/PXDClusterPositionEstimator.h>
13 #include <pxd/reconstruction/PXDGainCalibrator.h>
14 #include <pxd/dataobjects/PXDTrueHit.h>
15 #include <pxd/dataobjects/PXDCluster.h>
16 #include <pxd/geometry/SensorInfo.h>
17 #include <vxd/geometry/SensorPlane.h>
18 #include <vxd/geometry/GeoCache.h>
19 
20 #include <genfit/DetPlane.h>
21 #include <TVector3.h>
22 #include <TRandom.h>
23 
24 using namespace std;
25 using namespace Belle2;
26 
27 PXDRecoHit::PXDRecoHit():
28  genfit::PlanarMeasurement(HIT_DIMENSIONS), m_sensorID(0), m_trueHit(0), m_cluster(0),
29  m_energyDep(0)//, m_energyDepError(0)
30 {}
31 
32 PXDRecoHit::PXDRecoHit(const PXDTrueHit* hit, const genfit::TrackCandHit*, float sigmaU, float sigmaV):
33  genfit::PlanarMeasurement(HIT_DIMENSIONS), m_sensorID(0), m_trueHit(hit), m_cluster(0),
34  m_energyDep(0)//, m_energyDepError(0)
35 {
36  if (!gRandom) B2FATAL("gRandom not initialized, please set up gRandom first");
37 
38  // Set the sensor UID
39  m_sensorID = hit->getSensorID();
40 
41  //If no error is given, estimate the error by dividing the pixel size by sqrt(12)
42  if (sigmaU < 0 || sigmaV < 0) {
43  const PXD::SensorInfo& geometry = dynamic_cast<const PXD::SensorInfo&>(VXD::GeoCache::get(m_sensorID));
44  sigmaU = geometry.getUPitch(hit->getV()) / sqrt(12);
45  sigmaV = geometry.getVPitch(hit->getV()) / sqrt(12);
46  }
47 
48  // Set positions
49  rawHitCoords_(0) = gRandom->Gaus(hit->getU(), sigmaU);
50  rawHitCoords_(1) = gRandom->Gaus(hit->getV(), sigmaV);
51  // Set the error covariance matrix
52  rawHitCov_(0, 0) = sigmaU * sigmaU;
53  rawHitCov_(0, 1) = 0;
54  rawHitCov_(1, 0) = 0;
55  rawHitCov_(1, 1) = sigmaV * sigmaV;
56  // Set physical parameters
57  m_energyDep = hit->getEnergyDep();
58  // Setup geometry information
60 }
61 
62 PXDRecoHit::PXDRecoHit(const PXDCluster* hit, float sigmaU, float sigmaV, float covUV):
63  genfit::PlanarMeasurement(HIT_DIMENSIONS), m_sensorID(0), m_trueHit(0), m_cluster(hit),
64  m_energyDep(0)//, m_energyDepError(0)
65 {
66  // Set the sensor UID
67  m_sensorID = hit->getSensorID();
68  // Set positions
69  rawHitCoords_(0) = hit->getU();
70  rawHitCoords_(1) = hit->getV();
71  // Set the error covariance matrix
72  rawHitCov_(0, 0) = sigmaU * sigmaU;
73  rawHitCov_(0, 1) = covUV;
74  rawHitCov_(1, 0) = covUV;
75  rawHitCov_(1, 1) = sigmaV * sigmaV;
76  // Set physical parameters
77  const PXD::SensorInfo& SensorInfo = dynamic_cast<const PXD::SensorInfo&>(VXD::GeoCache::get(m_sensorID));
78  auto ADUToEnergy = PXD::PXDGainCalibrator::getInstance().getADUToEnergy(m_sensorID, SensorInfo.getUCellID(hit->getU()),
79  SensorInfo.getVCellID(hit->getV()));
80  m_energyDep = hit->getCharge() * ADUToEnergy;
81  //m_energyDepError = 0;
82  // Setup geometry information
84 }
85 
86 
88  genfit::PlanarMeasurement(HIT_DIMENSIONS), m_sensorID(0), m_trueHit(0), m_cluster(hit),
89  m_energyDep(0)//, m_energyDepError(0)
90 {
91  // Set the sensor UID
92  m_sensorID = hit->getSensorID();
93  // Set positions
94  rawHitCoords_(0) = hit->getU();
95  rawHitCoords_(1) = hit->getV();
96  // Set the error covariance matrix
97  rawHitCov_(0, 0) = hit->getUSigma() * hit->getUSigma();
98  rawHitCov_(0, 1) = hit->getRho() * hit->getUSigma() * hit->getVSigma();
99  rawHitCov_(1, 0) = hit->getRho() * hit->getUSigma() * hit->getVSigma();
100  rawHitCov_(1, 1) = hit->getVSigma() * hit->getVSigma();
101  // Set physical parameters
102  const PXD::SensorInfo& SensorInfo = dynamic_cast<const PXD::SensorInfo&>(VXD::GeoCache::get(m_sensorID));
103  auto ADUToEnergy = PXD::PXDGainCalibrator::getInstance().getADUToEnergy(m_sensorID, SensorInfo.getUCellID(hit->getU()),
104  SensorInfo.getVCellID(hit->getV()));
105  m_energyDep = hit->getCharge() * ADUToEnergy;
106  //m_energyDepError = 0;
107  // Setup geometry information
109 }
110 
112 {
113  return new PXDRecoHit(*this);
114 }
115 
116 
118 {
119  // Construct a finite detector plane and set it.
120  const PXD::SensorInfo& geometry = dynamic_cast<const PXD::SensorInfo&>(VXD::GeoCache::get(m_sensorID));
121 
122  // Construct vectors o, u, v
123  ROOT::Math::XYZVector uLocal(1, 0, 0);
124  ROOT::Math::XYZVector vLocal(0, 1, 0);
125  ROOT::Math::XYZVector origin = geometry.pointToGlobal(ROOT::Math::XYZVector(0, 0, 0), true);
126  ROOT::Math::XYZVector uGlobal = geometry.vectorToGlobal(uLocal, true);
127  ROOT::Math::XYZVector vGlobal = geometry.vectorToGlobal(vLocal, true);
128 
129  //Construct the detector plane
130  VXD::SensorPlane* finitePlane = new VXD::SensorPlane(m_sensorID, 20.0, 20.0);
131  genfit::SharedPlanePtr detPlane(new genfit::DetPlane(XYZToTVector(origin), XYZToTVector(uGlobal), XYZToTVector(vGlobal),
132  finitePlane));
133  setPlane(detPlane, m_sensorID);
134 }
135 
136 
138 {
139  // We need an associated cluster
140  if (this->getCluster()) {
141  // Likelyhood depends on the fitted incidence angles into the sensor
142  const TVectorD& state5 = state.getState();
143  return PXD::PXDClusterPositionEstimator::getInstance().getShapeLikelyhood(*this->getCluster(), state5[1], state5[2]);
144  }
145  // If we reach here, we can do no better than return zero
146  return 0;
147 }
148 
149 TVectorD PXDRecoHit::applyPlanarDeformation(TVectorD hitCoords, std::vector<double> planarParameters,
150  const genfit::StateOnPlane& state) const
151 {
152  // Legendre parametrization of deformation
153  auto L1 = [](double x) {return x;};
154  auto L2 = [](double x) {return (3 * x * x - 1) / 2;};
155  auto L3 = [](double x) {return (5 * x * x * x - 3 * x) / 2;};
156  auto L4 = [](double x) {return (35 * x * x * x * x - 30 * x * x + 3) / 8;};
157 
158  const PXD::SensorInfo& geometry = dynamic_cast<const PXD::SensorInfo&>(VXD::GeoCache::get(m_sensorID));
159 
160  double u = hitCoords[0];
161  double v = hitCoords[1];
162  double width = geometry.getWidth(v); // Width of sensor (U side)
163  double length = geometry.getLength(); // Length of sensor (V side)
164  u = u * 2 / width; // Legendre parametrization required U in (-1, 1)
165  v = v * 2 / length; // Legendre parametrization required V in (-1, 1)
166 
167  /* Planar deformation using Legendre parametrization
168  w(u, v) = L_{31} * L2(u) + L_{32} * L1(u) * L1(v) + L_{33} * L2(v) +
169  L_{41} * L3(u) + L_{42} * L2(u) * L1(v) + L_{43} * L1(u) * L2(v) + L_{44} * L3(v) +
170  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); */
171  double dw =
172  planarParameters[0] * L2(u) + planarParameters[1] * L1(u) * L1(v) + planarParameters[2] * L2(v) +
173  planarParameters[3] * L3(u) + planarParameters[4] * L2(u) * L1(v) + planarParameters[5] * L1(u) * L2(v) + planarParameters[6] * L3(
174  v) +
175  planarParameters[7] * L4(u) + planarParameters[8] * L3(u) * L1(v) + planarParameters[9] * L2(u) * L2(v) + planarParameters[10] * L1(
176  u) * L3(v) + planarParameters[11] * L4(v);
177 
178  double du_dw = state.getState()[1]; // slope in U direction
179  double dv_dw = state.getState()[2]; // slope in V direction
180 
181  u = u * width / 2; // from Legendre to Local parametrization
182  v = v * length / 2; // from Legendre to Local parametrization
183 
184  TVectorD pos(2);
185 
186  pos[0] = u + dw * du_dw;
187  pos[1] = v + dw * dv_dw;
188 
189  return pos;
190 }
191 
192 std::vector<genfit::MeasurementOnPlane*> PXDRecoHit::constructMeasurementsOnPlane(const genfit::StateOnPlane& state) const
193 {
194  // Track-based update only takes place when the RecoHit has an associated cluster
195  if (this->getCluster()) {
196  // Check if we can correct position coordinates based on track info
197  const TVectorD& state5 = state.getState();
198  auto offset = PXD::PXDClusterPositionEstimator::getInstance().getClusterOffset(*this->getCluster(), state5[1], state5[2]);
199 
200  if (offset != nullptr) {
201  // Found a valid offset, lets apply it
202  const Belle2::VxdID& sensorID = (*this->getCluster()).getSensorID();
203  const Belle2::PXD::SensorInfo& Info = dynamic_cast<const Belle2::PXD::SensorInfo&>(VXD::GeoCache::get(sensorID));
204  double posU = Info.getUCellPosition((*this->getCluster()).getUStart());
205  double posV = Info.getVCellPosition((*this->getCluster()).getVStart());
206 
207  TVectorD hitCoords(2);
208  hitCoords(0) = posU + offset->getU();
209  hitCoords(1) = posV + offset->getV();
210  TMatrixDSym hitCov(2);
211  hitCov(0, 0) = offset->getUSigma2();
212  hitCov(0, 1) = offset->getUVCovariance();
213  hitCov(1, 0) = offset->getUVCovariance();
214  hitCov(1, 1) = offset->getVSigma2();
215 
216  // Apply planar deformation
217  TVectorD pos = applyPlanarDeformation(hitCoords, VXD::GeoCache::get(m_sensorID).getSurfaceParameters(), state);
218 
219  return std::vector<genfit::MeasurementOnPlane*>(1, new genfit::MeasurementOnPlane(
220  pos, hitCov, state.getPlane(), state.getRep(), this->constructHMatrix(state.getRep())
221  ));
222  }
223  }
224 
225  // Apply planar deformation
226  TVectorD pos = applyPlanarDeformation(rawHitCoords_, VXD::GeoCache::get(m_sensorID).getSurfaceParameters(), state);
227 
228  // If we reach here, we can do no better than what we have
229  return std::vector<genfit::MeasurementOnPlane*>(1, new genfit::MeasurementOnPlane(
230  pos, rawHitCov_, state.getPlane(), state.getRep(), this->constructHMatrix(state.getRep())
231  ));
232 }
233 
234 
235 
The PXD Cluster class This class stores all information about reconstructed PXD clusters The position...
Definition: PXDCluster.h:30
float getShapeLikelyhood(const genfit::StateOnPlane &state) const
Get deposited energy error.
Definition: PXDRecoHit.cc:137
virtual std::vector< genfit::MeasurementOnPlane * > constructMeasurementsOnPlane(const genfit::StateOnPlane &state) const override
Methods that actually interface to Genfit.
Definition: PXDRecoHit.cc:192
float m_energyDep
transient member (not written out during streaming)
Definition: PXDRecoHit.h:141
unsigned short m_sensorID
Unique sensor identifier.
Definition: PXDRecoHit.h:136
const PXDCluster * getCluster() const
Get pointer to the Cluster used when creating this RecoHit, can be NULL if created from something els...
Definition: PXDRecoHit.h:106
PXDRecoHit()
Default constructor for ROOT IO.
Definition: PXDRecoHit.cc:27
TVectorD applyPlanarDeformation(TVectorD hitCoords, std::vector< double > planarParameters, const genfit::StateOnPlane &state) const
Apply planar deformation of sensors.
Definition: PXDRecoHit.cc:149
void setDetectorPlane()
Set up Detector plane information.
Definition: PXDRecoHit.cc:117
VxdID getSensorID() const
Get the compact ID.
Definition: PXDRecoHit.h:101
genfit::AbsMeasurement * clone() const override
Creating a deep copy of this hit.
Definition: PXDRecoHit.cc:111
Class PXDTrueHit - Records of tracks that either enter or leave the sensitive volume.
Definition: PXDTrueHit.h:31
static PXDClusterPositionEstimator & getInstance()
Main (and only) way to access the PXDClusterPositionEstimator.
const PXDClusterOffsetPar * getClusterOffset(const PXDCluster &cluster, double tu, double tv) const
Return pointer to cluster offsets, can be nullptr.
float getShapeLikelyhood(const PXDCluster &cluster, double tu, double tv) const
Return cluster shape likelyhood.
float getADUToEnergy(VxdID id, unsigned int uid, unsigned int vid) const
Get conversion factor from ADU to energy.
static PXDGainCalibrator & getInstance()
Main (and only) way to access the PXDGainCalibrator.
Specific implementation of SensorInfo for PXD Sensors which provides additional pixel specific inform...
Definition: SensorInfo.h:23
static const SensorInfoBase & get(Belle2::VxdID id)
Return a reference to the SensorInfo of a given SensorID.
Definition: GeoCache.h:139
double getVCellPosition(int vID) const
Return the position of a specific strip/pixel in v direction.
double getUCellPosition(int uID, int vID=-1) const
Return the position of a specific strip/pixel in u direction.
int getVCellID(double v, bool clamp=false) const
Return the corresponding pixel/strip ID of a given v coordinate.
int getUCellID(double u, double v=0, bool clamp=false) const
Return the corresponding pixel/strip ID of a given u coordinate.
A Finite plane of one VXD Sensor.
Definition: SensorPlane.h:34
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
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.