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