Belle II Software  release-08-01-10
VXDMomentumEstimationTools.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 <tracking/spacePointCreation/SpacePoint.h>
12 #include <vxd/dataobjects/VxdID.h>
13 #include <framework/geometry/B2Vector3.h>
14 #include <framework/dataobjects/Helix.h>
15 #include <vxd/geometry/GeoCache.h>
16 #include <vxd/geometry/SensorInfoBase.h>
17 #include <algorithm>
18 #include <cmath>
19 #include <framework/logging/Logger.h>
20 
21 
22 namespace Belle2 {
27  class SVDCluster;
28  class PXDCluster;
29 
31  template <class ClusterType>
33 
34  private:
41 
42  public:
45  {
46  static VXDMomentumEstimationTools instance;
47  return instance;
48  }
49 
51  double getDEDX(const ClusterType& cluster, const ROOT::Math::XYZVector& momentum, const ROOT::Math::XYZVector& position,
52  short charge) const
53  {
54 
55  const Helix trajectory(position, momentum, charge, 1.5);
56  const double calibratedCharge = getCalibratedCharge(cluster);
57  const double pathLength = getPathLength(cluster, trajectory);
58 
59  return calibratedCharge / pathLength;
60  }
61 
63  double getDEDXWithThickness(const ClusterType& cluster) const
64  {
65  const double calibratedCharge = getCalibratedCharge(cluster);
66  const double pathLength = getThicknessOfCluster(cluster);
67 
68  return calibratedCharge / pathLength;
69  }
70 
72  double getThicknessOfCluster(const ClusterType& cluster) const
73  {
74  const VxdID& vxdID = cluster.getSensorID();
75  const VXD::SensorInfoBase& sensorInfoBase = VXD::GeoCache::getInstance().getSensorInfo(vxdID);
76  return sensorInfoBase.getThickness();
77  }
78 
80  double getWidthOfCluster(const ClusterType& cluster) const
81  {
82  const VxdID& vxdID = cluster.getSensorID();
83  const VXD::SensorInfoBase& sensorInfoBase = VXD::GeoCache::getInstance().getSensorInfo(vxdID);
84  return sensorInfoBase.getWidth();
85  }
86 
88  double getLengthOfCluster(const ClusterType& cluster) const
89  {
90  const VxdID& vxdID = cluster.getSensorID();
91  const VXD::SensorInfoBase& sensorInfoBase = VXD::GeoCache::getInstance().getSensorInfo(vxdID);
92  return sensorInfoBase.getLength();
93  }
94 
96  double getRadiusOfCluster(const ClusterType& cluster) const
97  {
98  const SpacePoint* spacePoint = cluster.template getRelated<SpacePoint>("SpacePoints");
99 
100  double radius = 0;
101  if (spacePoint == nullptr) {
102  // Fallback function
103  VxdID vxdID = cluster.getSensorID();
104  VxdID::baseType layer = vxdID.getLayerNumber();
105  radius = m_layerPositions[layer - 1] / 100.0;
106  B2WARNING("Could not determine SpacePoint for this cluster. Falling back to geometrical information.");
107  } else {
108  // The positions is the one with w = 0 which is the one on the lowest detector plane.
109  radius = spacePoint->getPosition().Perp();
110  }
111  return radius;
112  }
113 
115  VxdID::baseType getLayerOfCluster(const ClusterType& cluster) const
116  {
117  VxdID vxdID = cluster.getSensorID();
118  VxdID::baseType layer = vxdID.getLayerNumber();
119  return layer;
120  }
121 
123  VxdID::baseType getLadderOfCluster(const ClusterType& cluster) const
124  {
125  VxdID vxdID = cluster.getSensorID();
126  VxdID::baseType ladder = vxdID.getLadderNumber();
127  return ladder;
128  }
129 
131  VxdID::baseType getSensorNumberOfCluster(const ClusterType& cluster) const
132  {
133  VxdID vxdID = cluster.getSensorID();
134  VxdID::baseType sensorNumber = vxdID.getSensorNumber();
135  return sensorNumber;
136  }
137 
139  VxdID::baseType getSegmentNumberOfCluster(const ClusterType& cluster) const
140  {
141  VxdID vxdID = cluster.getSensorID();
142  VxdID::baseType segmentNumber = vxdID.getSegmentNumber();
143  return segmentNumber;
144  }
145 
149  double getCalibratedCharge(const ClusterType& cluster) const
150  {
151  const double charge = cluster.getCharge();
152  const double calibration = getCalibration();
153 
154  return calibration * charge;
155  }
156 
159  ROOT::Math::XYZVector getEntryMomentumOfMCParticle(const ClusterType&) const
160  {
161  B2FATAL("Can not deal with this cluster type!");
162  return ROOT::Math::XYZVector();
163  }
164 
167  ROOT::Math::XYZVector getEntryPositionOfMCParticle(const ClusterType&) const
168  {
169  B2FATAL("Can not deal with this cluster type!");
170  return ROOT::Math::XYZVector();
171  }
172 
179  double getPathLength(const ClusterType& cluster, const Helix& trajectory) const
180  {
181  // This is not quite correct but we can not do better without doing an extrapolation with material effects.
182  // If the distance_3D is nan, it means that the helix does not reach into the cluster or curls that much
183  // that it does not reach the far end of the cluster. The first case is strange
184  // because the track is associated with the cluster (so it should normally reach it). The second case should be
185  // really rare (because the clusters are that thin), but we have to deal with it.
186  // There is also the possibility that the track curls that much that it interacts with the same sensor twice.
187  // This can not be handled properly in this stage.
188 
189  const double thickness = getThicknessOfCluster(cluster);
190  const double radius = getRadiusOfCluster(cluster);
191  const double width = getWidthOfCluster(cluster);
192  const double length = getLengthOfCluster(cluster);
193 
194  const double perp_s_at_cluster_entry = trajectory.getArcLength2DAtCylindricalR(radius);
195 
196  if (std::isnan(perp_s_at_cluster_entry)) {
197  // This case is really strange. I do not know how to deal with it probably.
198  return thickness;
199  }
200 
201  const ROOT::Math::XYZVector& position_at_inner_radius = trajectory.getPositionAtArcLength2D(perp_s_at_cluster_entry);
202 
203  const double perp_s_at_cluster_exit = trajectory.getArcLength2DAtCylindricalR(radius + thickness);
204 
205  if (std::isnan(perp_s_at_cluster_exit)) {
206  return std::min(width, length);
207  }
208 
209  const ROOT::Math::XYZVector& position_at_outer_radius = trajectory.getPositionAtArcLength2D(perp_s_at_cluster_exit);
210 
211  const double distance_3D = (position_at_outer_radius - position_at_inner_radius).R();
212 
213  return distance_3D;
214  }
215 
216  private:
218  const double m_layerPositions[6] = {1.42, 2.18, 3.81, 8.0, 10.51, 13.51};
219 
221  double getCalibration() const
222  {
223  return 1;
224  }
225  };
226 
228  template<>
230 
232  template <>
234 
236  template <>
238 
240  template <>
242 
244  template <>
247 }
double R
typedef autogenerated by FFTW
DataType Perp() const
The transverse component (R in cylindrical coordinate system).
Definition: B2Vector3.h:200
Helix parameter class.
Definition: Helix.h:48
The PXD Cluster class This class stores all information about reconstructed PXD clusters The position...
Definition: PXDCluster.h:30
The SVD Cluster class This class stores all information about reconstructed SVD clusters.
Definition: SVDCluster.h:29
SpacePoint typically is build from 1 PXDCluster or 1-2 SVDClusters.
Definition: SpacePoint.h:42
const B2Vector3< double > & getPosition() const
return the position vector in global coordinates
Definition: SpacePoint.h:138
Tools needed for the VXD momentum estimation to, e.g.
double getCalibratedCharge(const ClusterType &cluster) const
Return the charge of the cluster (in ADC count) calibrated with a factor of ~0.6 for pxd hits.
double getLengthOfCluster(const ClusterType &cluster) const
Return the thickness of a cluster.
VxdID::baseType getSegmentNumberOfCluster(const ClusterType &cluster) const
Return the segment number of the cluster.
double getThicknessOfCluster(const ClusterType &cluster) const
Return the thickness of a cluster.
VXDMomentumEstimationTools()
Do not create this class.
static const VXDMomentumEstimationTools & getInstance()
Use this class as singleton.
ROOT::Math::XYZVector getEntryMomentumOfMCParticle(const ClusterType &) const
Return the momentum of the simulated MCParticle at this cluster (by using the TrueHit associated with...
const double m_layerPositions[6]
the layer positions in the case we do not have a SpacePoint we can look at.
double getRadiusOfCluster(const ClusterType &cluster) const
Returns the distance from the interaction point to the cluster in the r-phi-plane.
VXDMomentumEstimationTools & operator=(const VXDMomentumEstimationTools &)
Do not create this class.
double getDEDX(const ClusterType &cluster, const ROOT::Math::XYZVector &momentum, const ROOT::Math::XYZVector &position, short charge) const
Main function: return dEdX for a cluster and the given momentum, position and charge seeds.
double getCalibration() const
For SVD the calibration is 1, for PXD (see below) it is ~0.6.
VxdID::baseType getLayerOfCluster(const ClusterType &cluster) const
Return the layer of the cluster.
ROOT::Math::XYZVector getEntryPositionOfMCParticle(const ClusterType &) const
Return the entry position of the simulated MCParticle at this cluster (by using the TrueHit associate...
double getDEDXWithThickness(const ClusterType &cluster) const
Return dEdX but not with dX = path length but with dX = thickness of cluster.
VXDMomentumEstimationTools(const VXDMomentumEstimationTools &)
Do not create this class.
VxdID::baseType getLadderOfCluster(const ClusterType &cluster) const
Return the ladder of the cluster.
VxdID::baseType getSensorNumberOfCluster(const ClusterType &cluster) const
Return the sensor number of the cluster.
double getPathLength(const ClusterType &cluster, const Helix &trajectory) const
Return the path length of a particle with the given helix that goes through the cluster.
double getWidthOfCluster(const ClusterType &cluster) const
Return the thickness of a cluster.
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a referecne to the SensorInfo of a given SensorID.
Definition: GeoCache.cc:67
static GeoCache & getInstance()
Return a reference to the singleton instance.
Definition: GeoCache.cc:214
Base class to provide Sensor Information for PXD and SVD.
double getWidth(double v=0) const
Return the width of the sensor.
double getThickness() const
Return the thickness of the sensor.
double getLength() const
Return the length 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 getSegmentNumber() const
Get the sensor segment.
Definition: VxdID.h:102
unsigned short baseType
The base integer type for VxdID.
Definition: VxdID.h:36
baseType getLadderNumber() const
Get the ladder id.
Definition: VxdID.h:98
baseType getLayerNumber() const
Get the layer id.
Definition: VxdID.h:96
Abstract base class for different kinds of events.