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 auto trackWithWeight = cluster->getRelatedFromWithWeight<Track>();
288 if (!trackWithWeight.first)
290 return 1. / trackWithWeight.second;
293 VARIABLE_GROUP(
"KLM Cluster and KlongID");
295 REGISTER_VARIABLE(
"klmClusterKlId", klmClusterKlId,
296 "Returns the KlId classifier output associated to the KLMCluster.");
297 REGISTER_VARIABLE(
"klmClusterBelleTrackFlag", klmClusterBelleTrackFlag,
298 "Returns the Belle-style Track flag.");
299 REGISTER_VARIABLE(
"klmClusterBelleECLFlag", klmClusterBelleECLFlag,
300 "Returns the Belle-style ECL flag.");
301 REGISTER_VARIABLE(
"klmClusterTiming", klmClusterTiming, R
"DOC(
302Returns the timing information of the associated KLMCluster.
305 REGISTER_VARIABLE("klmClusterPositionX", klmClusterPositionX, R"DOC(
306Returns the :math:`x` position of the associated KLMCluster.
309 REGISTER_VARIABLE("klmClusterPositionY", klmClusterPositionY, R"DOC(
310Returns the :math:`y` position of the associated KLMCluster.
313 REGISTER_VARIABLE("klmClusterPositionZ", klmClusterPositionZ, R"DOC(
314Returns the :math:`z` position of the associated KLMCluster.
317 REGISTER_VARIABLE("klmClusterInnermostLayer", klmClusterInnermostLayer,
318 "Returns the number of the innermost KLM layer with a 2-dimensional hit of the associated KLMCluster.");
319 REGISTER_VARIABLE("klmClusterLayers", klmClusterLayers,
320 "Returns the number of KLM layers with 2-dimensional hits of the associated KLMCluster.");
321 REGISTER_VARIABLE("klmClusterEnergy", klmClusterEnergy, R"DOC(
322Returns the energy of the associated KLMCluster.
325 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`
326 (: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`).
327 It should be used with caution, and may not be physically meaningful, especially for :math:`n` candidates.
330 REGISTER_VARIABLE("klmClusterMomentum", klmClusterMomentum, R"DOC(
331Returns the momentum magnitude of the associated KLMCluster.
334 This variable returns an approximation of the momentum, since it is proportional to :b2:var:`klmClusterLayers`
335 (: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`).
336 It should be used with caution, and may not be physically meaningful.
339 REGISTER_VARIABLE("klmClusterIsBKLM", klmClusterIsBKLM,
340 "Returns 1 if the associated KLMCluster is in barrel KLM.");
341 REGISTER_VARIABLE("klmClusterIsEKLM", klmClusterIsEKLM,
342 "Returns 1 if the associated KLMCluster is in endcap KLM.");
343 REGISTER_VARIABLE("klmClusterIsForwardEKLM", klmClusterIsForwardEKLM,
344 "Returns 1 if the associated KLMCluster is in forward endcap KLM.");
345 REGISTER_VARIABLE("klmClusterIsBackwardEKLM", klmClusterIsBackwardEKLM,
346 "Returns 1 if the associated KLMCluster is in backward endcap KLM.");
347 REGISTER_VARIABLE("klmClusterTheta", klmClusterTheta, R"DOC(
348Returns the polar (:math:`\theta`) angle of the associated KLMCluster.
351 REGISTER_VARIABLE("klmClusterPhi", klmClusterPhi, R"DOC(
352Returns the azimuthal (:math:`\phi`) angle of the associated KLMCluster.
355 REGISTER_VARIABLE("maximumKLMAngleCMS", maximumKLMAngleCMS ,
356 "Returns the maximum angle in the CMS frame between the Particle and all KLMClusters in the event.\n\n","rad");
357 REGISTER_VARIABLE("nKLMClusterTrackMatches", nKLMClusterTrackMatches, R"DOC(
358Returns 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.
360 REGISTER_VARIABLE("nMatchedKLMClusters", nMatchedKLMClusters, R
"DOC(
361 Returns the number of KLMClusters matched to the particle. It only works for
362 Particles created either from Tracks or from ECLCluster, while it returns NaN
363 for :math:`K_{L}^0` or :math:`n` candidates originating from KLMClusters.
365 REGISTER_VARIABLE("nKLMClusterECLClusterMatches", nKLMClusterECLClusterMatches, R
"DOC(
366 Returns the number of ECLClusters matched to the KLMCluster associated to this Particle.
368 REGISTER_VARIABLE("klmClusterTrackDistance", klmClusterTrackDistance,
369 "Returns the distance between the Track and the KLMCluster associated to this Particle. This variable returns NaN if there is no Track-to-KLMCluster relationship.\n\n",
static const double doubleNaN
quiet_NaN
EParticleSourceObject
particle source enumerators