Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-27 09:15:55

0001 /**
0002  *  @file   PandoraSDK/include/Objects/Cluster.h
0003  * 
0004  *  @brief  Header file for the cluster class.
0005  * 
0006  *  $Log: $
0007  */
0008 #ifndef PANDORA_CLUSTER_H
0009 #define PANDORA_CLUSTER_H 1
0010 
0011 #include "Helpers/ClusterFitHelper.h"
0012 
0013 #include "Objects/OrderedCaloHitList.h"
0014 
0015 #include "Pandora/ObjectCreation.h"
0016 #include "Pandora/StatusCodes.h"
0017 
0018 namespace pandora
0019 {
0020 
0021 class Pandora;
0022 template<typename T> class AlgorithmObjectManager;
0023 template<typename T, typename S> class PandoraObjectFactory;
0024 
0025 //------------------------------------------------------------------------------------------------------------------------------------------
0026 
0027 /**
0028  *  @brief  Cluster class
0029  */
0030 class Cluster
0031 {
0032 public:
0033     /**
0034      *  @brief  Get the ordered calo hit list
0035      * 
0036      *  @return The ordered calo hit list by reference
0037      */
0038     const OrderedCaloHitList &GetOrderedCaloHitList() const;
0039 
0040     /**
0041      *  @brief  Get the isolated calo hit list
0042      * 
0043      *  @return The isolated calo hit list by reference
0044      */
0045     const CaloHitList &GetIsolatedCaloHitList() const;
0046 
0047     /**
0048      *  @brief  Get the number of calo hits in the cluster
0049      * 
0050      *  @return The number of calo hits
0051      */
0052     unsigned int GetNCaloHits() const;
0053 
0054     /**
0055      *  @brief  Get the number of isolated calo hits in the cluster
0056      * 
0057      *  @return The number of isolated calo hits
0058      */
0059     unsigned int GetNIsolatedCaloHits() const;
0060 
0061     /**
0062      *  @brief  Get the number of calo hits in the cluster that have been flagged as possible mip hits
0063      * 
0064      *  @return The number of possible mip hits
0065      */
0066     unsigned int GetNPossibleMipHits() const;
0067 
0068     /**
0069      *  @brief  Get fraction of constituent calo hits that have been flagged as possible mip hits
0070      * 
0071      *  @return The mip fraction
0072      */
0073     float GetMipFraction() const;
0074 
0075     /**
0076      *  @brief  Get the number of hits in the outer sampling layers
0077      * 
0078      *  @return The number of hits in this cluster in the outermost sampling layer
0079      */
0080     unsigned int GetNHitsInOuterLayer() const;
0081 
0082     /**
0083      *  @brief  Get the sum of electromagnetic energy measures of all constituent calo hits, units GeV
0084      * 
0085      *  @return The electromagnetic energy measure
0086      */
0087     float GetElectromagneticEnergy() const;
0088 
0089     /**
0090      *  @brief  Get the sum of hadronic energy measures of all constituent calo hits, units GeV
0091      * 
0092      *  @return The hadronic energy measure
0093      */
0094     float GetHadronicEnergy() const;
0095 
0096     /**
0097      *  @brief  Get the sum of electromagnetic energy measures of isolated constituent calo hits, units GeV
0098      * 
0099      *  @return The electromagnetic energy measure
0100      */
0101     float GetIsolatedElectromagneticEnergy() const;
0102 
0103     /**
0104      *  @brief  Get the sum of hadronic energy measures of isolated constituent calo hits, units GeV
0105      * 
0106      *  @return The hadronic energy measure
0107      */
0108     float GetIsolatedHadronicEnergy() const;
0109 
0110     /**
0111      *  @brief  Get the particle id flag
0112      * 
0113      *  @return The particle id flag
0114      */
0115     int GetParticleId() const;
0116 
0117     /**
0118      *  @brief  Whether the cluster is track seeded
0119      * 
0120      *  @return boolean 
0121      */
0122     bool IsTrackSeeded() const;
0123 
0124     /**
0125      *  @brief  Get the address of the track with which the cluster is seeded
0126      * 
0127      *  @return address of the track seed
0128      */
0129     const Track *GetTrackSeed() const;
0130 
0131     /**
0132      *  @brief  Get the innermost pseudo layer in the cluster
0133      * 
0134      *  @return The innermost pseudo layer in the cluster
0135      */
0136     unsigned int GetInnerPseudoLayer() const;
0137 
0138     /**
0139      *  @brief  Get the outermost pseudo layer in the cluster
0140      * 
0141      *  @return The outermost pseudo layer in the cluster
0142      */
0143     unsigned int GetOuterPseudoLayer() const;
0144 
0145     /**
0146      *  @brief  Get unweighted centroid for cluster at a particular pseudo layer, calculated using cached values of hit coordinate sums
0147      * 
0148      *  @param  pseudoLayer the pseudo layer of interest
0149      * 
0150      *  @return The unweighted centroid, returned by value
0151      */
0152     const CartesianVector GetCentroid(const unsigned int pseudoLayer) const;
0153 
0154     /**
0155      *  @brief  Get the initial direction of the cluster
0156      * 
0157      *  @return The initial direction of the cluster
0158      */
0159     const CartesianVector &GetInitialDirection() const;
0160 
0161     /**
0162      *  @brief  Get the result of a linear fit to all calo hits in the cluster
0163      * 
0164      *  @return The cluster fit result
0165      */
0166     const ClusterFitResult &GetFitToAllHitsResult() const;
0167 
0168     /**
0169      *  @brief  Get the typical inner layer hit type
0170      * 
0171      *  @return The typical inner layer hit type
0172      */
0173     HitType GetInnerLayerHitType() const;
0174 
0175     /**
0176      *  @brief  Get the typical outer layer hit type
0177      * 
0178      *  @return The typical outer layer hit type
0179      */
0180     HitType GetOuterLayerHitType() const;
0181 
0182     /**
0183      *  @brief  Get the list of tracks associated with the cluster
0184      * 
0185      *  @return Address of the list of associated tracks
0186      */
0187     const TrackList &GetAssociatedTrackList() const;
0188 
0189     /**
0190      *  @brief  Whether the cluster is available to be added to a particle flow object
0191      * 
0192      *  @return boolean
0193      */
0194     bool IsAvailable() const;
0195 
0196     /**
0197      *  @brief  Get the corrected electromagnetic estimate of the cluster energy, units GeV
0198      * 
0199      *  @param  pandora the associated pandora instance
0200      * 
0201      *  @return The corrected electromagnetic energy estimate
0202      */
0203     float GetCorrectedElectromagneticEnergy(const Pandora &pandora) const;
0204 
0205     /**
0206      *  @brief  Get the corrected hadronic estimate of the cluster energy, units GeV
0207      * 
0208      *  @param  pandora the associated pandora instance
0209      * 
0210      *  @return The corrected hadronic energy estimate
0211      */
0212     float GetCorrectedHadronicEnergy(const Pandora &pandora) const;
0213 
0214     /**
0215      *  @brief  Get the best energy estimate to use when comparing cluster energy to associated track momentum, units GeV.
0216      *          For clusters identified as electromagnetic showers, the corrected electromagnetic energy will be returned.
0217      *          For all other clusters, the corrected hadronic energy will be returned.
0218      * 
0219      *  @param  pandora the associated pandora instance
0220      * 
0221      *  @return The track comparison energy estimate
0222      */
0223     float GetTrackComparisonEnergy(const Pandora &pandora) const;
0224 
0225     /**
0226      *  @brief  Whether the cluster passes the photon id
0227      * 
0228      *  @param  pandora the associated pandora instance
0229      * 
0230      *  @return boolean
0231      */
0232     bool PassPhotonId(const Pandora &pandora) const;
0233 
0234     /**
0235      *  @brief  Get the pseudo layer at which shower commences
0236      * 
0237      *  @param  pandora the associated pandora instance
0238      * 
0239      *  @return The pseudo layer at which shower commences
0240      */
0241     unsigned int GetShowerStartLayer(const Pandora &pandora) const;
0242 
0243     /**
0244      *  @brief  Get the cluster shower profile start, units radiation lengths
0245      * 
0246      *  @param  pandora the associated pandora instance
0247      * 
0248      *  @return The cluster shower profile start
0249      */
0250     float GetShowerProfileStart(const Pandora &pandora) const;
0251 
0252     /**
0253      *  @brief  Get the cluster shower profile discrepancy
0254      * 
0255      *  @param  pandora the associated pandora instance
0256      * 
0257      *  @return The cluster shower profile discrepancy
0258      */
0259     float GetShowerProfileDiscrepancy(const Pandora &pandora) const;
0260 
0261     /**
0262      *  @brief  Get minimum and maximum X positions of the calo hits in this cluster
0263      *
0264      *  @param  the minimum position of x
0265      *  @param  the maximum position of x
0266      */
0267     void GetClusterSpanX(float &xmin, float &xmax) const;
0268 
0269     /**
0270      *  @brief  Get upper and lower Z positions of the calo hits in a cluster in range xmin to xmax
0271      *
0272      *  @param  xmin for range in x
0273      *  @param  xmax for range in x
0274      *  @param  zmin the lower z for this range of x
0275      *  @param  zmax the upper z for this range in x
0276      */
0277     void GetClusterSpanZ(const float xmin, const float xmax, float &zmin, float &zmax) const;
0278 
0279 protected:
0280     /**
0281      *  @brief  Constructor
0282      * 
0283      *  @param  parameters the cluster parameters
0284      */
0285     Cluster(const object_creation::Cluster::Parameters &parameters);
0286 
0287     /**
0288      *  @brief  Destructor
0289      */
0290     virtual ~Cluster();
0291 
0292     /**
0293      *  @brief  Alter the metadata information stored in a cluster
0294      * 
0295      *  @param  metaData the metadata (only populated metadata fields will be propagated to the object)
0296      */
0297     StatusCode AlterMetadata(const object_creation::Cluster::Metadata &metadata);
0298 
0299     /**
0300      *  @brief  Add a calo hit to the cluster
0301      * 
0302      *  @param  pCaloHit the address of the calo hit
0303      */
0304     StatusCode AddCaloHit(const CaloHit *const pCaloHit);
0305 
0306     /**
0307      *  @brief  Remove a calo hit from the cluster
0308      * 
0309      *  @param  pCaloHit the address of the calo hit
0310      */
0311     StatusCode RemoveCaloHit(const CaloHit *const pCaloHit);
0312 
0313     /**
0314      *  @brief  Add an isolated calo hit to the cluster.
0315      * 
0316      *  @param  pCaloHit the address of the isolated calo hit
0317      */
0318     StatusCode AddIsolatedCaloHit(const CaloHit *const pCaloHit);
0319 
0320     /**
0321      *  @brief  Remove an isolated calo hit from the cluster
0322      * 
0323      *  @param  pCaloHit the address of the isolated calo hit
0324      */
0325     StatusCode RemoveIsolatedCaloHit(const CaloHit *const pCaloHit);
0326 
0327     /**
0328      *  @brief  Update result of linear fit to all calo hits in cluster
0329      */
0330     void UpdateFitToAllHitsCache() const;
0331 
0332     /**
0333      *  @brief  Update cluster initial direction
0334      */
0335     void UpdateInitialDirectionCache() const;
0336 
0337     /**
0338      *  @brief  Update typical hit type for specified layer
0339      * 
0340      *  @param  pseudoLayer the pseudo layer
0341      *  @param  layerHitType to receive the typical layer hit type
0342      */
0343     void UpdateLayerHitTypeCache(const unsigned int pseudoLayer, InputHitType &layerHitType) const;
0344 
0345     /**
0346      *  @brief  Update cluster corrected energy values
0347      * 
0348      *  @param  pandora the associated pandora instance
0349      */
0350     void UpdateEnergyCorrectionsCache(const Pandora &pandora) const;
0351 
0352     /**
0353      *  @brief  Update photon if flag
0354      * 
0355      *  @param  pandora the associated pandora instance
0356      */
0357     void UpdatePhotonIdCache(const Pandora &pandora) const;
0358 
0359     /**
0360      *  @brief  Update the pseudo layer at which shower commences
0361      * 
0362      *  @param  pandora the associated pandora instance
0363      */
0364     void UpdateShowerLayerCache(const Pandora &pandora) const;
0365 
0366     /**
0367      *  @brief  Update shower profile and comparison with expectation for a photon
0368      * 
0369      *  @param  pandora the associated pandora instance
0370      */
0371     void UpdateShowerProfileCache(const Pandora &pandora) const;
0372 
0373     /**
0374      *  @brief  Reset all cluster properties
0375      */
0376     StatusCode ResetProperties();
0377 
0378     /**
0379      *  @brief  Reset those cluster properties that must be recalculated upon addition/removal of a calo hit
0380      */
0381     void ResetOutdatedProperties();
0382 
0383     /**
0384      *  @brief  Add the calo hits from a second cluster to this
0385      * 
0386      *  @param  pCluster the address of the second cluster
0387      */
0388     StatusCode AddHitsFromSecondCluster(const Cluster *const pCluster);
0389 
0390     /**
0391      *  @brief  Add an association between the cluster and a track
0392      * 
0393      *  @param  pTrack the address of the track with which the cluster is associated
0394      */
0395     StatusCode AddTrackAssociation(const Track *const pTrack);
0396 
0397     /**
0398      *  @brief  Remove an association between the cluster and a track
0399      * 
0400      *  @param  pTrack the address of the track with which the cluster is no longer associated
0401      */
0402     StatusCode RemoveTrackAssociation(const Track *const pTrack);
0403 
0404     /**
0405      *  @brief  Remove the track seed, changing the initial direction measurement.
0406      */
0407     void RemoveTrackSeed();
0408 
0409     /**
0410      *  @brief  Set availability of cluster to be added to a particle flow object
0411      * 
0412      *  @param  isAvailable the cluster availability
0413      */
0414     void SetAvailability(bool isAvailable);
0415 
0416     /**
0417      *  @brief  SimplePoint class
0418      */
0419     class SimplePoint
0420     {
0421     public:
0422         double                  m_xyzPositionSums[3];           ///< The sum of the x, y and z hit positions in the pseudo layer
0423         unsigned int            m_nHits;                        ///< The number of hits in the pseudo layer
0424     };
0425 
0426     typedef std::map<unsigned int, SimplePoint> PointByPseudoLayerMap;///< The point by pseudo layer typedef
0427     typedef std::map<HitType, float> HitTypeToEnergyMap;        ///< The hit type to energy map typedef
0428 
0429     OrderedCaloHitList          m_orderedCaloHitList;           ///< The ordered calo hit list
0430     CaloHitList                 m_isolatedCaloHitList;          ///< The list of isolated hits, which contribute only towards cluster energy
0431     unsigned int                m_nCaloHits;                    ///< The number of calo hits
0432     unsigned int                m_nPossibleMipHits;             ///< The number of calo hits that have been flagged as possible mip hits
0433     unsigned int                m_nCaloHitsInOuterLayer;        ///< Keep track of the number of calo hits in the outermost layers
0434     double                      m_electromagneticEnergy;        ///< The sum of electromagnetic energy measures of constituent calo hits, units GeV
0435     double                      m_hadronicEnergy;               ///< The sum of hadronic energy measures of constituent calo hits, units GeV
0436     double                      m_isolatedElectromagneticEnergy;///< Sum of electromagnetic energy measures of isolated calo hits, units GeV
0437     double                      m_isolatedHadronicEnergy;       ///< Sum of hadronic energy measures of isolated calo hits, units GeV
0438     int                         m_particleId;                   ///< The particle id flag
0439     const Track                *m_pTrackSeed;                   ///< Address of the track with which the cluster is seeded
0440     PointByPseudoLayerMap       m_sumXYZByPseudoLayer;          ///< Construct to allow rapid calculation of centroid in each pseudolayer
0441     InputUInt                   m_innerPseudoLayer;             ///< The innermost pseudo layer in the cluster
0442     InputUInt                   m_outerPseudoLayer;             ///< The outermost pseudo layer in the cluster
0443 
0444     mutable CartesianVector     m_initialDirection;             ///< The initial direction of the cluster
0445     mutable bool                m_isDirectionUpToDate;          ///< Whether the initial direction of the cluster is up to date
0446     mutable ClusterFitResult    m_fitToAllHitsResult;           ///< The result of a linear fit to all calo hits in the cluster
0447     mutable bool                m_isFitUpToDate;                ///< Whether the fit to all calo hits is up to date
0448     mutable InputFloat          m_correctedElectromagneticEnergy;///< The corrected electromagnetic estimate of the cluster energy, units GeV
0449     mutable InputFloat          m_correctedHadronicEnergy;      ///< The corrected hadronic estimate of the cluster energy, units GeV
0450     mutable InputFloat          m_trackComparisonEnergy;        ///< The appropriate corrected energy to use in comparisons with track momentum, units GeV
0451     mutable InputBool           m_passPhotonId;                 ///< Whether the cluster passes the photon id
0452     mutable InputUInt           m_showerStartLayer;             ///< The pseudo layer at which shower commences
0453     mutable InputFloat          m_showerProfileStart;           ///< The cluster shower profile start, units radiation lengths
0454     mutable InputFloat          m_showerProfileDiscrepancy;     ///< The cluster shower profile discrepancy
0455     mutable InputHitType        m_innerLayerHitType;            ///< The typical inner layer hit type
0456     mutable InputHitType        m_outerLayerHitType;            ///< The typical outer layer hit type
0457     mutable InputFloat          m_xMin;                         ///< Cached cluster minimum in x
0458     mutable InputFloat          m_xMax;                         ///< Cached cluster maximum in x
0459 
0460     TrackList                   m_associatedTrackList;          ///< The list of tracks associated with the cluster
0461     bool                        m_isAvailable;                  ///< Whether the cluster is available to be added to a particle flow object
0462 
0463     friend class ClusterManager;
0464     friend class AlgorithmObjectManager<Cluster>;
0465     friend class PandoraObjectFactory<object_creation::Cluster::Parameters, object_creation::Cluster::Object>;
0466 };
0467 
0468 //------------------------------------------------------------------------------------------------------------------------------------------
0469 
0470 inline const OrderedCaloHitList &Cluster::GetOrderedCaloHitList() const
0471 {
0472     return m_orderedCaloHitList;
0473 }
0474 
0475 //------------------------------------------------------------------------------------------------------------------------------------------
0476 
0477 inline const CaloHitList &Cluster::GetIsolatedCaloHitList() const
0478 {
0479     return m_isolatedCaloHitList;
0480 }
0481 
0482 //------------------------------------------------------------------------------------------------------------------------------------------
0483 
0484 inline unsigned int Cluster::GetNCaloHits() const
0485 {
0486     return m_nCaloHits;
0487 }
0488 
0489 //------------------------------------------------------------------------------------------------------------------------------------------
0490 
0491 inline unsigned int Cluster::GetNIsolatedCaloHits() const
0492 {
0493     return m_isolatedCaloHitList.size();
0494 }
0495 
0496 //------------------------------------------------------------------------------------------------------------------------------------------
0497 
0498 inline unsigned int Cluster::GetNPossibleMipHits() const
0499 {
0500     return m_nPossibleMipHits;
0501 }
0502 
0503 //------------------------------------------------------------------------------------------------------------------------------------------
0504 
0505 inline float Cluster::GetMipFraction() const
0506 {
0507     return ((0 != m_nCaloHits) ? static_cast<float> (m_nPossibleMipHits) / static_cast<float> (m_nCaloHits) : 0);
0508 }
0509 
0510 //------------------------------------------------------------------------------------------------------------------------------------------
0511 
0512 inline unsigned int Cluster::GetNHitsInOuterLayer() const
0513 {
0514     return m_nCaloHitsInOuterLayer;
0515 }
0516 
0517 //------------------------------------------------------------------------------------------------------------------------------------------
0518 
0519 inline float Cluster::GetElectromagneticEnergy() const
0520 {
0521     return static_cast<float>(m_electromagneticEnergy);
0522 }
0523 
0524 //------------------------------------------------------------------------------------------------------------------------------------------
0525 
0526 inline float Cluster::GetHadronicEnergy() const
0527 {
0528     return static_cast<float>(m_hadronicEnergy);
0529 }
0530 
0531 //------------------------------------------------------------------------------------------------------------------------------------------
0532 
0533 inline float Cluster::GetIsolatedElectromagneticEnergy() const
0534 {
0535     return static_cast<float>(m_isolatedElectromagneticEnergy);
0536 }
0537 
0538 //------------------------------------------------------------------------------------------------------------------------------------------
0539 
0540 inline float Cluster::GetIsolatedHadronicEnergy() const
0541 {
0542     return static_cast<float>(m_isolatedHadronicEnergy);
0543 }
0544 
0545 //------------------------------------------------------------------------------------------------------------------------------------------
0546 
0547 inline int Cluster::GetParticleId() const
0548 {
0549     return m_particleId;
0550 }
0551 
0552 //------------------------------------------------------------------------------------------------------------------------------------------
0553 
0554 inline bool Cluster::IsTrackSeeded() const
0555 {
0556     return (nullptr != m_pTrackSeed);
0557 }
0558 
0559 //------------------------------------------------------------------------------------------------------------------------------------------
0560 
0561 inline unsigned int Cluster::GetInnerPseudoLayer() const
0562 {
0563     return m_innerPseudoLayer.Get();
0564 }
0565 
0566 //------------------------------------------------------------------------------------------------------------------------------------------
0567 
0568 inline unsigned int Cluster::GetOuterPseudoLayer() const
0569 {
0570     return m_outerPseudoLayer.Get();
0571 }
0572 
0573 //------------------------------------------------------------------------------------------------------------------------------------------
0574 
0575 inline const TrackList &Cluster::GetAssociatedTrackList() const
0576 {
0577     return m_associatedTrackList;
0578 }
0579 
0580 //------------------------------------------------------------------------------------------------------------------------------------------
0581 
0582 inline bool Cluster::IsAvailable() const
0583 {
0584     return m_isAvailable;
0585 }
0586 
0587 //------------------------------------------------------------------------------------------------------------------------------------------
0588 
0589 inline void Cluster::SetAvailability(bool isAvailable)
0590 {
0591     m_isAvailable = isAvailable;
0592 }
0593 
0594 } // namespace pandora
0595 
0596 #endif // #ifndef PANDORA_CLUSTER_H