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>
29 namespace Belle2::Variable {
31 double klmClusterKlId(
const Particle* particle)
33 const KLMCluster* cluster = particle->getKLMCluster();
35 return std::numeric_limits<double>::quiet_NaN();
37 const KlId* klid = cluster->getRelatedTo<KlId>();
39 return std::numeric_limits<double>::quiet_NaN();
41 return klid->getKlId();
44 int klmClusterBelleTrackFlag(
const Particle* particle)
46 const float angle = 0.24;
47 const KLMCluster* cluster = particle->getKLMCluster();
51 const B2Vector3D& pos = cluster->getClusterPosition();
52 StoreArray<TrackFitResult> tracks;
53 for (
const TrackFitResult& track : tracks) {
54 const B2Vector3D& trackPos = track.getPosition();
55 if (trackPos.Angle(pos) < angle) {
62 int klmClusterBelleECLFlag(
const Particle* particle)
64 const float angle = 0.24;
65 const KLMCluster* klmCluster = particle->getKLMCluster();
69 const B2Vector3D& klmClusterPos = klmCluster->getClusterPosition();
70 StoreArray<ECLCluster> eclClusters;
71 for (
const ECLCluster& eclCluster : eclClusters) {
72 const B2Vector3D& eclClusterPos = eclCluster.getClusterPosition();
73 if (eclClusterPos.Angle(klmClusterPos) < angle) {
80 double klmClusterTiming(
const Particle* particle)
82 const KLMCluster* cluster = particle->getKLMCluster();
84 return std::numeric_limits<double>::quiet_NaN();
86 return cluster->getTime();
90 double klmClusterPositionX(
const Particle* particle)
92 const KLMCluster* cluster = particle->getKLMCluster();
94 return std::numeric_limits<double>::quiet_NaN();
96 return cluster->getClusterPosition().X();
100 double klmClusterPositionY(
const Particle* particle)
102 const KLMCluster* cluster = particle->getKLMCluster();
104 return std::numeric_limits<double>::quiet_NaN();
106 return cluster->getClusterPosition().Y();
110 double klmClusterPositionZ(
const Particle* particle)
112 const KLMCluster* cluster = particle->getKLMCluster();
114 return std::numeric_limits<double>::quiet_NaN();
116 return cluster->getClusterPosition().Z();
120 double klmClusterInnermostLayer(
const Particle* particle)
122 const KLMCluster* cluster = particle->getKLMCluster();
124 return std::numeric_limits<double>::quiet_NaN();
126 return cluster->getInnermostLayer();
130 double klmClusterLayers(
const Particle* particle)
132 const KLMCluster* cluster = particle->getKLMCluster();
134 return std::numeric_limits<double>::quiet_NaN();
136 return cluster->getLayers();
139 double klmClusterEnergy(
const Particle* particle)
141 const KLMCluster* cluster = particle->getKLMCluster();
143 return std::numeric_limits<double>::quiet_NaN();
145 return cluster->getEnergy();
148 double klmClusterMomentum(
const Particle* particle)
150 const KLMCluster* cluster = particle->getKLMCluster();
152 return std::numeric_limits<double>::quiet_NaN();
154 return cluster->getMomentumMag();
157 double klmClusterIsBKLM(
const Particle* particle)
159 const KLMCluster* cluster = particle->getKLMCluster();
161 return std::numeric_limits<double>::quiet_NaN();
163 float clusterZ = cluster->getClusterPosition().Z();
164 if ((clusterZ > -180) && (clusterZ < 275)) {
170 double klmClusterIsEKLM(
const Particle* particle)
172 const KLMCluster* cluster = particle->getKLMCluster();
174 return std::numeric_limits<double>::quiet_NaN();
176 float clusterZ = cluster->getClusterPosition().Z();
177 if ((clusterZ < -180) || (clusterZ > 275)) {
183 double klmClusterIsForwardEKLM(
const Particle* particle)
185 const KLMCluster* cluster = particle->getKLMCluster();
187 return std::numeric_limits<double>::quiet_NaN();
189 float clusterZ = cluster->getClusterPosition().Z();
190 if (clusterZ > 275) {
196 double klmClusterIsBackwardEKLM(
const Particle* particle)
198 const KLMCluster* cluster = particle->getKLMCluster();
200 return std::numeric_limits<double>::quiet_NaN();
202 float clusterZ = cluster->getClusterPosition().Z();
203 if (clusterZ < -180) {
209 double klmClusterTheta(
const Particle* particle)
211 const KLMCluster* cluster = particle->getKLMCluster();
213 return std::numeric_limits<double>::quiet_NaN();
215 return cluster->getClusterPosition().Theta();
218 double klmClusterPhi(
const Particle* particle)
220 const KLMCluster* cluster = particle->getKLMCluster();
222 return std::numeric_limits<double>::quiet_NaN();
224 return cluster->getClusterPosition().Phi();
227 double maximumKLMAngleCMS(
const Particle* particle)
230 StoreArray<KLMCluster> clusters;
231 if (clusters.getEntries() == 0)
return std::numeric_limits<double>::quiet_NaN();
235 const B2Vector3D pCms = (T.rotateLabToCms() * particle->get4Vector()).Vect();
238 double maxAngle = 0.0;
239 for (
int iKLM = 0; iKLM < clusters.getEntries(); iKLM++) {
240 const B2Vector3D clusterMomentumCms = (T.rotateLabToCms() * clusters[iKLM]->getMomentum()).Vect();
241 double angle = pCms.
Angle(clusterMomentumCms);
242 if (angle > maxAngle) maxAngle = angle;
247 double nKLMClusterTrackMatches(
const Particle* particle)
249 const KLMCluster* cluster = particle->getKLMCluster();
251 return std::numeric_limits<double>::quiet_NaN();
252 size_t out = cluster->getRelationsFrom<Track>().size();
256 double nMatchedKLMClusters(
const Particle* particle)
259 if (particleSource == Particle::EParticleSourceObject::c_Track) {
260 return particle->getTrack()->getRelationsTo<KLMCluster>().size();
261 }
else if (particleSource == Particle::EParticleSourceObject::c_ECLCluster) {
262 return particle->getECLCluster()->getRelationsTo<KLMCluster>().size();
264 return std::numeric_limits<double>::quiet_NaN();
268 double nKLMClusterECLClusterMatches(
const Particle* particle)
270 const KLMCluster* cluster = particle->getKLMCluster();
272 return std::numeric_limits<double>::quiet_NaN();
273 size_t out = cluster->getRelationsFrom<ECLCluster>().size();
277 double klmClusterTrackDistance(
const Particle* particle)
279 const KLMCluster* cluster = particle->getKLMCluster();
281 return std::numeric_limits<double>::quiet_NaN();
282 auto trackWithWeight = cluster->getRelatedFromWithWeight<Track>();
283 if (!trackWithWeight.first)
284 return std::numeric_limits<double>::quiet_NaN();
285 return 1. / trackWithWeight.second;
288 VARIABLE_GROUP(
"KLM Cluster and KlongID");
290 REGISTER_VARIABLE(
"klmClusterKlId", klmClusterKlId,
291 "Returns the KlId classifier output associated to the KLMCluster.");
292 REGISTER_VARIABLE(
"klmClusterBelleTrackFlag", klmClusterBelleTrackFlag,
293 "Returns the Belle-style Track flag.");
294 REGISTER_VARIABLE(
"klmClusterBelleECLFlag", klmClusterBelleECLFlag,
295 "Returns the Belle-style ECL flag.");
296 REGISTER_VARIABLE(
"klmClusterTiming", klmClusterTiming, R
"DOC(
297 Returns the timing information of the associated KLMCluster.
300 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.
301 It is recommended to not use it in any case until the KLM is calibrated, even for simulated data.
304 REGISTER_VARIABLE("klmClusterPositionX", klmClusterPositionX, R"DOC(
305 Returns the :math:`x` position of the associated KLMCluster.
307 REGISTER_VARIABLE("klmClusterPositionY", klmClusterPositionY, R"DOC(
308 Returns the :math:`y` position of the associated KLMCluster.
310 REGISTER_VARIABLE("klmClusterPositionZ", klmClusterPositionZ, R"DOC(
311 Returns the :math:`z` position of the associated KLMCluster.
313 REGISTER_VARIABLE("klmClusterInnermostLayer", klmClusterInnermostLayer,
314 "Returns the number of the innermost KLM layer with a 2-dimensional hit of the associated KLMCluster.");
315 REGISTER_VARIABLE("klmClusterLayers", klmClusterLayers,
316 "Returns the number of KLM layers with 2-dimensional hits of the associated KLMCluster.");
317 REGISTER_VARIABLE("klmClusterEnergy", klmClusterEnergy, R"DOC(
318 Returns the energy of the associated KLMCluster.
321 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`
322 (: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`).
323 It should be used with caution, and may not be physically meaningful, especially for :math:`n` candidates.
326 REGISTER_VARIABLE("klmClusterMomentum", klmClusterMomentum, R"DOC(
327 Returns the momentum magnitude of the associated KLMCluster.
330 This variable returns an approximation of the momentum, since it is proportional to :b2:var:`klmClusterLayers`
331 (: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`).
332 It should be used with caution, and may not be physically meaningful.
335 REGISTER_VARIABLE("klmClusterIsBKLM", klmClusterIsBKLM,
336 "Returns 1 if the associated KLMCluster is in barrel KLM.");
337 REGISTER_VARIABLE("klmClusterIsEKLM", klmClusterIsEKLM,
338 "Returns 1 if the associated KLMCluster is in endcap KLM.");
339 REGISTER_VARIABLE("klmClusterIsForwardEKLM", klmClusterIsForwardEKLM,
340 "Returns 1 if the associated KLMCluster is in forward endcap KLM.");
341 REGISTER_VARIABLE("klmClusterIsBackwardEKLM", klmClusterIsBackwardEKLM,
342 "Returns 1 if the associated KLMCluster is in backward endcap KLM.");
343 REGISTER_VARIABLE("klmClusterTheta", klmClusterTheta, R"DOC(
344 Returns the polar (:math:`\theta`) angle of the associated KLMCluster.
346 REGISTER_VARIABLE("klmClusterPhi", klmClusterPhi, R"DOC(
347 Returns the azimuthal (:math:`\phi`) angle of the associated KLMCluster.
349 REGISTER_VARIABLE("maximumKLMAngleCMS", maximumKLMAngleCMS ,
350 "Returns the maximum angle in the CMS frame between the Particle and all KLMClusters in the event.","rad");
351 REGISTER_VARIABLE("nKLMClusterTrackMatches", nKLMClusterTrackMatches, R"DOC(
352 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.
354 REGISTER_VARIABLE("nMatchedKLMClusters", nMatchedKLMClusters, R
"DOC(
355 Returns the number of KLMClusters matched to the particle. It only works for
356 Particles created either from Tracks or from ECLCluster, while it returns NaN
357 for :math:`K_{L}^0` or :math:`n` candidates originating from KLMClusters.
359 REGISTER_VARIABLE("nKLMClusterECLClusterMatches", nKLMClusterECLClusterMatches, R
"DOC(
360 Returns the number of ECLClusters matched to the KLMCluster associated to this Particle.
362 REGISTER_VARIABLE("klmClusterTrackDistance", klmClusterTrackDistance,
363 "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.",
DataType Angle(const B2Vector3< DataType > &q) const
The angle w.r.t.
EParticleSourceObject
particle source enumerators
B2Vector3< double > B2Vector3D
typedef for common usage with double