Belle II Software development
SVDClusterVariables.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 <tracking/dataobjects/RecoTrack.h>
10#include <mdst/dataobjects/Track.h>
11#include <analysis/dataobjects/Particle.h>
12#include <svd/variables/SVDClusterVariables.h>
13#include <svd/dataobjects/SVDTrueHit.h>
14#include <vxd/dataobjects/VxdID.h>
15
16namespace {
17 Belle2::RecoTrack* getRecoTrack(const Belle2::Particle* particle)
18 {
19 const Belle2::Track* track = particle->getTrack();
20 if (!track)
21 return nullptr;
22 return track->getRelatedTo<Belle2::RecoTrack>();
23 }
24
25 Belle2::SVDCluster* getSVDCluster(const Belle2::RecoTrack* recoTrack, unsigned int clusterIndex)
26 {
27 if (!recoTrack) {
28 return nullptr;
29 }
30 const std::vector<Belle2::SVDCluster*> svdClusters = recoTrack->getSVDHitList();
31 if (clusterIndex >= svdClusters.size()) {
32 return nullptr;
33 }
34 return svdClusters[clusterIndex];
35 }
36
37 Belle2::SVDCluster* getSVDCluster(const Belle2::Particle* particle, unsigned int clusterIndex)
38 {
39 const Belle2::RecoTrack* recoTrack = getRecoTrack(particle);
40 return getSVDCluster(recoTrack, clusterIndex);
41 }
42}
43
44namespace Belle2::Variable {
45
46 double SVDClusterCharge(const Particle* particle, const std::vector<double>& indices)
47 {
48 if (!particle) {
49 return Const::doubleNaN;
50 }
51 if (indices.size() != 1) {
52 B2FATAL("Exactly one parameter (cluster index) is required.");
53 }
54 const auto clusterIndex = static_cast<unsigned int>(indices[0]);
55
56 SVDCluster* svdCluster = getSVDCluster(particle, clusterIndex);
57 return svdCluster ? svdCluster->getCharge() : Const::doubleNaN;
58 }
59
60 double SVDClusterSNR(const Particle* particle, const std::vector<double>& indices)
61 {
62 if (!particle) {
63 return Const::doubleNaN;
64 }
65
66 if (indices.size() != 1) {
67 B2FATAL("Exactly one parameter (cluster index) is required.");
68 }
69 const auto clusterIndex = static_cast<unsigned int>(indices[0]);
70
71 SVDCluster* svdCluster = getSVDCluster(particle, clusterIndex);
72 return svdCluster ? svdCluster->getSNR() : Const::doubleNaN;
73 }
74
75 int SVDClusterSize(const Particle* particle, const std::vector<double>& indices)
76 {
77 if (!particle) {
78 return -1;
79 }
80
81 if (indices.size() != 1) {
82 B2FATAL("Exactly one parameter (cluster index) is required.");
83 }
84 const auto clusterIndex = static_cast<unsigned int>(indices[0]);
85
86 SVDCluster* svdCluster = getSVDCluster(particle, clusterIndex);
87 return svdCluster ? svdCluster->getSize() : -1;
88 }
89
90 double SVDClusterTime(const Particle* particle, const std::vector<double>& indices)
91 {
92 if (!particle) {
93 return Const::doubleNaN;
94 }
95 if (indices.size() != 1) {
96 B2FATAL("Exactly one parameter (cluster index) is required.");
97 }
98 const auto clusterIndex = static_cast<unsigned int>(indices[0]);
99
100 SVDCluster* svdCluster = getSVDCluster(particle, clusterIndex);
101 return svdCluster ? svdCluster->getClsTime() : Const::doubleNaN;
102 }
103
104 double SVDTrackPrime(const Particle* particle, const std::vector<double>& indices)
105 {
106 if (!particle) {
107 return Const::doubleNaN;
108 }
109 if (indices.size() != 1) {
110 B2FATAL("Exactly one parameter (cluster index) is required.");
111 }
112 const auto clusterIndex = static_cast<unsigned int>(indices[0]);
113
114 const RecoTrack* recoTrack = getRecoTrack(particle);
115 if (!recoTrack) {
116 return Const::doubleNaN;
117 }
118 const SVDCluster* svdCluster = getSVDCluster(recoTrack, clusterIndex);
119 if (!svdCluster) {
120 return Const::doubleNaN;
121 }
122 const RecoHitInformation* recoHitInformation = recoTrack->getRecoHitInformation(svdCluster);
123 if (!recoHitInformation) {
124 return Const::doubleNaN;
125 }
126 try {
127 genfit::MeasuredStateOnPlane measuredState = recoTrack->getMeasuredStateOnPlaneFromRecoHit(recoHitInformation);
128 return svdCluster->isUCluster()
129 ? measuredState.getState()[1]
130 : measuredState.getState()[2];
131 } catch (const NoTrackFitResult&) {
132 B2WARNING("No track fit result available for this hit!");
133 return Const::doubleNaN;
134 }
135 }
136
137 double SVDTrackPositionErrorUnbiased(const Particle* particle, const std::vector<double>& indices)
138 {
139 if (!particle) {
140 return Const::doubleNaN;
141 }
142 if (indices.size() != 1) {
143 B2FATAL("Exactly one parameter (cluster index) is required.");
144 }
145 const auto clusterIndex = static_cast<unsigned int>(indices[0]);
146
147 const RecoTrack* recoTrack = getRecoTrack(particle);
148 if (!recoTrack) {
149 return Const::doubleNaN;
150 }
151 const SVDCluster* svdCluster = getSVDCluster(recoTrack, clusterIndex);
152 if (!svdCluster) {
153 return Const::doubleNaN;
154 }
155 const RecoHitInformation* recoHitInformation = recoTrack->getRecoHitInformation(svdCluster);
156 if (!recoHitInformation) {
157 return Const::doubleNaN;
158 }
159 const genfit::TrackPoint* trackPoint = recoTrack->getCreatedTrackPoint(recoHitInformation);
160 if (!trackPoint) {
161 return Const::doubleNaN;
162 }
163 const genfit::AbsFitterInfo* fitterInfo = trackPoint->getFitterInfo();
164 if (!fitterInfo) {
165 return Const::doubleNaN;
166 }
167 try {
168 genfit::MeasuredStateOnPlane unbiasedState = fitterInfo->getFittedState(false);
169 return svdCluster->isUCluster()
170 ? sqrt(unbiasedState.getCov()[3][3])
171 : sqrt(unbiasedState.getCov()[4][4]);
172 } catch (...) {
173 B2WARNING("Could not compute SVDTrackPositionErrorUnbiased.");
174 return Const::doubleNaN;
175 }
176 }
177
178 double SVDTruePosition(const Particle* particle, const std::vector<double>& indices)
179 {
180 if (!particle) {
181 return Const::doubleNaN;
182 }
183 if (indices.size() != 1) {
184 B2FATAL("Exactly one parameter (cluster index) is required.");
185 }
186 const auto clusterIndex = static_cast<unsigned int>(indices[0]);
187
188 SVDCluster* svdCluster = getSVDCluster(particle, clusterIndex);
189 if (!svdCluster) {
190 return Const::doubleNaN;
191 }
192
193 const auto trueHit = svdCluster->getRelatedTo<Belle2::SVDTrueHit>();
194
195 if (!trueHit) {
196 return Const::doubleNaN;
197 }
198 return svdCluster->isUCluster()
199 ? trueHit->getU()
200 : trueHit->getV();
201 }
202
203 double SVDResidual(const Particle* particle, const std::vector<double>& indices)
204 {
205 if (!particle) {
206 return Const::doubleNaN;
207 }
208 if (indices.size() != 1) {
209 B2FATAL("Exactly one parameter (cluster index) is required.");
210 }
211 const auto clusterIndex = static_cast<unsigned int>(indices[0]);
212
213 const RecoTrack* recoTrack = getRecoTrack(particle);
214 if (!recoTrack) {
215 return Const::doubleNaN;
216 }
217 const SVDCluster* svdCluster = getSVDCluster(recoTrack, clusterIndex);
218 if (!svdCluster) {
219 return Const::doubleNaN;
220 }
221 const RecoHitInformation* recoHitInformation = recoTrack->getRecoHitInformation(svdCluster);
222 if (!recoHitInformation) {
223 return Const::doubleNaN;
224 }
225 const genfit::TrackPoint* trackPoint = recoTrack->getCreatedTrackPoint(recoHitInformation);
226 if (!trackPoint) {
227 return Const::doubleNaN;
228 }
229 const genfit::AbsFitterInfo* fitterInfo = trackPoint->getFitterInfo();
230 if (!fitterInfo) {
231 return Const::doubleNaN;
232 }
233 try {
234 const TVectorD residualMeasurement = fitterInfo->getResidual(0, false).getState();
235 return residualMeasurement.GetMatrixArray()[0] * Unit::convertValueToUnit(1.0, "um");
236 } catch (...) {
237 B2WARNING("Could not get track residual.");
238 return Const::doubleNaN;
239 }
240 }
241
242 int SVDLayer(const Particle* particle, const std::vector<double>& indices)
243 {
244 if (!particle) {
245 return -1;
246 }
247 if (indices.size() != 1) {
248 B2FATAL("Exactly one parameter (cluster index) is required.");
249 }
250 const auto clusterIndex = static_cast<unsigned int>(indices[0]);
251
252 SVDCluster* svdCluster = getSVDCluster(particle, clusterIndex);
253 if (!svdCluster) {
254 return -1;
255 }
256 const VxdID vxdId = svdCluster->getSensorID();
257 return vxdId ? vxdId.getLayerNumber() : -1;
258 }
259
260 int SVDLadder(const Particle* particle, const std::vector<double>& indices)
261 {
262 if (!particle) {
263 return -1;
264 }
265 if (indices.size() != 1) {
266 B2FATAL("Exactly one parameter (cluster index) is required.");
267 }
268 const auto clusterIndex = static_cast<unsigned int>(indices[0]);
269
270 SVDCluster* svdCluster = getSVDCluster(particle, clusterIndex);
271 if (!svdCluster) {
272 return -1;
273 }
274 const VxdID vxdId = svdCluster->getSensorID();
275 return vxdId ? vxdId.getLadderNumber() : -1;
276 }
277
278 int SVDSensor(const Particle* particle, const std::vector<double>& indices)
279 {
280 if (!particle) {
281 return -1;
282 }
283 if (indices.size() != 1) {
284 B2FATAL("Exactly one parameter (cluster index) is required.");
285 }
286 const auto clusterIndex = static_cast<unsigned int>(indices[0]);
287
288 SVDCluster* svdCluster = getSVDCluster(particle, clusterIndex);
289 if (!svdCluster) {
290 return -1;
291 }
292 const VxdID vxdId = svdCluster->getSensorID();
293 return vxdId ? vxdId.getSensorNumber() : -1;
294 }
295
296 bool SVDSide(const Particle* particle, const std::vector<double>& indices)
297 {
298 if (!particle) {
299 return false;
300 }
301 if (indices.size() != 1) {
302 B2FATAL("Exactly one parameter (cluster index) is required.");
303 }
304 const auto clusterIndex = static_cast<unsigned int>(indices[0]);
305
306 SVDCluster* svdCluster = getSVDCluster(particle, clusterIndex);
307 return svdCluster ? svdCluster->isUCluster() : false;
308 }
309
310 VARIABLE_GROUP("SVD Validation");
311
312 REGISTER_VARIABLE("SVDClusterCharge(i)", SVDClusterCharge,
313 "Returns the charge of the i-th SVD cluster related to the Particle.");
314 REGISTER_VARIABLE("SVDClusterSNR(i)", SVDClusterSNR,
315 "Returns the SNR of the i-th SVD cluster related to the Particle.");
316 REGISTER_VARIABLE("SVDClusterSize(i)", SVDClusterSize,
317 "Returns the size of the i-th SVD cluster related to the Particle.");
318 REGISTER_VARIABLE("SVDClusterTime(i)", SVDClusterTime,
319 "Returns the time of the i-th SVD cluster related to the Particle.");
320 REGISTER_VARIABLE("SVDTrackPrime(i)", SVDTrackPrime,
321 "Returns the tan of the incident angle projected on U/V of the i-th SVD cluster related to the Particle.");
322 REGISTER_VARIABLE("SVDResidual(i)", SVDResidual,
323 "Returns the track residual of the i-th SVD cluster related to the Particle.");
324 REGISTER_VARIABLE("SVDTrackPositionErrorUnbiased(i)", SVDTrackPositionErrorUnbiased,
325 "Returns the unbiased track position error of the i-th SVD cluster related to the Particle.");
326 REGISTER_VARIABLE("SVDTruePosition(i)", SVDTruePosition,
327 "Returns the true position of the i-th SVD cluster related to the Particle.");
328 REGISTER_VARIABLE("SVDLayer(i)", SVDLayer,
329 "Returns the layer number of the i-th SVD cluster related to the Particle. If no SVD cluster is found, returns -1.");
330 REGISTER_VARIABLE("SVDLadder(i)", SVDLadder,
331 "Returns the ladder number of the i-th SVD cluster related to the Particle. If no SVD cluster is found, returns -1.");
332 REGISTER_VARIABLE("SVDSensor(i)", SVDSensor,
333 "Returns the sensor number of the i-th SVD cluster related to the Particle. If no SVD cluster is found, returns -1.");
334 REGISTER_VARIABLE("SVDSide(i)", SVDSide,
335 "Returns true if the i-th SVD cluster related to the Particle is a U cluster.");
336}
static const double doubleNaN
quiet_NaN
Definition Const.h:703
Class to store reconstructed particles.
Definition Particle.h:76
This is the Reconstruction Event-Data Model Track.
Definition RecoTrack.h:79
std::vector< Belle2::RecoTrack::UsedSVDHit * > getSVDHitList() const
Return an unsorted list of svd hits.
Definition RecoTrack.h:452
The SVD Cluster class This class stores all information about reconstructed SVD clusters.
Definition SVDCluster.h:29
Class that bundles various TrackFitResults.
Definition Track.h:25
static double convertValueToUnit(double value, const std::string &unitString)
Converts a floating point value from the standard framework unit to the given unit.
Definition UnitConst.cc:138
double sqrt(double a)
sqrt for double
Definition beamHelpers.h:28