10#include <analysis/variables/KLMClusterVariables.h>
13#include <analysis/VariableManager/Manager.h>
16#include <analysis/dataobjects/Particle.h>
17#include <analysis/utility/PCmsLabTransform.h>
20#include <framework/datastore/StoreArray.h>
21#include <mdst/dataobjects/ECLCluster.h>
22#include <mdst/dataobjects/KlId.h>
23#include <mdst/dataobjects/KLMCluster.h>
24#include <mdst/dataobjects/Track.h>
25#include <mdst/dataobjects/TrackFitResult.h>
28#include <Math/Vector3D.h>
29#include <Math/Vector4D.h>
30#include <Math/VectorUtil.h>
34namespace Belle2::Variable {
36 double klmClusterKlId(
const Particle* particle)
38 const KLMCluster* cluster = particle->getKLMCluster();
42 const KlId* klid = cluster->getRelatedTo<KlId>();
46 return klid->getKlId();
49 int klmClusterBelleTrackFlag(
const Particle* particle)
51 const float angle = 0.24;
52 const KLMCluster* cluster = particle->getKLMCluster();
56 const ROOT::Math::XYZVector& pos = cluster->getClusterPosition();
57 StoreArray<TrackFitResult> tracks;
58 for (
const TrackFitResult& track : tracks) {
59 const ROOT::Math::XYZVector& trackPos = track.getPosition();
60 if (ROOT::Math::VectorUtil::Angle(trackPos, pos) < angle) {
67 int klmClusterBelleECLFlag(
const Particle* particle)
69 const float angle = 0.24;
70 const KLMCluster* klmCluster = particle->getKLMCluster();
74 const ROOT::Math::XYZVector& klmClusterPos = klmCluster->getClusterPosition();
75 StoreArray<ECLCluster> eclClusters;
76 for (
const ECLCluster& eclCluster : eclClusters) {
77 const ROOT::Math::XYZVector& eclClusterPos = eclCluster.getClusterPosition();
78 if (ROOT::Math::VectorUtil::Angle(eclClusterPos, klmClusterPos) < angle) {
85 double klmClusterTiming(
const Particle* particle)
87 const KLMCluster* cluster = particle->getKLMCluster();
91 return cluster->getTime();
95 double klmClusterPositionX(
const Particle* particle)
97 const KLMCluster* cluster = particle->getKLMCluster();
101 return cluster->getClusterPosition().X();
105 double klmClusterPositionY(
const Particle* particle)
107 const KLMCluster* cluster = particle->getKLMCluster();
111 return cluster->getClusterPosition().Y();
115 double klmClusterPositionZ(
const Particle* particle)
117 const KLMCluster* cluster = particle->getKLMCluster();
121 return cluster->getClusterPosition().Z();
125 double klmClusterInnermostLayer(
const Particle* particle)
127 const KLMCluster* cluster = particle->getKLMCluster();
131 return cluster->getInnermostLayer();
135 double klmClusterLayers(
const Particle* particle)
137 const KLMCluster* cluster = particle->getKLMCluster();
141 return cluster->getLayers();
144 double klmClusterEnergy(
const Particle* particle)
146 const KLMCluster* cluster = particle->getKLMCluster();
150 return cluster->getEnergy();
153 double klmClusterMomentum(
const Particle* particle)
155 const KLMCluster* cluster = particle->getKLMCluster();
159 return cluster->getMomentumMag();
162 double klmClusterIsBKLM(
const Particle* particle)
164 const KLMCluster* cluster = particle->getKLMCluster();
168 float clusterZ = cluster->getClusterPosition().Z();
169 if ((clusterZ > -180) && (clusterZ < 275)) {
175 double klmClusterIsEKLM(
const Particle* particle)
177 const KLMCluster* cluster = particle->getKLMCluster();
181 float clusterZ = cluster->getClusterPosition().Z();
182 if ((clusterZ < -180) || (clusterZ > 275)) {
188 double klmClusterIsForwardEKLM(
const Particle* particle)
190 const KLMCluster* cluster = particle->getKLMCluster();
194 float clusterZ = cluster->getClusterPosition().Z();
195 if (clusterZ > 275) {
201 double klmClusterIsBackwardEKLM(
const Particle* particle)
203 const KLMCluster* cluster = particle->getKLMCluster();
207 float clusterZ = cluster->getClusterPosition().Z();
208 if (clusterZ < -180) {
214 double klmClusterTheta(
const Particle* particle)
216 const KLMCluster* cluster = particle->getKLMCluster();
220 return cluster->getClusterPosition().Theta();
223 double klmClusterPhi(
const Particle* particle)
225 const KLMCluster* cluster = particle->getKLMCluster();
229 return cluster->getClusterPosition().Phi();
232 double maximumKLMAngleCMS(
const Particle* particle)
235 StoreArray<KLMCluster> clusters;
240 const ROOT::Math::PxPyPzEVector pCms = T.rotateLabToCms() * particle->get4Vector();
243 double maxAngle = 0.0;
244 for (
int iKLM = 0; iKLM < clusters.getEntries(); iKLM++) {
245 const ROOT::Math::PxPyPzEVector clusterMomentumCms = T.rotateLabToCms() * clusters[iKLM]->getMomentum();
246 double angle = ROOT::Math::VectorUtil::Angle(pCms, clusterMomentumCms);
247 if (angle > maxAngle) maxAngle = angle;
252 double nKLMClusterTrackMatches(
const Particle* particle)
254 const KLMCluster* cluster = particle->getKLMCluster();
257 size_t out = cluster->getRelationsFrom<Track>().size();
261 double nMatchedKLMClusters(
const Particle* particle)
264 if (particleSource == Particle::EParticleSourceObject::c_Track) {
265 return particle->getTrack()->getRelationsTo<KLMCluster>().size();
266 }
else if (particleSource == Particle::EParticleSourceObject::c_ECLCluster) {
267 return particle->getECLCluster()->getRelationsTo<KLMCluster>().size();
273 double nKLMClusterECLClusterMatches(
const Particle* particle)
275 const KLMCluster* cluster = particle->getKLMCluster();
278 size_t out = cluster->getRelationsFrom<ECLCluster>().size();
282 double klmClusterTrackDistance(
const Particle* particle)
284 const KLMCluster* cluster = particle->getKLMCluster();
287 return cluster->getClusterTrackSeparation();
290 double klmClusterTrackSeparationAngle(
const Particle* particle)
292 const KLMCluster* cluster = particle->getKLMCluster();
295 return cluster->getClusterTrackSeparationAngle();
298 double klmClusterTrackRotationAngle(
const Particle* particle)
300 const KLMCluster* cluster = particle->getKLMCluster();
303 return cluster->getClusterTrackRotationAngle();
306 double klmClusterShapeStdDev1(
const Particle* particle)
308 const KLMCluster* cluster = particle->getKLMCluster();
311 return cluster->getShapeStdDev1();
314 double klmClusterShapeStdDev2(
const Particle* particle)
316 const KLMCluster* cluster = particle->getKLMCluster();
319 return cluster->getShapeStdDev2();
322 double klmClusterShapeStdDev3(
const Particle* particle)
324 const KLMCluster* cluster = particle->getKLMCluster();
327 return cluster->getShapeStdDev3();
330 VARIABLE_GROUP(
"KLM Cluster and KlongID");
332 REGISTER_VARIABLE(
"klmClusterKlId", klmClusterKlId,
333 "Returns the KlId classifier output associated to the KLMCluster.");
334 REGISTER_VARIABLE(
"klmClusterBelleTrackFlag", klmClusterBelleTrackFlag,
335 "Returns the Belle-style Track flag.");
336 REGISTER_VARIABLE(
"klmClusterBelleECLFlag", klmClusterBelleECLFlag,
337 "Returns the Belle-style ECL flag.");
338 REGISTER_VARIABLE(
"klmClusterTiming", klmClusterTiming, R
"DOC(
339Returns the timing information of the associated KLMCluster.
342 REGISTER_VARIABLE("klmClusterPositionX", klmClusterPositionX, R"DOC(
343Returns the :math:`x` position of the associated KLMCluster.
346 REGISTER_VARIABLE("klmClusterPositionY", klmClusterPositionY, R"DOC(
347Returns the :math:`y` position of the associated KLMCluster.
350 REGISTER_VARIABLE("klmClusterPositionZ", klmClusterPositionZ, R"DOC(
351Returns the :math:`z` position of the associated KLMCluster.
354 REGISTER_VARIABLE("klmClusterInnermostLayer", klmClusterInnermostLayer,
355 "Returns the number of the innermost KLM layer with a 2-dimensional hit of the associated KLMCluster.");
356 REGISTER_VARIABLE("klmClusterLayers", klmClusterLayers,
357 "Returns the number of KLM layers with 2-dimensional hits of the associated KLMCluster.");
358 REGISTER_VARIABLE("klmClusterEnergy", klmClusterEnergy, R"DOC(
359Returns the energy of the associated KLMCluster.
362 This variable returns an approximation of the energy: it uses :b2:var:`klmClusterMomentum` as momentum and the hypothesis that the KLMCluster is originated by a :math:`K_{L}^0`
363 (: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 :b2:var:`klmClusterMomentum`).
364 It should be used with caution, and may not be physically meaningful, especially for :math:`n` candidates.
367 REGISTER_VARIABLE("klmClusterMomentum", klmClusterMomentum, R"DOC(
368Returns the momentum magnitude of the associated KLMCluster.
371 This variable returns an approximation of the momentum, since it is proportional to :b2:var:`klmClusterLayers`
372 (:math:`p_{\text{KLM}} = 0.215 \cdot N_{\text{layers}}`, where :math:`p_{\text{KLM}}` is this variable and :math:`N_{\text{layers}}` is :b2:var:`klmClusterLayers`).
373 It should be used with caution, and may not be physically meaningful.
376 REGISTER_VARIABLE("klmClusterIsBKLM", klmClusterIsBKLM,
377 "Returns 1 if the associated KLMCluster is in barrel KLM.");
378 REGISTER_VARIABLE("klmClusterIsEKLM", klmClusterIsEKLM,
379 "Returns 1 if the associated KLMCluster is in endcap KLM.");
380 REGISTER_VARIABLE("klmClusterIsForwardEKLM", klmClusterIsForwardEKLM,
381 "Returns 1 if the associated KLMCluster is in forward endcap KLM.");
382 REGISTER_VARIABLE("klmClusterIsBackwardEKLM", klmClusterIsBackwardEKLM,
383 "Returns 1 if the associated KLMCluster is in backward endcap KLM.");
384 REGISTER_VARIABLE("klmClusterTheta", klmClusterTheta, R"DOC(
385Returns the polar (:math:`\theta`) angle of the associated KLMCluster.
388 REGISTER_VARIABLE("klmClusterPhi", klmClusterPhi, R"DOC(
389Returns the azimuthal (:math:`\phi`) angle of the associated KLMCluster.
392 REGISTER_VARIABLE("maximumKLMAngleCMS", maximumKLMAngleCMS ,
393 "Returns the maximum angle in the CMS frame between the Particle and all KLMClusters in the event.\n\n","rad");
394 REGISTER_VARIABLE("nKLMClusterTrackMatches", nKLMClusterTrackMatches, R"DOC(
395Returns 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.
397 REGISTER_VARIABLE("nMatchedKLMClusters", nMatchedKLMClusters, R
"DOC(
398 Returns the number of KLMClusters matched to the particle. It only works for
399 Particles created either from Tracks or from ECLCluster, while it returns NaN
400 for :math:`K_{L}^0` or :math:`n` candidates originating from KLMClusters.
402 REGISTER_VARIABLE("nKLMClusterECLClusterMatches", nKLMClusterECLClusterMatches, R
"DOC(
403 Returns the number of ECLClusters matched to the KLMCluster associated to this Particle.
405 REGISTER_VARIABLE("klmClusterTrackDistance", klmClusterTrackDistance,
406 "Returns the distance between KLMCluster associated to this Particle and the closest track. This variable returns NaN if there is no Track-to-KLMCluster relationship.",
408 REGISTER_VARIABLE(
"klmClusterTrackRotationAngle", klmClusterTrackRotationAngle,
409 "Returns the angle between the direction at the IP and at the POCA to the KLMCluster associated to this Particle for the closest track. This variable returns NaN if there is no Track-to-KLMCluster relationship.\n\n",
411 REGISTER_VARIABLE(
"klmClusterTrackSeparationAngle", klmClusterTrackSeparationAngle,
412 "Returns 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"
415 REGISTER_VARIABLE(
"klmClusterShapeStdDev1", klmClusterShapeStdDev1,
416 "Returns 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 KLMHit2d cluster."
418 REGISTER_VARIABLE(
"klmClusterShapeStdDev2", klmClusterShapeStdDev2,
419 "Returns the std deviation of the 2nd axis from a PCA of the KLMCluster associated to this Particle. This variable returns 0 if this KLMCluster contains only one KLMHit2d cluster."
421 REGISTER_VARIABLE(
"klmClusterShapeStdDev3", klmClusterShapeStdDev3,
422 "Returns the std deviation of the 3rd axis from a PCA of the KLMCluster associated to this Particle. This variable returns 0 if this KLMCluster contains only one KLMHit2d cluster."
static const double doubleNaN
quiet_NaN
EParticleSourceObject
particle source enumerators