Belle II Software development
KLMClusterVariables.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/* Own header. */
10#include <analysis/variables/KLMClusterVariables.h>
11
12// include VariableManager
13#include <analysis/VariableManager/Manager.h>
14
15/* Analysis headers. */
16#include <analysis/dataobjects/Particle.h>
17#include <analysis/utility/PCmsLabTransform.h>
18#include <analysis/utility/DetectorSurface.h>
19
20/* Basf2 headers. */
21#include <framework/datastore/StoreArray.h>
22#include <framework/dataobjects/Helix.h>
23#include <framework/gearbox/Const.h>
24#include <framework/geometry/VectorUtil.h>
25#include <mdst/dataobjects/ECLCluster.h>
26#include <mdst/dataobjects/KlId.h>
27#include <mdst/dataobjects/KLMCluster.h>
28#include <mdst/dataobjects/Track.h>
29#include <mdst/dataobjects/TrackFitResult.h>
30
31/* ROOT headers. */
32#include <Math/Vector3D.h>
33#include <Math/Vector4D.h>
34#include <Math/VectorUtil.h>
35
36/* C++ headers. */
37#include <cmath>
38
39using namespace std;
40
41namespace Belle2::Variable {
42
43 double klmClusterKlId(const Particle* particle)
44 {
45 const KLMCluster* cluster = particle->getKLMCluster();
46 if (!cluster) {
47 return Const::doubleNaN;
48 }
49 const KlId* klid = cluster->getRelatedTo<KlId>();
50 if (!klid) {
51 return Const::doubleNaN;
52 }
53 return klid->getKlId();
54 }
55
56 int klmClusterBelleTrackFlag(const Particle* particle)
57 {
58 const float angle = 0.24;
59 const KLMCluster* cluster = particle->getKLMCluster();
60 if (!cluster) {
61 return 0;
62 }
63 const ROOT::Math::XYZVector& pos = cluster->getClusterPosition();
64 StoreArray<TrackFitResult> tracks;
65 for (const TrackFitResult& track : tracks) {
66 const ROOT::Math::XYZVector& trackPos = track.getPosition();
67 if (ROOT::Math::VectorUtil::Angle(trackPos, pos) < angle) {
68 return 1;
69 }
70 }
71 return 0;
72 }
73
74 int klmClusterBelleECLFlag(const Particle* particle)
75 {
76 const float angle = 0.24;
77 const KLMCluster* klmCluster = particle->getKLMCluster();
78 if (!klmCluster) {
79 return 0;
80 }
81 const ROOT::Math::XYZVector& klmClusterPos = klmCluster->getClusterPosition();
82 StoreArray<ECLCluster> eclClusters;
83 for (const ECLCluster& eclCluster : eclClusters) {
84 const ROOT::Math::XYZVector& eclClusterPos = eclCluster.getClusterPosition();
85 if (ROOT::Math::VectorUtil::Angle(eclClusterPos, klmClusterPos) < angle) {
86 return 1;
87 }
88 }
89 return 0;
90 }
91
92 double klmClusterTiming(const Particle* particle)
93 {
94 const KLMCluster* cluster = particle->getKLMCluster();
95 if (!cluster) {
96 return Const::doubleNaN;
97 }
98 return cluster->getTime();
99 }
100
101
102 double klmClusterPositionX(const Particle* particle)
103 {
104 const KLMCluster* cluster = particle->getKLMCluster();
105 if (!cluster) {
106 return Const::doubleNaN;
107 }
108 return cluster->getClusterPosition().X();
109 }
110
111
112 double klmClusterPositionY(const Particle* particle)
113 {
114 const KLMCluster* cluster = particle->getKLMCluster();
115 if (!cluster) {
116 return Const::doubleNaN;
117 }
118 return cluster->getClusterPosition().Y();
119 }
120
121
122 double klmClusterPositionZ(const Particle* particle)
123 {
124 const KLMCluster* cluster = particle->getKLMCluster();
125 if (!cluster) {
126 return Const::doubleNaN;
127 }
128 return cluster->getClusterPosition().Z();
129 }
130
131
132 double klmClusterInnermostLayer(const Particle* particle)
133 {
134 const KLMCluster* cluster = particle->getKLMCluster();
135 if (!cluster) {
136 return Const::doubleNaN;
137 }
138 return cluster->getInnermostLayer();
139 }
140
141
142 double klmClusterLayers(const Particle* particle)
143 {
144 const KLMCluster* cluster = particle->getKLMCluster();
145 if (!cluster) {
146 return Const::doubleNaN;
147 }
148 return cluster->getLayers();
149 }
150
151 double klmClusterEnergy(const Particle* particle)
152 {
153 const KLMCluster* cluster = particle->getKLMCluster();
154 if (!cluster) {
155 return Const::doubleNaN;
156 }
157 return cluster->getEnergy();
158 }
159
160 double klmClusterMomentum(const Particle* particle)
161 {
162 const KLMCluster* cluster = particle->getKLMCluster();
163 if (!cluster) {
164 return Const::doubleNaN;
165 }
166 return cluster->getMomentumMag();
167 }
168
169 double klmClusterIsBKLM(const Particle* particle)
170 {
171 const KLMCluster* cluster = particle->getKLMCluster();
172 if (!cluster) {
173 return Const::doubleNaN;
174 }
175 float clusterZ = cluster->getClusterPosition().Z();
176 if ((clusterZ > -180) && (clusterZ < 275)) {
177 return 1;
178 }
179 return 0;
180 }
181
182 double klmClusterIsEKLM(const Particle* particle)
183 {
184 const KLMCluster* cluster = particle->getKLMCluster();
185 if (!cluster) {
186 return Const::doubleNaN;
187 }
188 float clusterZ = cluster->getClusterPosition().Z();
189 if ((clusterZ < -180) || (clusterZ > 275)) {
190 return 1;
191 }
192 return 0;
193 }
194
195 double klmClusterIsForwardEKLM(const Particle* particle)
196 {
197 const KLMCluster* cluster = particle->getKLMCluster();
198 if (!cluster) {
199 return Const::doubleNaN;
200 }
201 float clusterZ = cluster->getClusterPosition().Z();
202 if (clusterZ > 275) {
203 return 1;
204 }
205 return 0;
206 }
207
208 double klmClusterIsBackwardEKLM(const Particle* particle)
209 {
210 const KLMCluster* cluster = particle->getKLMCluster();
211 if (!cluster) {
212 return Const::doubleNaN;
213 }
214 float clusterZ = cluster->getClusterPosition().Z();
215 if (clusterZ < -180) {
216 return 1;
217 }
218 return 0;
219 }
220
221 double klmClusterTheta(const Particle* particle)
222 {
223 const KLMCluster* cluster = particle->getKLMCluster();
224 if (!cluster) {
225 return Const::doubleNaN;
226 }
227 return cluster->getClusterPosition().Theta();
228 }
229
230 double klmClusterPhi(const Particle* particle)
231 {
232 const KLMCluster* cluster = particle->getKLMCluster();
233 if (!cluster) {
234 return Const::doubleNaN;
235 }
236 return cluster->getClusterPosition().Phi();
237 }
238
239 double maximumKLMAngleCMS(const Particle* particle)
240 {
241 // check there actually are KLM clusters in the event
242 StoreArray<KLMCluster> clusters;
243 if (clusters.getEntries() == 0) return Const::doubleNaN;
244
245 // get the input particle's vector momentum in the CMS frame
246 PCmsLabTransform T;
247 const ROOT::Math::PxPyPzEVector pCms = T.rotateLabToCms() * particle->get4Vector();
248
249 // find the KLM cluster with the largest angle
250 double maxAngle = 0.0;
251 for (int iKLM = 0; iKLM < clusters.getEntries(); iKLM++) {
252 const ROOT::Math::PxPyPzEVector clusterMomentumCms = T.rotateLabToCms() * clusters[iKLM]->getMomentum();
253 double angle = ROOT::Math::VectorUtil::Angle(pCms, clusterMomentumCms);
254 if (angle > maxAngle) maxAngle = angle;
255 }
256 return maxAngle;
257 }
258
259 double nKLMClusterTrackMatches(const Particle* particle)
260 {
261 const KLMCluster* cluster = particle->getKLMCluster();
262 if (!cluster)
263 return Const::doubleNaN;
264 size_t out = cluster->getRelationsFrom<Track>().size();
265 return double(out);
266 }
267
268 double nMatchedKLMClusters(const Particle* particle)
269 {
270 Particle::EParticleSourceObject particleSource = particle->getParticleSource();
271 if (particleSource == Particle::EParticleSourceObject::c_Track) {
272 return particle->getTrack()->getRelationsTo<KLMCluster>().size();
273 } else if (particleSource == Particle::EParticleSourceObject::c_ECLCluster) {
274 return particle->getECLCluster()->getRelationsTo<KLMCluster>().size();
275 } else {
276 return Const::doubleNaN;
277 }
278 }
279
280 double nKLMClusterECLClusterMatches(const Particle* particle)
281 {
282 const KLMCluster* cluster = particle->getKLMCluster();
283 if (!cluster)
284 return Const::doubleNaN;
285 size_t out = cluster->getRelationsFrom<ECLCluster>().size();
286 return double(out);
287 }
288
289 double klmClusterTrackDistance(const Particle* particle)
290 {
291 const KLMCluster* cluster = particle->getKLMCluster();
292 if (!cluster)
293 return Const::doubleNaN;
294 return cluster->getClusterTrackSeparation();
295 }
296
297 double ClusterTrackDistance_usingHelixExtrapolate(const KLMCluster* cluster, const Belle2::Track* specificTrack = nullptr)
298 {
299 // Get a reference to the KLM boundaries and set the values
300 const auto& klmBounds = DetectorSurface::detToSurfBoundaries.at("KLM");
301 const double r_BKLM = klmBounds.m_rho;
302 const double z_EFWD = klmBounds.m_zfwd;
303 const double z_EBWD = klmBounds.m_zbwd;
304 static const ROOT::Math::XYZVector vecNaN(Const::doubleNaN, Const::doubleNaN, Const::doubleNaN);
305
306 // Define the Lambda function
307 auto getPositionOnHelix_trackfit = [&](const TrackFitResult * trackFit) -> ROOT::Math::XYZVector {
308 if (!trackFit) return vecNaN;
309
310 // get helix and parameters
311 const double z0 = trackFit->getZ0();
312 const double tanlambda = trackFit->getTanLambda();
313 const Helix h = trackFit->getHelix();
314
315 // extrapolate to radius
316 const double arcLength = h.getArcLength2DAtCylindricalR(r_BKLM);
317 const double lHelixRadius = arcLength > 0 ? arcLength : std::numeric_limits<double>::max();
318
319 // extrapolate to FWD z
320 const double lFWD = (z_EFWD - z0) / tanlambda > 0 ? (z_EFWD - z0) / tanlambda : std::numeric_limits<double>::max();
321
322 // extrapolate to BWD z
323 const double lBWD = (z_EBWD - z0) / tanlambda > 0 ? (z_EBWD - z0) / tanlambda : std::numeric_limits<double>::max();
324
325 // pick smallest arclength
326 const double l = std::min({lHelixRadius, lFWD, lBWD});
327
328 ROOT::Math::XYZVector ext_helix = h.getPositionAtArcLength2D(l);
329 double helixExtR_surface = r_BKLM / sin(ext_helix.Theta());
330
331 if (l == lFWD)
332 {
333 helixExtR_surface = z_EFWD / cos(ext_helix.Theta());
334 } else if (l == lBWD)
335 {
336 helixExtR_surface = z_EBWD / cos(ext_helix.Theta());
337 }
338
339 // Safety Check
340 if (!std::isfinite(helixExtR_surface)) return vecNaN;
341
342 ROOT::Math::XYZVector helixExt_surface_position(0, 0, 0);
343 VectorUtil::setMagThetaPhi(helixExt_surface_position, helixExtR_surface, ext_helix.Theta(), ext_helix.Phi());
344
345 return helixExt_surface_position;
346 };
347
348 bool isEFWD = (cluster->getClusterPosition().Z() > klmBounds.m_zfwd);
349 bool isEBWD = (cluster->getClusterPosition().Z() < klmBounds.m_zbwd);
350
351 double klmClusterR_surface = r_BKLM / sin(cluster->getClusterPosition().Theta());
352 if (isEFWD) { klmClusterR_surface = z_EFWD / cos(cluster->getClusterPosition().Theta()); }
353 else if (isEBWD) { klmClusterR_surface = z_EBWD / cos(cluster->getClusterPosition().Theta()); }
354
355 ROOT::Math::XYZVector klmCluster_surface_position(0, 0, 0);
356 VectorUtil::setMagThetaPhi(klmCluster_surface_position,
357 klmClusterR_surface, cluster->getClusterPosition().Theta(), cluster->getClusterPosition().Phi());
358
359 double min_dist = 1e10;
360
361 if (specificTrack != nullptr) {
362 const TrackFitResult* trackfit = specificTrack->getTrackFitResultWithBestPValue();
363 ROOT::Math::XYZVector helixPos = getPositionOnHelix_trackfit(trackfit);
364 // Check if all components are valid (NOT NaN)
365 if (!std::isnan(helixPos.X()) && !std::isnan(helixPos.Y()) && !std::isnan(helixPos.Z())) {
366 min_dist = (klmCluster_surface_position - helixPos).R();
367 }
368 } else {
369 StoreArray<Track> tracks;
370 for (const Track& track : tracks) {
371 const TrackFitResult* trackfit = track.getTrackFitResultWithBestPValue();
372 ROOT::Math::XYZVector helixPos = getPositionOnHelix_trackfit(trackfit);
373 // Check if all components are valid (NOT NaN)
374 if (std::isnan(helixPos.X()) || std::isnan(helixPos.Y()) || std::isnan(helixPos.Z())) continue;
375
376 double dist = (klmCluster_surface_position - helixPos).R();
377 if (dist < min_dist) min_dist = dist;
378 }
379 }
380
381 return (min_dist > 1e9) ? Const::doubleNaN : min_dist;
382 }
383
384 double klmClusterTrackDistance_helix_extrapolation(const Particle* particle)
385 {
386 const KLMCluster* cluster = particle->getKLMCluster();
387 if (!cluster)
388 return Const::doubleNaN;
389 double min_dist = ClusterTrackDistance_usingHelixExtrapolate(cluster);
390 return min_dist;
391 }
392
393
394 double klmClusterTrackSeparationAngle(const Particle* particle)
395 {
396 const KLMCluster* cluster = particle->getKLMCluster();
397 if (!cluster)
398 return Const::doubleNaN;
399 return cluster->getClusterTrackSeparationAngle();
400 }
401
402 double klmClusterTrackRotationAngle(const Particle* particle)
403 {
404 const KLMCluster* cluster = particle->getKLMCluster();
405 if (!cluster)
406 return Const::doubleNaN;
407 return cluster->getClusterTrackRotationAngle();
408 }
409
410 double klmClusterShapeStdDev1(const Particle* particle)
411 {
412 const KLMCluster* cluster = particle->getKLMCluster();
413 if (!cluster)
414 return Const::doubleNaN;
415 return cluster->getShapeStdDev1();
416 }
417
418 double klmClusterShapeStdDev2(const Particle* particle)
419 {
420 const KLMCluster* cluster = particle->getKLMCluster();
421 if (!cluster)
422 return Const::doubleNaN;
423 return cluster->getShapeStdDev2();
424 }
425
426 double klmClusterShapeStdDev3(const Particle* particle)
427 {
428 const KLMCluster* cluster = particle->getKLMCluster();
429 if (!cluster)
430 return Const::doubleNaN;
431 return cluster->getShapeStdDev3();
432 }
433
434 VARIABLE_GROUP("KLM Cluster and KlongID");
435
436 REGISTER_VARIABLE("klmClusterKlId", klmClusterKlId,
437 "Returns the KlId classifier output associated to the KLMCluster.");
438 REGISTER_VARIABLE("klmClusterBelleTrackFlag", klmClusterBelleTrackFlag,
439 "Returns the Belle-style Track flag.");
440 REGISTER_VARIABLE("klmClusterBelleECLFlag", klmClusterBelleECLFlag,
441 "Returns the Belle-style ECL flag.");
442 REGISTER_VARIABLE("klmClusterTiming", klmClusterTiming, R"DOC(
443Returns the timing information of the associated KLMCluster.
444
445)DOC","ns");
446 REGISTER_VARIABLE("klmClusterPositionX", klmClusterPositionX, R"DOC(
447Returns the :math:`x` position of the associated KLMCluster.
448
449)DOC","cm");
450 REGISTER_VARIABLE("klmClusterPositionY", klmClusterPositionY, R"DOC(
451Returns the :math:`y` position of the associated KLMCluster.
452
453)DOC","cm");
454 REGISTER_VARIABLE("klmClusterPositionZ", klmClusterPositionZ, R"DOC(
455Returns the :math:`z` position of the associated KLMCluster.
456
457)DOC","cm");
458 REGISTER_VARIABLE("klmClusterInnermostLayer", klmClusterInnermostLayer,
459 "Returns the number of the innermost KLM layer with a 2-dimensional hit of the associated KLMCluster.");
460 REGISTER_VARIABLE("klmClusterLayers", klmClusterLayers,
461 "Returns the number of KLM layers with 2-dimensional hits of the associated KLMCluster.");
462 REGISTER_VARIABLE("klmClusterEnergy", klmClusterEnergy, R"DOC(
463Returns the energy of the associated KLMCluster. This variable returns an approximation of the energy: it uses `klmClusterMomentum` as momentum and the hypothesis that the KLMCluster is originated by a :math:`K_{L}^0`
464
465 (:math:`E_{\text{KLM}} = \sqrt{M_{K^0_L}^2 + p_{\text{KLM}}^2}`, where :math:`E_{\text{KLM}}` is this variable, :math:`M_{K^0_L}` is the :math:`K^0_L` mass and :math:`p_{\text{KLM}}` is `klmClusterMomentum`).
466
467)DOC","GeV");
468 MAKE_DEPRECATED("klmClusterEnergy", true, "light-2511-gacrux", R"DOC(
469 As this variable is deemed not physically meaningful it has been deprecated to avoid further use.
470)DOC");
471 REGISTER_VARIABLE("klmClusterMomentum", klmClusterMomentum, R"DOC(
472Returns the momentum magnitude of the associated KLMCluster. This variable returns an approximation of the momentum, since it is proportional to `klmClusterLayers`
473
474 (:math:`p_{\text{KLM}} = 0.215 \cdot N_{\text{layers}}`, where :math:`p_{\text{KLM}}` is this variable and :math:`N_{\text{layers}}` is `klmClusterLayers`).
475
476)DOC","GeV/c");
477 MAKE_DEPRECATED("klmClusterMomentum", true, "light-2511-gacrux", R"DOC(
478 As this variable is deemed not physically meaningful it has been deprecated to avoid further use.
479)DOC");
480 REGISTER_VARIABLE("klmClusterIsBKLM", klmClusterIsBKLM,
481 "Returns 1 if the associated KLMCluster is in barrel KLM.");
482 REGISTER_VARIABLE("klmClusterIsEKLM", klmClusterIsEKLM,
483 "Returns 1 if the associated KLMCluster is in endcap KLM.");
484 REGISTER_VARIABLE("klmClusterIsForwardEKLM", klmClusterIsForwardEKLM,
485 "Returns 1 if the associated KLMCluster is in forward endcap KLM.");
486 REGISTER_VARIABLE("klmClusterIsBackwardEKLM", klmClusterIsBackwardEKLM,
487 "Returns 1 if the associated KLMCluster is in backward endcap KLM.");
488 REGISTER_VARIABLE("klmClusterTheta", klmClusterTheta, R"DOC(
489Returns the polar (:math:`\theta`) angle of the associated KLMCluster.
490
491)DOC","rad");
492 REGISTER_VARIABLE("klmClusterPhi", klmClusterPhi, R"DOC(
493Returns the azimuthal (:math:`\phi`) angle of the associated KLMCluster.
494
495)DOC","rad");
496 REGISTER_VARIABLE("maximumKLMAngleCMS", maximumKLMAngleCMS ,
497 "Returns the maximum angle in the CMS frame between the Particle and all KLMClusters in the event.\n\n","rad");
498 REGISTER_VARIABLE("nKLMClusterTrackMatches", nKLMClusterTrackMatches, R"DOC(
499Returns the number of Tracks matched to the KLMCluster associated to this Particle. This variable can return a number greater than 0 for :math:`K_{L}^0` or :math:`n` candidates originating from KLMClusters and returns NaN for Particles with no KLMClusters associated.
500)DOC");
501 REGISTER_VARIABLE("nMatchedKLMClusters", nMatchedKLMClusters, R"DOC(
502 Returns the number of KLMClusters matched to the particle. It only works for
503 Particles created either from Tracks or from ECLCluster, while it returns NaN
504 for :math:`K_{L}^0` or :math:`n` candidates originating from KLMClusters.
505 )DOC");
506 REGISTER_VARIABLE("nKLMClusterECLClusterMatches", nKLMClusterECLClusterMatches, R"DOC(
507 Returns the number of ECLClusters matched to the KLMCluster associated to this Particle.
508 )DOC");
509 REGISTER_VARIABLE("klmClusterTrackDistance_helix_extrapolation", klmClusterTrackDistance_helix_extrapolation, R"DOC(
510This also returns the distance between KLM cluster and its closes track, but calculated using helix extrapolation. This variable returns ``NAN`` if there is no Track-to-KLMCluster relationship.
511
512.. note::
513 This is only an approximation of the cluster-track distance that is intended to be used for mDSTs processed with release-09 or earlier. For mDSTs created using release-10 or later please use `klmClusterTrackDistance`.
514
515)DOC","cm");
516 REGISTER_VARIABLE("klmClusterTrackDistance", klmClusterTrackDistance, R"DOC(
517Returns the distance between the KLMCluster associated to this Particle and the closest track to this cluster. This variable returns NaN if there is no Track-to-KLMCluster relationship.
518
519.. warning::
520 This variable only works on mdsts created with release-10 and onwards. For mdsts created with a previous release this variable would
521 return NaN. Please check the release version of the input mdst using
522 `b2file-metadata-show <https://software.belle2.org/development/sphinx/framework/doc/tools/02-b2file.html#b2file-metadata-show-show-the-metadata-of-a-basf2-output-file>`_ with the ``--all`` option.
523
524)DOC","cm");
525 REGISTER_VARIABLE("klmClusterTrackRotationAngle", klmClusterTrackRotationAngle, R"DOC(
526Returns the angle between momenta of the track initially at IP and then at POCA to the KLMCluster associated to this Particle for the closest Track. This variable returns NaN if there is no Track-to-KLMCluster relationship.
527
528.. warning::
529 This variable only works on mdsts created with release-10 and onwards. For mdsts created with a previous release this variable would
530 return NaN. Please check the release version of the input mdst using
531 `b2file-metadata-show <https://software.belle2.org/development/sphinx/framework/doc/tools/02-b2file.html#b2file-metadata-show-show-the-metadata-of-a-basf2-output-file>`_ with the ``--all`` option.
532
533)DOC","rad");
534 REGISTER_VARIABLE("klmClusterTrackSeparationAngle", klmClusterTrackSeparationAngle, R"DOC(
535Returns the angle between the KLMCluster associated to this Particle and the closest track. This variable returns NaN if there is no Track-to-KLMCluster relationship.
536
537.. warning::
538 This variable only works on mdsts created with release-10 and onwards. For mdsts created with a previous release this variable would
539 return NaN. Please check the release version of the input mdst using
540 `b2file-metadata-show <https://software.belle2.org/development/sphinx/framework/doc/tools/02-b2file.html#b2file-metadata-show-show-the-metadata-of-a-basf2-output-file>`_ with the ``--all`` option.
541
542)DOC","rad");
543
544 REGISTER_VARIABLE("klmClusterShapeStdDev1", klmClusterShapeStdDev1, R"DOC(
545Returns the std deviation of the 1st axis from a PCA of the KLMCluster associated to this Particle. This variable returns 0 if this KLMCluster contains only one 2D Hit.
546
547.. warning::
548 This variable only works on mdsts created with release-10 and onwards. For mdsts created with a previous release this variable would
549 return NaN. Please check the release version of the input mdst using
550 `b2file-metadata-show <https://software.belle2.org/development/sphinx/framework/doc/tools/02-b2file.html#b2file-metadata-show-show-the-metadata-of-a-basf2-output-file>`_ with the ``--all`` option.
551
552)DOC","cm");
553 REGISTER_VARIABLE("klmClusterShapeStdDev2", klmClusterShapeStdDev2, R"DOC(
554Returns the std deviation of the 2nd axis from a PCA of the KLMCluster associated to this Particle. This variable returns 0 if this KLMCluster has all the 2D hits lying on a single straight line.
555
556.. warning::
557 This variable only works on mdsts created with release-10 and onwards. For mdsts created with a previous release this variable would
558 return NaN. Please check the release version of the input mdst using
559 `b2file-metadata-show <https://software.belle2.org/development/sphinx/framework/doc/tools/02-b2file.html#b2file-metadata-show-show-the-metadata-of-a-basf2-output-file>`_ with the ``--all`` option.
560
561)DOC","cm");
562 REGISTER_VARIABLE("klmClusterShapeStdDev3", klmClusterShapeStdDev3, R"DOC(
563Returns the std deviation of the 3nd axis from a PCA of the KLMCluster associated to this Particle. This variable returns 0 if this KLMCluster has all the 2D hits lying on a 2D plane.
564
565.. warning::
566 This variable only works on mdsts created with release-10 and onwards. For mdsts created with a previous release this variable would
567 return NaN. Please check the release version of the input mdst using
568 `b2file-metadata-show <https://software.belle2.org/development/sphinx/framework/doc/tools/02-b2file.html#b2file-metadata-show-show-the-metadata-of-a-basf2-output-file>`_ with the ``--all`` option.
569
570)DOC","cm");
571}
572
double R
typedef autogenerated by FFTW
static const double doubleNaN
quiet_NaN
Definition Const.h:703
EParticleSourceObject
particle source enumerators
Definition Particle.h:83
STL namespace.
static const std::unordered_map< std::string, DetSurfCylBoundaries > detToSurfBoundaries
Map that associates to each detector its valid cylindrical surface's boundaries.