Belle II Software development
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
22namespace 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 static double getDEDXWithThickness(const ClusterType& cluster)
64 {
65 const double calibratedCharge = getCalibratedCharge(cluster);
66 const double pathLength = getThicknessOfCluster(cluster);
67
68 return calibratedCharge / pathLength;
69 }
70
72 static double getThicknessOfCluster(const ClusterType& cluster)
73 {
74 const VxdID& vxdID = cluster.getSensorID();
75 const VXD::SensorInfoBase& sensorInfoBase = VXD::GeoCache::getInstance().getSensorInfo(vxdID);
76 return sensorInfoBase.getThickness();
77 }
78
80 static double getWidthOfCluster(const ClusterType& cluster)
81 {
82 const VxdID& vxdID = cluster.getSensorID();
83 const VXD::SensorInfoBase& sensorInfoBase = VXD::GeoCache::getInstance().getSensorInfo(vxdID);
84 return sensorInfoBase.getWidth();
85 }
86
88 static double getLengthOfCluster(const ClusterType& cluster)
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 static VxdID::baseType getLayerOfCluster(const ClusterType& cluster)
116 {
117 VxdID vxdID = cluster.getSensorID();
118 VxdID::baseType layer = vxdID.getLayerNumber();
119 return layer;
120 }
121
123 static VxdID::baseType getLadderOfCluster(const ClusterType& cluster)
124 {
125 VxdID vxdID = cluster.getSensorID();
126 VxdID::baseType ladder = vxdID.getLadderNumber();
127 return ladder;
128 }
129
131 static VxdID::baseType getSensorNumberOfCluster(const ClusterType& cluster)
132 {
133 VxdID vxdID = cluster.getSensorID();
134 VxdID::baseType sensorNumber = vxdID.getSensorNumber();
135 return sensorNumber;
136 }
137
139 static VxdID::baseType getSegmentNumberOfCluster(const ClusterType& cluster)
140 {
141 VxdID vxdID = cluster.getSensorID();
142 VxdID::baseType segmentNumber = vxdID.getSegmentNumber();
143 return segmentNumber;
144 }
145
149 static double getCalibratedCharge(const ClusterType& cluster)
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 static double getCalibration()
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 B2Vector3D & getPosition() const
return the position vector in global coordinates
Definition SpacePoint.h:138
VXDMomentumEstimationTools()
Do not create this class.
static double getLengthOfCluster(const ClusterType &cluster)
Return the thickness of a cluster.
static const VXDMomentumEstimationTools & getInstance()
Use this class as singleton.
VXDMomentumEstimationTools & operator=(const VXDMomentumEstimationTools &)
Do not create this class.
static double getThicknessOfCluster(const ClusterType &cluster)
Return the thickness of a cluster.
static double getWidthOfCluster(const ClusterType &cluster)
Return the thickness of a cluster.
ROOT::Math::XYZVector getEntryMomentumOfMCParticle(const ClusterType &) const
Return the momentum of the simulated MCParticle at this cluster (by using the TrueHit associated with...
static VxdID::baseType getSensorNumberOfCluster(const ClusterType &cluster)
Return the sensor number of the cluster.
const double m_layerPositions[6]
the layer positions in the case we do not have a SpacePoint we can look at.
static double getCalibratedCharge(const ClusterType &cluster)
Return the charge of the cluster (in ADC count) calibrated with a factor of ~0.6 for pxd hits.
double getRadiusOfCluster(const ClusterType &cluster) const
Returns the distance from the interaction point to the cluster in the r-phi-plane.
static VxdID::baseType getLadderOfCluster(const ClusterType &cluster)
Return the ladder of the cluster.
static double getDEDXWithThickness(const ClusterType &cluster)
Return dEdX but not with dX = path length but with dX = thickness of cluster.
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.
static VxdID::baseType getSegmentNumberOfCluster(const ClusterType &cluster)
Return the segment number 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...
static double getCalibration()
For SVD the calibration is 1, for PXD (see below) it is ~0.6.
VXDMomentumEstimationTools(const VXDMomentumEstimationTools &)
Do not create this class.
static VxdID::baseType getLayerOfCluster(const ClusterType &cluster)
Return the layer 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.
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a reference 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:32
baseType getSensorNumber() const
Get the sensor id.
Definition VxdID.h:99
baseType getSegmentNumber() const
Get the sensor segment.
Definition VxdID.h:101
unsigned short baseType
The base integer type for VxdID.
Definition VxdID.h:35
baseType getLadderNumber() const
Get the ladder id.
Definition VxdID.h:97
baseType getLayerNumber() const
Get the layer id.
Definition VxdID.h:95
Abstract base class for different kinds of events.