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 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 B2Vector3D & 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.
VXDMomentumEstimationTools & operator=(const VXDMomentumEstimationTools &)
Do not create this class.
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.
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.