Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-27 09:13:45

0001 /**
0002  *  @file   PandoraSDK/include/Helpers/ClusterFitHelper.h
0003  * 
0004  *  @brief  Header file for the cluster fit helper class.
0005  * 
0006  *  $Log: $
0007  */
0008 #ifndef PANDORA_CLUSTER_FIT_HELPER_H
0009 #define PANDORA_CLUSTER_FIT_HELPER_H 1
0010 
0011 #include "Pandora/PandoraInputTypes.h"
0012 #include "Pandora/PandoraInternal.h"
0013 
0014 namespace pandora
0015 {
0016 
0017 /**
0018  *  @brief  ClusterFitPoint class
0019  */
0020 class ClusterFitPoint
0021 {
0022 public:
0023     /**
0024      *  @brief  Constructor
0025      * 
0026      *  @param  pCaloHit address of a calo hit on which to base the cluster fit point
0027      */
0028     ClusterFitPoint(const CaloHit *const pCaloHit);
0029 
0030     /**
0031      *  @brief  Constructor
0032      * 
0033      *  @param  position the position vector of the fit point
0034      *  @param  cellNormalVector the unit normal vector to the cell in which the point was recorded
0035      *  @param  cellSize the size of the cell in which the point was recorded
0036      *  @param  energy the energy deposited in the cell in which the point was recorded
0037      *  @param  pseudoLayer the pseudolayer in which the point was recorded
0038      */
0039     ClusterFitPoint(const CartesianVector &position, const CartesianVector &cellNormalVector, const float cellSize,
0040         const float energy, const unsigned int pseudoLayer);
0041 
0042     /**
0043      *  @brief  Get the position vector of the fit point
0044      * 
0045      *  @return the position vector of the fit point
0046      */
0047     const CartesianVector &GetPosition() const;
0048 
0049     /**
0050      *  @brief  Get the unit normal vector to the cell in which the point was recorded
0051      * 
0052      *  @return the unit normal vector to the cell in which the point was recorded
0053      */
0054     const CartesianVector &GetCellNormalVector() const;
0055 
0056     /**
0057      *  @brief  Get the size of the cell in which the point was recorded
0058      * 
0059      *  @return the size of the cell in which the point was recorded
0060      */
0061     float GetCellSize() const;
0062 
0063     /**
0064      *  @brief  Get the energy deposited in the cell in which the point was recorded
0065      * 
0066      *  @return energy deposited in the cell in which the point was recorded
0067      */
0068     float GetEnergy() const;
0069 
0070     /**
0071      *  @brief  Get the pseudolayer in which the point was recorded
0072      * 
0073      *  @return the pseudolayer in which the point was recorded
0074      */
0075     unsigned int GetPseudoLayer() const;
0076 
0077     /**
0078      *  @brief  operator< to define an ordering for cluster fit points
0079      * 
0080      *  @param  rhs the cluster fit point for comparison
0081      * 
0082      *  @return boolean
0083      */
0084     bool operator<(const ClusterFitPoint &rhs) const;
0085 
0086 private:
0087     CartesianVector         m_position;              ///< The position vector of the fit point
0088     CartesianVector         m_cellNormalVector;      ///< The unit normal vector to the cell in which the point was recorded
0089     float                   m_cellSize;              ///< The size of the cell in which the point was recorded
0090     float                   m_energy;                ///< The energy deposited in the cell in which the point was recorded
0091     unsigned int            m_pseudoLayer;           ///< The pseudolayer in which the point was recorded
0092 };
0093 
0094 typedef std::vector<ClusterFitPoint> ClusterFitPointList;
0095 
0096 //------------------------------------------------------------------------------------------------------------------------------------------
0097 
0098 /**
0099  *  @brief  ClusterFitResult class
0100  */
0101 class ClusterFitResult
0102 {
0103 public:
0104     /**
0105      *  @brief  Default constructor
0106      */
0107     ClusterFitResult();
0108 
0109     /**
0110      *  @brief  Query whether fit was successful
0111      * 
0112      *  @return boolean
0113      */
0114     bool IsFitSuccessful() const;
0115 
0116     /**
0117      *  @brief  Get the fit direction
0118      * 
0119      *  @return the fit direction
0120      */
0121     const CartesianVector &GetDirection() const;
0122 
0123     /**
0124      *  @brief  Get the fit intercept
0125      * 
0126      *  @return the fit intercept
0127      */
0128     const CartesianVector &GetIntercept() const;
0129 
0130     /**
0131      *  @brief  Get the fit ch2
0132      * 
0133      *  @return the fit chi2
0134      */
0135     float GetChi2() const;
0136 
0137     /**
0138      *  @brief  Get the fit rms
0139      * 
0140      *  @return the fit rms
0141      */
0142     float GetRms() const;
0143 
0144     /**
0145      *  @brief  Get the fit direction cosine w.r.t. the radial direction
0146      * 
0147      *  @return the fit direction cosine w.r.t. the radial direction
0148      */
0149     float GetRadialDirectionCosine() const;
0150 
0151     /**
0152      *  @brief  Set the fit success flag
0153      * 
0154      *  @param  successFlag the fit success flag
0155      */
0156     void SetSuccessFlag(const bool successFlag);
0157 
0158     /**
0159      *  @brief  Set the fit direction
0160      * 
0161      *  @param  direction the fit direction
0162      */
0163     void SetDirection(const CartesianVector &direction);
0164 
0165     /**
0166      *  @brief  Set the fit intercept
0167      * 
0168      *  @param  intercept the fit intercept
0169      */
0170     void SetIntercept(const CartesianVector &intercept);
0171 
0172     /**
0173      *  @brief  Set the fit chi2
0174      * 
0175      *  @param  chi2 the fit chi2
0176      */
0177     void SetChi2(const float chi2);
0178 
0179     /**
0180      *  @brief  Set the fit rms
0181      * 
0182      *  @param  rms the fit rms
0183      */
0184     void SetRms(const float rms);
0185 
0186     /**
0187      *  @brief  Set the fit direction cosine w.r.t. the radial direction
0188      * 
0189      *  @param  radialDirectionCosine the fit direction cosine w.r.t. the radial direction
0190      */
0191     void SetRadialDirectionCosine(const float radialDirectionCosine);
0192 
0193     /**
0194      *  @brief  Reset the cluster fit result
0195      */
0196     void Reset();
0197 
0198 private:
0199     bool                    m_isFitSuccessful;       ///< Whether the fit was successful
0200     CartesianVector         m_direction;             ///< The best fit direction
0201     CartesianVector         m_intercept;             ///< The best fit intercept
0202     InputFloat              m_chi2;                  ///< The chi2 value for the fit
0203     InputFloat              m_rms;                   ///< The rms of the fit
0204     InputFloat              m_dirCosR;               ///< The direction cosine wrt to the radial direction
0205 };
0206 
0207 typedef std::vector<ClusterFitResult> ClusterFitResultList;
0208 
0209 //------------------------------------------------------------------------------------------------------------------------------------------
0210 
0211 /**
0212  *  @brief  ClusterFitHelper class
0213  */
0214 class ClusterFitHelper
0215 {
0216 public:
0217     /**
0218      *  @brief  Fit points in first n occupied pseudolayers of a cluster
0219      * 
0220      *  @param  pCluster the cluster containing the ordered list of calo hits to fit
0221      *  @param  maxOccupiedLayers the maximum number of occupied pseudo layers to consider
0222      *  @param  clusterFitResult to receive the cluster fit result
0223      */
0224     static StatusCode FitStart(const Cluster *const pCluster, const unsigned int maxOccupiedLayers, ClusterFitResult &clusterFitResult);
0225 
0226     /**
0227      *  @brief  Fit points in last n occupied pseudolayers of a cluster
0228      * 
0229      *  @param  pCluster the cluster containing the ordered list of calo hits to fit
0230      *  @param  maxOccupiedLayers the maximum number of occupied pseudo layers to consider
0231      *  @param  clusterFitResult to receive the cluster fit result
0232      */
0233     static StatusCode FitEnd(const Cluster *const pCluster, const unsigned int maxOccupiedLayers, ClusterFitResult &clusterFitResult);
0234 
0235     /**
0236      *  @brief  Fit all points in a cluster
0237      * 
0238      *  @param  pCluster the cluster containing the ordered list of calo hits to fit
0239      *  @param  clusterFitResult to receive the cluster fit result
0240      */
0241     static StatusCode FitFullCluster(const Cluster *const pCluster, ClusterFitResult &clusterFitResult);
0242 
0243     /**
0244      *  @brief  Fit all cluster points within the specified (inclusive) pseudolayer range
0245      * 
0246      *  @param  pCluster the cluster containing the ordered list of calo hits to fit
0247      *  @param  startLayer the start of the pseudolayer range
0248      *  @param  endLayer the end of the pseudolayer range
0249      *  @param  clusterFitResult to receive the cluster fit result
0250      */
0251     static StatusCode FitLayers(const Cluster *const pCluster, const unsigned int startLayer, const unsigned int endLayer,
0252         ClusterFitResult &clusterFitResult);
0253 
0254     /**
0255      *  @brief  Fit all cluster centroids within the specified (inclusive) pseudolayer range
0256      * 
0257      *  @param  pCluster the cluster containing the ordered list of calo hits to fit
0258      *  @param  startLayer the start of the pseudolayer range
0259      *  @param  endLayer the end of the pseudolayer range
0260      *  @param  clusterFitResult to receive the cluster fit result
0261      */
0262     static StatusCode FitLayerCentroids(const Cluster *const pCluster, const unsigned int startLayer, const unsigned int endLayer,
0263         ClusterFitResult &clusterFitResult);
0264 
0265     /**
0266      *  @brief  Perform linear regression of x vs d and y vs d and z vs d (assuming same error on all hits)
0267      * 
0268      *  @param  clusterFitPointList list of cluster fit points
0269      *  @param  clusterFitResult to receive the cluster fit result
0270      */
0271     static StatusCode FitPoints(ClusterFitPointList &clusterFitPointList, ClusterFitResult &clusterFitResult);
0272 
0273 private:
0274     /**
0275      *  @brief  Perform linear fit to cluster fit points
0276      * 
0277      *  @param  centralPosition central position of the cluster fit points
0278      *  @param  centralDirection central direction of normal to cluster fit calorimeter cells
0279      *  @param  clusterFitPointList list of cluster fit points
0280      *  @param  clusterFitResult to receive the cluster fit result
0281      */
0282     static StatusCode PerformLinearFit(const CartesianVector &centralPosition, const CartesianVector &centralDirection,
0283         ClusterFitPointList &clusterFitPointList, ClusterFitResult &clusterFitResult);
0284 };
0285 
0286 //------------------------------------------------------------------------------------------------------------------------------------------
0287 //------------------------------------------------------------------------------------------------------------------------------------------
0288 
0289 inline const CartesianVector &ClusterFitPoint::GetPosition() const
0290 {
0291     return m_position;
0292 }
0293 
0294 //------------------------------------------------------------------------------------------------------------------------------------------
0295 
0296 inline const CartesianVector &ClusterFitPoint::GetCellNormalVector() const
0297 {
0298     return m_cellNormalVector;
0299 }
0300 
0301 //------------------------------------------------------------------------------------------------------------------------------------------
0302 
0303 inline float ClusterFitPoint::GetCellSize() const
0304 {
0305     return m_cellSize;
0306 }
0307 
0308 //------------------------------------------------------------------------------------------------------------------------------------------
0309 
0310 inline float ClusterFitPoint::GetEnergy() const
0311 {
0312     return m_energy;
0313 }
0314 
0315 //------------------------------------------------------------------------------------------------------------------------------------------
0316 
0317 inline unsigned int ClusterFitPoint::GetPseudoLayer() const
0318 {
0319     return m_pseudoLayer;
0320 }
0321 
0322 //------------------------------------------------------------------------------------------------------------------------------------------
0323 //------------------------------------------------------------------------------------------------------------------------------------------
0324 
0325 inline ClusterFitResult::ClusterFitResult() :
0326     m_isFitSuccessful(false),
0327     m_direction(0.f, 0.f, 0.f),
0328     m_intercept(0.f, 0.f, 0.f)
0329 {
0330 }
0331 
0332 //------------------------------------------------------------------------------------------------------------------------------------------
0333 
0334 inline bool ClusterFitResult::IsFitSuccessful() const
0335 {
0336     return m_isFitSuccessful;
0337 }
0338 
0339 //------------------------------------------------------------------------------------------------------------------------------------------
0340 
0341 inline const CartesianVector &ClusterFitResult::GetDirection() const
0342 {
0343     if (!m_isFitSuccessful)
0344         throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
0345 
0346     return m_direction;
0347 }
0348 
0349 //------------------------------------------------------------------------------------------------------------------------------------------
0350 
0351 inline const CartesianVector &ClusterFitResult::GetIntercept() const
0352 {
0353     if (!m_isFitSuccessful)
0354         throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
0355 
0356     return m_intercept;
0357 }
0358 
0359 //------------------------------------------------------------------------------------------------------------------------------------------
0360 
0361 inline float ClusterFitResult::GetChi2() const
0362 {
0363     if (!m_isFitSuccessful)
0364         throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
0365 
0366     return m_chi2.Get();
0367 }
0368 
0369 //------------------------------------------------------------------------------------------------------------------------------------------
0370 
0371 inline float ClusterFitResult::GetRms() const
0372 {
0373     if (!m_isFitSuccessful)
0374         throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
0375 
0376     return m_rms.Get();
0377 }
0378 
0379 //------------------------------------------------------------------------------------------------------------------------------------------
0380 
0381 inline float ClusterFitResult::GetRadialDirectionCosine() const
0382 {
0383     if (!m_isFitSuccessful)
0384         throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
0385 
0386     return m_dirCosR.Get();
0387 }
0388 
0389 //------------------------------------------------------------------------------------------------------------------------------------------
0390 
0391 inline void ClusterFitResult::SetSuccessFlag(bool successFlag)
0392 {
0393     m_isFitSuccessful = successFlag;
0394 }
0395 
0396 //------------------------------------------------------------------------------------------------------------------------------------------
0397 
0398 inline void ClusterFitResult::SetDirection(const CartesianVector &direction)
0399 {
0400     m_direction = direction;
0401 }
0402 
0403 //------------------------------------------------------------------------------------------------------------------------------------------
0404 
0405 inline void ClusterFitResult::SetIntercept(const CartesianVector &intercept)
0406 {
0407     m_intercept = intercept;
0408 }
0409 
0410 //------------------------------------------------------------------------------------------------------------------------------------------
0411 
0412 inline void ClusterFitResult::SetChi2(const float chi2)
0413 {
0414     m_chi2 = chi2;
0415     if (!m_chi2.IsInitialized())
0416         throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
0417 }
0418 
0419 //------------------------------------------------------------------------------------------------------------------------------------------
0420 
0421 inline void ClusterFitResult::SetRms(const float rms)
0422 {
0423     m_rms = rms;
0424     if (!m_rms.IsInitialized())
0425         throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
0426 }
0427 
0428 //------------------------------------------------------------------------------------------------------------------------------------------
0429 
0430 inline void ClusterFitResult::SetRadialDirectionCosine(const float radialDirectionCosine)
0431 {
0432     m_dirCosR = radialDirectionCosine;
0433     if (!m_dirCosR.IsInitialized())
0434         throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
0435 }
0436 
0437 //------------------------------------------------------------------------------------------------------------------------------------------
0438 
0439 inline void ClusterFitResult::Reset()
0440 {
0441     m_isFitSuccessful = false;
0442     m_direction.SetValues(0.f, 0.f, 0.f);
0443     m_intercept.SetValues(0.f, 0.f, 0.f);
0444     m_chi2.Reset();
0445     m_rms.Reset();
0446     m_dirCosR.Reset();
0447 }
0448 
0449 } // namespace pandora
0450 
0451 #endif // #ifndef PANDORA_CLUSTER_FIT_HELPER_H