10 #include <analysis/variables/KLMClusterVariables.h>
13 #include <analysis/dataobjects/Particle.h>
14 #include <analysis/utility/PCmsLabTransform.h>
15 #include <analysis/VariableManager/Manager.h>
18 #include <framework/datastore/StoreArray.h>
19 #include <mdst/dataobjects/ECLCluster.h>
20 #include <mdst/dataobjects/KlId.h>
21 #include <mdst/dataobjects/KLMCluster.h>
22 #include <mdst/dataobjects/Track.h>
23 #include <mdst/dataobjects/TrackFitResult.h>
27 namespace Belle2::Variable {
29 double klmClusterKlId(
const Particle* particle)
31 const KLMCluster* cluster = particle->getKLMCluster();
33 return std::numeric_limits<double>::quiet_NaN();
35 const KlId* klid = cluster->getRelatedTo<KlId>();
37 return std::numeric_limits<double>::quiet_NaN();
39 return klid->getKlId();
42 int klmClusterBelleTrackFlag(
const Particle* particle)
44 const float angle = 0.24;
45 const KLMCluster* cluster = particle->getKLMCluster();
47 return std::numeric_limits<int>::quiet_NaN();
49 const TVector3& pos = cluster->getClusterPosition();
50 StoreArray<TrackFitResult> tracks;
51 for (
const TrackFitResult& track : tracks) {
52 const TVector3& trackPos = track.getPosition();
53 if (trackPos.Angle(pos) < angle) {
60 int klmClusterBelleECLFlag(
const Particle* particle)
62 const float angle = 0.24;
63 const KLMCluster* klmCluster = particle->getKLMCluster();
65 return std::numeric_limits<int>::quiet_NaN();
67 const TVector3& klmClusterPos = klmCluster->getClusterPosition();
68 StoreArray<ECLCluster> eclClusters;
69 for (
const ECLCluster& eclCluster : eclClusters) {
70 const TVector3& eclClusterPos = eclCluster.getClusterPosition();
71 if (eclClusterPos.Angle(klmClusterPos) < angle) {
78 double klmClusterTiming(
const Particle* particle)
80 const KLMCluster* cluster = particle->getKLMCluster();
82 return std::numeric_limits<double>::quiet_NaN();
84 return cluster->getTime();
88 double klmClusterPositionX(
const Particle* particle)
90 const KLMCluster* cluster = particle->getKLMCluster();
92 return std::numeric_limits<double>::quiet_NaN();
94 return cluster->getClusterPosition().x();
98 double klmClusterPositionY(
const Particle* particle)
100 const KLMCluster* cluster = particle->getKLMCluster();
102 return std::numeric_limits<double>::quiet_NaN();
104 return cluster->getClusterPosition().y();
108 double klmClusterPositionZ(
const Particle* particle)
110 const KLMCluster* cluster = particle->getKLMCluster();
112 return std::numeric_limits<double>::quiet_NaN();
114 return cluster->getClusterPosition().z();
118 double klmClusterInnermostLayer(
const Particle* particle)
120 const KLMCluster* cluster = particle->getKLMCluster();
122 return std::numeric_limits<double>::quiet_NaN();
124 return cluster->getInnermostLayer();
128 double klmClusterLayers(
const Particle* particle)
130 const KLMCluster* cluster = particle->getKLMCluster();
132 return std::numeric_limits<double>::quiet_NaN();
134 return cluster->getLayers();
137 double klmClusterEnergy(
const Particle* particle)
139 const KLMCluster* cluster = particle->getKLMCluster();
141 return std::numeric_limits<double>::quiet_NaN();
143 return cluster->getEnergy();
146 double klmClusterMomentum(
const Particle* particle)
148 const KLMCluster* cluster = particle->getKLMCluster();
150 return std::numeric_limits<double>::quiet_NaN();
152 return cluster->getMomentumMag();
155 double klmClusterIsBKLM(
const Particle* particle)
157 const KLMCluster* cluster = particle->getKLMCluster();
159 return std::numeric_limits<double>::quiet_NaN();
161 float clusterZ = cluster->getClusterPosition().Z();
162 if ((clusterZ > -180) && (clusterZ < 275)) {
168 double klmClusterIsEKLM(
const Particle* particle)
170 const KLMCluster* cluster = particle->getKLMCluster();
172 return std::numeric_limits<double>::quiet_NaN();
174 float clusterZ = cluster->getClusterPosition().Z();
175 if ((clusterZ < -180) || (clusterZ > 275)) {
181 double klmClusterIsForwardEKLM(
const Particle* particle)
183 const KLMCluster* cluster = particle->getKLMCluster();
185 return std::numeric_limits<double>::quiet_NaN();
187 float clusterZ = cluster->getClusterPosition().Z();
188 if (clusterZ > 275) {
194 double klmClusterIsBackwardEKLM(
const Particle* particle)
196 const KLMCluster* cluster = particle->getKLMCluster();
198 return std::numeric_limits<double>::quiet_NaN();
200 float clusterZ = cluster->getClusterPosition().Z();
201 if (clusterZ < -180) {
207 double klmClusterTheta(
const Particle* particle)
209 const KLMCluster* cluster = particle->getKLMCluster();
211 return std::numeric_limits<double>::quiet_NaN();
213 return cluster->getClusterPosition().Theta();
216 double klmClusterPhi(
const Particle* particle)
218 const KLMCluster* cluster = particle->getKLMCluster();
220 return std::numeric_limits<double>::quiet_NaN();
222 return cluster->getClusterPosition().Phi();
225 double maximumKLMAngleCMS(
const Particle* particle)
228 StoreArray<KLMCluster> clusters;
229 if (clusters.getEntries() == 0)
return std::numeric_limits<double>::quiet_NaN();
233 const TVector3 pCms = (T.rotateLabToCms() * particle->get4Vector()).Vect();
236 double maxAngle = 0.0;
237 for (
int iKLM = 0; iKLM < clusters.getEntries(); iKLM++) {
238 const TVector3 clusterMomentumCms = (T.rotateLabToCms() * clusters[iKLM]->getMomentum()).Vect();
239 double angle = pCms.Angle(clusterMomentumCms);
240 if (angle > maxAngle) maxAngle = angle;
245 double nKLMClusterTrackMatches(
const Particle* particle)
247 const KLMCluster* cluster = particle->getKLMCluster();
249 return std::numeric_limits<double>::quiet_NaN();
250 size_t out = cluster->getRelationsFrom<Track>().size();
254 double nMatchedKLMClusters(
const Particle* particle)
257 if (particleSource == Particle::EParticleSourceObject::c_Track) {
258 return particle->getTrack()->getRelationsTo<KLMCluster>().size();
259 }
else if (particleSource == Particle::EParticleSourceObject::c_ECLCluster) {
260 return particle->getECLCluster()->getRelationsTo<KLMCluster>().size();
262 return std::numeric_limits<double>::quiet_NaN();
266 double nKLMClusterECLClusterMatches(
const Particle* particle)
268 const KLMCluster* cluster = particle->getKLMCluster();
270 return std::numeric_limits<double>::quiet_NaN();
271 size_t out = cluster->getRelationsFrom<ECLCluster>().size();
275 double klmClusterTrackDistance(
const Particle* particle)
277 const KLMCluster* cluster = particle->getKLMCluster();
279 return std::numeric_limits<double>::quiet_NaN();
280 auto trackWithWeight = cluster->getRelatedFromWithWeight<Track>();
281 if (!trackWithWeight.first)
282 return std::numeric_limits<double>::quiet_NaN();
283 return 1. / trackWithWeight.second;
286 VARIABLE_GROUP(
"KLM Cluster and KlongID");
288 REGISTER_VARIABLE(
"klmClusterKlId", klmClusterKlId,
289 "Returns the KlId classifier output associated to the KLMCluster.");
290 REGISTER_VARIABLE(
"klmClusterBelleTrackFlag", klmClusterBelleTrackFlag,
291 "Returns the Belle-style Track flag.");
292 REGISTER_VARIABLE(
"klmClusterBelleECLFlag", klmClusterBelleECLFlag,
293 "Returns the Belle-style ECL flag.");
294 REGISTER_VARIABLE(
"klmClusterTiming", klmClusterTiming, R
"DOC(
295 Returns the timing informationf of the associated KLMCluster.
298 Currently the KLM has no time calibration. This leads to a huge discrepancy for the variable :b2:var:`klmClusterTiming` if one compares collisions and simulated data. Moreover, the distribution of the variable on collisions data has a very complicated structure, due to the different timing shifts of different KLM components.
299 It is recommended to not use it in any case until the KLM is calibrated, even for simulated data.
302 REGISTER_VARIABLE("klmClusterPositionX", klmClusterPositionX, R
"DOC(
303 Returns the :math:`x` position of the associated KLMCluster.
305 REGISTER_VARIABLE("klmClusterPositionY", klmClusterPositionY, R
"DOC(
306 Returns the :math:`y` position of the associated KLMCluster.
308 REGISTER_VARIABLE("klmClusterPositionZ", klmClusterPositionZ, R
"DOC(
309 Returns the :math:`z` position of the associated KLMCluster.
311 REGISTER_VARIABLE("klmClusterInnermostLayer", klmClusterInnermostLayer,
312 "Returns the number of the innermost KLM layer with a 2-dimensional hit of the associated KLMCluster.");
313 REGISTER_VARIABLE(
"klmClusterLayers", klmClusterLayers,
314 "Returns the number of KLM layers with 2-dimensional hits of the associated KLMCluster.");
315 REGISTER_VARIABLE(
"klmClusterEnergy", klmClusterEnergy, R
"DOC(
316 Returns the energy of the associated KLMCluster.
319 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`
320 (: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`).
321 It should be used with caution, and may not be physically meaningful, especially for :math:`n` candidates.
324 REGISTER_VARIABLE("klmClusterMomentum", klmClusterMomentum, R
"DOC(
325 Returns the momentum magnitude of the associated KLMCluster.
328 This variable returns an approximation of the momentum, since it is proportional to :b2:var:`klmClusterLayers`
329 (: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`).
330 It should be used with caution, and may not be physically meaningful.
333 REGISTER_VARIABLE("klmClusterIsBKLM", klmClusterIsBKLM,
334 "Returns 1 if the associated KLMCluster is in barrel KLM.");
335 REGISTER_VARIABLE(
"klmClusterIsEKLM", klmClusterIsEKLM,
336 "Returns 1 if the associated KLMCluster is in endcap KLM.");
337 REGISTER_VARIABLE(
"klmClusterIsForwardEKLM", klmClusterIsForwardEKLM,
338 "Returns 1 if the associated KLMCluster is in forward endcap KLM.");
339 REGISTER_VARIABLE(
"klmClusterIsBackwardEKLM", klmClusterIsBackwardEKLM,
340 "Returns 1 if the associated KLMCluster is in backward endcap KLM.");
341 REGISTER_VARIABLE(
"klmClusterTheta", klmClusterTheta, R
"DOC(
342 Returns the polar (:math:`\theta`) angle of the associated KLMCluster.
344 REGISTER_VARIABLE("klmClusterPhi", klmClusterPhi, R
"DOC(
345 Returns the azimuthal (:math:`\phi`) angle of the associated KLMCluster.
347 REGISTER_VARIABLE("maximumKLMAngleCMS", maximumKLMAngleCMS ,
348 "Returns the maximum angle in the CMS frame between the Particle and all KLMClusters in the event.");
349 REGISTER_VARIABLE(
"nKLMClusterTrackMatches", nKLMClusterTrackMatches, R
"DOC(
350 Returns 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.
352 REGISTER_VARIABLE("nMatchedKLMClusters", nMatchedKLMClusters, R
"DOC(
353 Returns the number of KLMClusters matched to the particle. It only works for
354 Particles created either from Tracks or from ECLCluster, while it returns NaN
355 for :math:`K_{L}^0` or :math:`n` candidates originating from KLMClusters.
357 REGISTER_VARIABLE("nKLMClusterECLClusterMatches", nKLMClusterECLClusterMatches, R
"DOC(
358 Returns the number of ECLClusters matched to the KLMCluster associated to this Particle.
360 REGISTER_VARIABLE("klmClusterTrackDistance", klmClusterTrackDistance, R
"DOC(
361 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.
365 When used over samples (data or MC) produced with release-06 or newer releases, the variable returns values
366 in cm; otherwise, over samples produced with release-05 or older releases, the variable returns values in mm.
EParticleSourceObject
particle source enumerators