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, R"DOC(
437Returns the KlId classifier output associated to the KLMCluster.
438
439.. attention::
440 This variable returns ``NaN`` when datasets produced with
441 release-11 or a newer major release are analysed.
442)DOC");
443 REGISTER_VARIABLE("klmClusterBelleTrackFlag", klmClusterBelleTrackFlag,
444 "Returns the Belle-style Track flag.");
445 REGISTER_VARIABLE("klmClusterBelleECLFlag", klmClusterBelleECLFlag,
446 "Returns the Belle-style ECL flag.");
447 REGISTER_VARIABLE("klmClusterTiming", klmClusterTiming, R"DOC(
448Returns the timing information of the associated KLMCluster.
449
450)DOC","ns");
451 REGISTER_VARIABLE("klmClusterPositionX", klmClusterPositionX, R"DOC(
452Returns the :math:`x` position of the associated KLMCluster.
453
454)DOC","cm");
455 REGISTER_VARIABLE("klmClusterPositionY", klmClusterPositionY, R"DOC(
456Returns the :math:`y` position of the associated KLMCluster.
457
458)DOC","cm");
459 REGISTER_VARIABLE("klmClusterPositionZ", klmClusterPositionZ, R"DOC(
460Returns the :math:`z` position of the associated KLMCluster.
461
462)DOC","cm");
463 REGISTER_VARIABLE("klmClusterInnermostLayer", klmClusterInnermostLayer,
464 "Returns the number of the innermost KLM layer with a 2-dimensional hit of the associated KLMCluster.");
465 REGISTER_VARIABLE("klmClusterLayers", klmClusterLayers,
466 "Returns the number of KLM layers with 2-dimensional hits of the associated KLMCluster.");
467 REGISTER_VARIABLE("klmClusterEnergy", klmClusterEnergy, R"DOC(
468Returns 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`
469
470 (: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`).
471
472)DOC","GeV");
473 MAKE_DEPRECATED("klmClusterEnergy", true, "light-2511-gacrux", R"DOC(
474 As this variable is deemed not physically meaningful it has been deprecated to avoid further use.
475)DOC");
476 REGISTER_VARIABLE("klmClusterMomentum", klmClusterMomentum, R"DOC(
477Returns the momentum magnitude of the associated KLMCluster. This variable returns an approximation of the momentum, since it is proportional to `klmClusterLayers`
478
479 (: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`).
480
481)DOC","GeV/c");
482 MAKE_DEPRECATED("klmClusterMomentum", true, "light-2511-gacrux", R"DOC(
483 As this variable is deemed not physically meaningful it has been deprecated to avoid further use.
484)DOC");
485 REGISTER_VARIABLE("klmClusterIsBKLM", klmClusterIsBKLM,
486 "Returns 1 if the associated KLMCluster is in barrel KLM.");
487 REGISTER_VARIABLE("klmClusterIsEKLM", klmClusterIsEKLM,
488 "Returns 1 if the associated KLMCluster is in endcap KLM.");
489 REGISTER_VARIABLE("klmClusterIsForwardEKLM", klmClusterIsForwardEKLM,
490 "Returns 1 if the associated KLMCluster is in forward endcap KLM.");
491 REGISTER_VARIABLE("klmClusterIsBackwardEKLM", klmClusterIsBackwardEKLM,
492 "Returns 1 if the associated KLMCluster is in backward endcap KLM.");
493 REGISTER_VARIABLE("klmClusterTheta", klmClusterTheta, R"DOC(
494Returns the polar (:math:`\theta`) angle of the associated KLMCluster.
495
496)DOC","rad");
497 REGISTER_VARIABLE("klmClusterPhi", klmClusterPhi, R"DOC(
498Returns the azimuthal (:math:`\phi`) angle of the associated KLMCluster.
499
500)DOC","rad");
501 REGISTER_VARIABLE("maximumKLMAngleCMS", maximumKLMAngleCMS ,
502 "Returns the maximum angle in the CMS frame between the Particle and all KLMClusters in the event.\n\n","rad");
503 REGISTER_VARIABLE("nKLMClusterTrackMatches", nKLMClusterTrackMatches, R"DOC(
504Returns 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.
505)DOC");
506 REGISTER_VARIABLE("nMatchedKLMClusters", nMatchedKLMClusters, R"DOC(
507 Returns the number of KLMClusters matched to the particle. It only works for
508 Particles created either from Tracks or from ECLCluster, while it returns NaN
509 for :math:`K_{L}^0` or :math:`n` candidates originating from KLMClusters.
510 )DOC");
511 REGISTER_VARIABLE("nKLMClusterECLClusterMatches", nKLMClusterECLClusterMatches, R"DOC(
512 Returns the number of ECLClusters matched to the KLMCluster associated to this Particle.
513 )DOC");
514 REGISTER_VARIABLE("klmClusterTrackDistance_helix_extrapolation", klmClusterTrackDistance_helix_extrapolation, R"DOC(
515This 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.
516
517.. note::
518 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`.
519
520)DOC","cm");
521 REGISTER_VARIABLE("klmClusterTrackDistance", klmClusterTrackDistance, R"DOC(
522Returns 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.
523
524.. warning::
525 This variable only works on mdsts created with release-10 and onwards. For mdsts created with a previous release this variable would
526 return NaN. Please check the release version of the input mdst using
527 `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.
528
529)DOC","cm");
530 REGISTER_VARIABLE("klmClusterTrackRotationAngle", klmClusterTrackRotationAngle, R"DOC(
531Returns 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.
532
533.. warning::
534 This variable only works on mdsts created with release-10 and onwards. For mdsts created with a previous release this variable would
535 return NaN. Please check the release version of the input mdst using
536 `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.
537
538)DOC","rad");
539 REGISTER_VARIABLE("klmClusterTrackSeparationAngle", klmClusterTrackSeparationAngle, R"DOC(
540Returns 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.
541
542.. warning::
543 This variable only works on mdsts created with release-10 and onwards. For mdsts created with a previous release this variable would
544 return NaN. Please check the release version of the input mdst using
545 `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.
546
547)DOC","rad");
548
549 REGISTER_VARIABLE("klmClusterShapeStdDev1", klmClusterShapeStdDev1, R"DOC(
550Returns 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.
551
552.. warning::
553 This variable only works on mdsts created with release-10 and onwards. For mdsts created with a previous release this variable would
554 return NaN. Please check the release version of the input mdst using
555 `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.
556
557)DOC","cm");
558 REGISTER_VARIABLE("klmClusterShapeStdDev2", klmClusterShapeStdDev2, R"DOC(
559Returns 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.
560
561.. warning::
562 This variable only works on mdsts created with release-10 and onwards. For mdsts created with a previous release this variable would
563 return NaN. Please check the release version of the input mdst using
564 `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.
565
566)DOC","cm");
567 REGISTER_VARIABLE("klmClusterShapeStdDev3", klmClusterShapeStdDev3, R"DOC(
568Returns 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.
569
570.. warning::
571 This variable only works on mdsts created with release-10 and onwards. For mdsts created with a previous release this variable would
572 return NaN. Please check the release version of the input mdst using
573 `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.
574
575)DOC","cm");
576}
577
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.