Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-27 09:14:59

0001 /**
0002  *  @file   LCContent/include/LCParticleId/PhotonReconstructionAlgorithm.h
0003  *
0004  *  @brief  Header file for the photon reconstruction algorithm class.
0005  *
0006  *  $Log: $
0007  */
0008 #ifndef LC_PHOTON_RECONSTRUCTION_ALGORITHM_H
0009 #define LC_PHOTON_RECONSTRUCTION_ALGORITHM_H 1
0010 
0011 #include "Pandora/Algorithm.h"
0012 #include "Plugins/ShowerProfilePlugin.h"
0013 
0014 namespace pandora {
0015 class TiXmlDocument;
0016 }
0017 
0018 namespace lc_content {
0019 
0020 /**
0021  *  @brief  PhotonReconstructionAlgorithm class
0022  */
0023 class PhotonReconstructionAlgorithm : public pandora::Algorithm {
0024 public:
0025   /**
0026    *  @brief Default constructor
0027    */
0028   PhotonReconstructionAlgorithm();
0029 
0030   /**
0031    *  @param  Destructor
0032    */
0033   ~PhotonReconstructionAlgorithm();
0034 
0035 private:
0036   /**
0037    *  @brief  pdf variables
0038    */
0039   enum PDFVar { PEAKRMS, RMSXYRATIO, LONGPROFILESTART, LONGPROFILEDISCREPANCY, PEAKENERGYFRACTION, MINDISTANCETOTRACK };
0040 
0041   /**
0042    *  @brief  likelihood pdf obejct class
0043    */
0044   class LikelihoodPDFObject {
0045   public:
0046     LikelihoodPDFObject(const std::string& pdfVarName);
0047 
0048     std::string m_pdfVarName;              /// pdf variable name
0049     int m_nBins;                           /// number of bins
0050     float m_lowValue;                      /// The min value
0051     float m_highValue;                     /// The max value
0052     pandora::Histogram** m_pSignalPDF;     /// The signal pdf
0053     pandora::Histogram** m_pBackgroundPDF; /// The background pdf
0054   };
0055 
0056   typedef std::map<PDFVar, LikelihoodPDFObject> PDFVarLikelihoodPDFMap; /// The pdf variable to pdf object map
0057   typedef std::map<PDFVar, float> PDFVarFloatMap;                       /// The pdf variable to float object map
0058 
0059   pandora::StatusCode Run();
0060 
0061   /**
0062    *  @brief  Set input cluster list name
0063    *
0064    *  @param  inputClusterListName input cluster list name
0065    */
0066   pandora::StatusCode InitialiseInputClusterListName(std::string& inputClusterListName) const;
0067 
0068   /**
0069    *  @brief  Create clusters of interest
0070    *
0071    *  @param  clusterVector to receive clusters of interests
0072    */
0073   pandora::StatusCode CreateClustersOfInterest(pandora::ClusterVector& clusterVector) const;
0074 
0075   /**
0076    *  @brief  Get all tracks from event track list and put into a vector
0077    *
0078    *  @param  trackVector all tracks in vector to receive
0079    */
0080   pandora::StatusCode GetTrackVectors(pandora::TrackVector& trackVector) const;
0081 
0082   /**
0083    *  @brief  True for passing pre selection cut. Ideally loose cuts to rejet non interesting cluster
0084    *
0085    *  @param  pCluster address of the cluster
0086    *
0087    *  @return True for passing pre selection cut.
0088    */
0089   bool PassClusterQualityPreCut(const pandora::Cluster* const pCluster) const;
0090 
0091   /**
0092    *  @brief  Get individual showers(clusters) from the big cluster, for the cluster far from charged tracks projection.
0093    * Main power horse
0094    *
0095    *  @param  pCluster address of the cluster
0096    *  @param  showersPhoton shower peak list of photon candidates from the big cluster
0097    */
0098   pandora::StatusCode GetTracklessClusterShowerList(const pandora::Cluster* const pCluster,
0099                                                     pandora::ShowerProfilePlugin::ShowerPeakList& showersPhoton) const;
0100 
0101   /**
0102    *  @brief  Get individual showers(clusters) from the big cluster, for the cluster close to charged tracks projection.
0103    * Main power horse
0104    *
0105    *  @param  pCluster address of the cluster
0106    *  @param  pMinTrack address of the cloeset track to the cluster
0107    *  @param  trackVector the vector of all tracks
0108    *  @param  showersPhoton shower peak list of photon candidates from the big cluster
0109    *  @param  showersCharged shower peak list of non photon candidates from the big cluster
0110    */
0111   pandora::StatusCode GetTrackClusterShowerList(const pandora::Cluster* const pCluster,
0112                                                 const pandora::Track* const pMinTrack,
0113                                                 const pandora::TrackVector trackVector,
0114                                                 pandora::ShowerProfilePlugin::ShowerPeakList& showersPhoton,
0115                                                 pandora::ShowerProfilePlugin::ShowerPeakList& showersCharged) const;
0116 
0117   /**
0118    *  @brief  Create photons by checking and setting photon id
0119    *
0120    *  @param  pCluster address of the cluster
0121    *  @param  showersPhoton shower peak list of photon candidates from the big cluster
0122    *  @param  isFromTrack true for a cluster close to a track
0123    */
0124   pandora::StatusCode CreatePhotons(const pandora::Cluster* const pCluster,
0125                                     const pandora::ShowerProfilePlugin::ShowerPeakList& showersPhoton,
0126                                     const bool isFromTrack) const;
0127 
0128   /**
0129    *  @brief  Initialise fragmentation
0130    *
0131    *  @param  pCluster address of the cluster
0132    *  @param  originalClusterListName original cluster list name
0133    *  @param  peakClusterListName new cluster list name
0134    */
0135   pandora::StatusCode InitialiseFragmentation(const pandora::Cluster* const pCluster,
0136                                               std::string& originalClusterListName,
0137                                               std::string& peakClusterListName) const;
0138 
0139   /**
0140    *  @brief  End fragmentation. Revert back to the correct cluster list depending on whether the cluster is used
0141    *
0142    *  @param  usedCluster true for any part of cluster is a photon
0143    *  @param  originalClusterListName original cluster list name
0144    *  @param  peakClusterListName new cluster list name
0145    */
0146   pandora::StatusCode EndFragmentation(const bool usedCluster, const std::string& originalClusterListName,
0147                                        const std::string& peakClusterListName) const;
0148 
0149   /**
0150    *  @brief  Create a photon by checking and setting photon id
0151    *
0152    *  @param  showersPhoton shower peak list for photon candidate
0153    *  @param  wholeClusuterEnergy the total energy of the big cluster where the shower peak comes from
0154    *  @param  usedCluster true for the cluster is a photon to receive
0155    *  @param  isFromTrack true for the cluster close to a track
0156    */
0157   pandora::StatusCode CreateClustersAndSetPhotonID(const pandora::ShowerProfilePlugin::ShowerPeakList& showersPhoton,
0158                                                    const float wholeClusuterEnergy, bool& usedCluster,
0159                                                    const bool isFromTrack) const;
0160 
0161   /**
0162    *  @brief  Create a photon and modify the particle id to photon
0163    *
0164    *  @param  showerPeak shower peak list for photon candidate
0165    *  @param  pPeakCluster address of the photon to form
0166    */
0167   pandora::StatusCode CreateCluster(const pandora::ShowerProfilePlugin::ShowerPeak& showerPeak,
0168                                     const pandora::Cluster*& pPeakCluster) const;
0169 
0170   /**
0171    *  @brief  Check and set photon id for a cluster
0172    *
0173    *  @param  showerPeak shower peak list for photon candidate
0174    *  @param  pPeakCluster address of the photon candidate
0175    *  @param  wholeClusuterEnergy the total energy of the big cluster where the shower peak comes from
0176    *  @param  isPhoton true for the cluster is a photon to receive
0177    *  @param  isFromTrack true for the cluster close to a track
0178    */
0179   pandora::StatusCode CheckAndSetPhotonID(const pandora::ShowerProfilePlugin::ShowerPeak& showerPeak,
0180                                           const pandora::Cluster* const pPeakCluster, const float wholeClusuterEnergy,
0181                                           bool& isPhoton, const bool isFromTrack) const;
0182 
0183   /**
0184    *  @brief  Calculate quantities for photon id pdf test
0185    *
0186    *  @param  showerPeak shower peak list for photon candidate
0187    *  @param  pPeakCluster address of the photon candidate
0188    *  @param  wholeClusuterEnergy the total energy of the big cluster where the shower peak comes from
0189    *  @param  pdfVarFloatMap a varible to value map to store quantities for checking photon id
0190    */
0191   pandora::StatusCode CalculateForPhotonID(const pandora::ShowerProfilePlugin::ShowerPeak& showerPeak,
0192                                            const pandora::Cluster* const pPeakCluster, const float wholeClusuterEnergy,
0193                                            PDFVarFloatMap& pdfVarFloatMap) const;
0194 
0195   /**
0196    *  @brief  Use likelihood pdf to check photon id
0197    *
0198    *  @param  pPeakCluster address of the photon candidate
0199    *  @param  pdfVarFloatMap a varible to value map to store quantities for checking photon id
0200    *  @param  isFromTrack true for the cluster close to a track
0201    */
0202   bool IsPhoton(const pandora::Cluster* const pPeakCluster, const PDFVarFloatMap& pdfVarFloatMap,
0203                 const bool isFromTrack) const;
0204 
0205   /**
0206    *  @brief  Set particle id to photon
0207    *
0208    *  @param  pPeakCluster address of the photon candidate
0209    */
0210   pandora::StatusCode SetPhotonID(const pandora::Cluster* const pPeakCluster) const;
0211 
0212   /**
0213    *  @brief  True for passing quality cuut
0214    *
0215    *  @param  clusterEnergy energy of the photon candidate
0216    *  @param  pdfVarFloatMap a varible to value map to store quantities for checking photon id
0217    *
0218    *  @return True for passing quality cuut
0219    */
0220   bool PassPhotonQualityCut(const float clusterEnergy, const PDFVarFloatMap& pdfVarFloatMap) const;
0221 
0222   /**
0223    *  @brief  Get the pid of photon id
0224    *
0225    *  @param  clusterEnergy energy of the photon candidate
0226    *  @param  pdfVarFloatMap a varible to value map to store quantities for checking photon id
0227    *
0228    *  @return The pid of photon id
0229    */
0230   float GetPIDForPhotonID(const float clusterEnergy, const PDFVarFloatMap& pdfVarFloatMap) const;
0231 
0232   /**
0233    *  @brief  True for the pid of photon passing the cut
0234    *
0235    *  @param  pid The pid of photon id
0236    *  @param  clusterEnergy energy of the photon candidate
0237    *  @param  isFromTrack true for the cluster close to a track
0238    *
0239    *  @return True for the pid of photon passing the cut
0240    */
0241   bool PassPhotonPIDCut(const float pid, const float clusterEnergy, const bool isFromTrack) const;
0242 
0243   /**
0244    *  @brief  Delete cluster
0245    *
0246    *  @param  pCluster address of the cluster
0247    */
0248   pandora::StatusCode DeleteCluster(const pandora::Cluster* const pCluster) const;
0249 
0250   /**
0251    *  @brief  Run nested fragment removal algorithm
0252    */
0253   pandora::StatusCode RunNestedFragmentRemovalAlg() const;
0254 
0255   /**
0256    *  @brief  Revert to input cluster list
0257    *
0258    *  @param  inputClusterListName input cluster list name
0259    */
0260   pandora::StatusCode ReplaceInputClusterList(const std::string& inputClusterListName) const;
0261 
0262   /**
0263    *  @brief  Get minimum distance to the closest track to a cluster, use the ClusterHelper::GetTrackClusterDistance
0264    *
0265    *  @param  pCluster the address of the cluster
0266    *  @param  trackVector the vector that holds addresses of all tracks
0267    *  @param  minDistance to receive the minimum distance to closest track to a cluster
0268    *  @param  pMinTrack to receive the address of the closest track to a cluster
0269    */
0270   pandora::StatusCode GetMinDistanceToTrack(const pandora::Cluster* const pCluster,
0271                                             const pandora::TrackVector& trackVector, float& minDistance,
0272                                             const pandora::Track*& pMinTrack) const;
0273 
0274   // histogram functions
0275   /**
0276    *  @brief  Read histogram settings
0277    *
0278    *  @param  xmlHandle xml handler
0279    */
0280   pandora::StatusCode ReadHistogramSettings(const pandora::TiXmlHandle xmlHandle);
0281 
0282   /**
0283    *  @brief  Initialise histogram writing
0284    *
0285    *  @param  xmlHandle xml handler
0286    */
0287   pandora::StatusCode InitialiseHistogramWriting(const pandora::TiXmlHandle xmlHandle);
0288 
0289   /**
0290    *  @brief  Initialise histogram reading
0291    *
0292    *  @param  xmlHandle xml handler
0293    */
0294   pandora::StatusCode InitialiseHistogramReading();
0295 
0296   /**
0297    *  @brief  Initialise pdf varible to likelihood pdf object map
0298    */
0299   pandora::StatusCode InitialisePDFVarLikelihoodPDFObjectMap();
0300 
0301   /**
0302    *  @brief  Get the number of energy bins
0303    *
0304    *  @param  xmlHandle xml handler
0305    *  @param  nEnergyBinsStr the string of the n energy bin
0306    *  @param  nEnergyBins number of energy bin to receive
0307    */
0308   pandora::StatusCode GetNEnergyBins(const pandora::TiXmlHandle xmlHandle, const std::string& nEnergyBinsStr,
0309                                      unsigned int& nEnergyBins) const;
0310 
0311   /**
0312    *  @brief  Get the energy bin lower edges
0313    *
0314    *  @param  xmlHandle xml handler
0315    *  @param  energyBinLowerEdgesStr the string of the energy blow edge in
0316    *  @param  energyBinLowerEdges the energy bin lower edges to receive
0317    */
0318   pandora::StatusCode GetEnergyBinLowerEdges(const pandora::TiXmlHandle xmlHandle,
0319                                              const std::string& energyBinLowerEdgesStr,
0320                                              pandora::FloatVector& energyBinLowerEdges) const;
0321 
0322   /**
0323    *  @brief  Check for the correct parameter element of the histogram
0324    *
0325    *  @param  parameter the parameter to receive
0326    */
0327   pandora::StatusCode ParameterElementNumberCheck(pandora::FloatVector& parameter) const;
0328 
0329   /**
0330    *  @brief  Get number of signal and background events in training
0331    *
0332    *  @param  xmlHandle xml handler
0333    *  @param  nSignalEventsStr string for signal events
0334    *  @param  nBackgroundEventsStr string for background events
0335    *  @param  nSignalEvents signal events number to receive
0336    *  @param  nBackgroundEvents background events number to receive
0337    */
0338   pandora::StatusCode GetNSignalBackgroundEvts(const pandora::TiXmlHandle xmlHandle,
0339                                                const std::string& nSignalEventsStr,
0340                                                const std::string& nBackgroundEventsStr,
0341                                                pandora::IntVector& nSignalEvents,
0342                                                pandora::IntVector& nBackgroundEvents) const;
0343 
0344   /**
0345    *  @brief  Fill pdf varible to likelihood pdf object map parameters
0346    *
0347    *  @param  xmlHandle xml handler
0348    *  @param  PDFVar the varible to fill
0349    *  @param  nBinStr the name of the varible
0350    *  @param  nBinDefault the value to fill
0351    *  @param  lowValueStr the string of the lower edge
0352    *  @param  lowValueDefault the value to the lower edge
0353    *  @param  highValueStr the string of the upper edge
0354    *  @param  highValueDefault the value to the upper edge
0355    */
0356   pandora::StatusCode FillPDFVarLikelihoodPDFMapParameters(const pandora::TiXmlHandle xmlHandle, const PDFVar histVar,
0357                                                            const std::string& nBinStr, const int nBinDefault,
0358                                                            const std::string& lowValueStr, const float lowValueDefault,
0359                                                            const std::string& highValueStr,
0360                                                            const float highValueDefault);
0361 
0362   /**
0363    *  @brief  Get the relevant energy bin number for a specified energy value
0364    *
0365    *  @param  energy the specified energy value
0366    */
0367   unsigned int GetEnergyBin(const float energy) const;
0368 
0369   /**
0370    *  @brief  Get the relevant histogram bin content for a specified parameter value, avoiding overflow bins
0371    *
0372    *  @param  pHistogram address of the histogram
0373    *  @param  value the parameter value to look-up in the histogram
0374    *
0375    *  @return the relevant histogram bin content
0376    */
0377   float GetHistogramContent(const pandora::Histogram* const pHistogram, const float value) const;
0378 
0379   /**
0380    *  @brief  Create a photon for training
0381    *
0382    *  @param  pCluster address of the cluster
0383    *  @param  showersPhoton shower peak list for photon candidate
0384    */
0385   pandora::StatusCode CreatePhotonsForTraining(const pandora::Cluster* const pCluster,
0386                                                const pandora::ShowerProfilePlugin::ShowerPeakList& showersPhoton);
0387 
0388   /**
0389    *  @brief  Create a photon and train photon likelihood id
0390    *
0391    *  @param  showersPhoton shower peak list for photon candidate
0392    *  @param  wholeClusuterEnergy the energy of the whole cluster
0393    */
0394   pandora::StatusCode CreateClustersAndTrainPhotonID(const pandora::ShowerProfilePlugin::ShowerPeakList& showersPhoton,
0395                                                      const float wholeClusuterEnergy);
0396 
0397   /**
0398    *  @brief  Train photon likelihood id
0399    *
0400    *  @param  showerPeak shower peak list for photon candidate
0401    *  @param  pCluster the address of the photon candidate
0402    *  @param  wholeClusuterEnergy the energy of the whole cluster
0403    */
0404   pandora::StatusCode TrainPhotonID(const pandora::ShowerProfilePlugin::ShowerPeak& showerPeak,
0405                                     const pandora::Cluster* const pCluster, const float wholeClusuterEnergy);
0406 
0407   /**
0408    *  @brief  Fill histogram
0409    *
0410    *  @param  pCluster the address of the photon candidate
0411    *  @param  pdfVarFloatMap a varible to value map to store quantities for checking photon id
0412    */
0413   pandora::StatusCode FillPdfHistograms(const pandora::Cluster* const pCluster, const PDFVarFloatMap& pdfVarFloatMap);
0414 
0415   /**
0416    *  @brief  Normalizing member variable histograms
0417    *
0418    *  @param  pHistogram the address of the histogram
0419    */
0420   void NormalizeHistogram(pandora::Histogram* const pHistogram) const;
0421 
0422   /**
0423    *  @brief  Write varibles to xml
0424    *
0425    *  @param  xmlDocument xml file
0426    *  @param  nameStr string of the varible name
0427    *  @param  valueStr string of the value
0428    */
0429   void WriteString(pandora::TiXmlDocument& xmlDocument, const std::string nameStr, const std::string valueStr);
0430 
0431   /**
0432    *  @brief  Normalizing member variable histograms and write them to xml
0433    */
0434   void NormalizeAndWriteHistograms();
0435 
0436   /**
0437    *  @brief  Draw member variable histograms if pandora monitoring functionality is enabled
0438    */
0439   void DrawHistograms() const;
0440 
0441   pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle);
0442 
0443   std::string m_photonClusteringAlgName; ///< The name of the photon clustering algorithm to run
0444   std::string m_fragmentMergingAlgName;  ///< The name of the photon fragment merging algorithm to run
0445 
0446   std::string m_clusterListName;        ///< The name of the output cluster list
0447   bool m_replaceCurrentClusterList;     ///< Whether to subsequently use the new cluster list as the "current" list
0448   bool m_shouldDeleteNonPhotonClusters; ///< Whether to delete clusters that are not reconstructed photons
0449 
0450   float m_minClusterEnergy;              ///< The minimum energy to consider a cluster
0451   float m_minPeakEnergy;                 ///< The minimum energy to consider a transverse profile peak
0452   float m_maxPeakRms;                    ///< The maximum rms value to consider a transverse profile peak
0453   float m_maxRmsRatio;                   ///< The max rms ratio
0454   float m_maxLongProfileStart;           ///< The maximum longitudinal shower profile start
0455   float m_maxLongProfileDiscrepancy;     ///< The maximum longitudinal shower profile discrepancy
0456   unsigned int m_maxSearchLayer;         ///< Max pseudo layer to examine when calculating track-cluster distance
0457   float m_parallelDistanceCut;           ///< Max allowed projection of track-hit separation along track direction
0458   float m_minTrackClusterCosAngle;       ///< Min cos(angle) between track and cluster initial direction
0459   float m_minDistanceToTrackDivisionCut; ///< Minimum distance to track to separate clusters close to track or not
0460   bool m_transProfileEcalOnly;         ///< Transverse profile shower calculator uses EcalOnly. Can be overridden by the
0461                                        ///< m_transProfileMaxLayer
0462   unsigned int m_transProfileMaxLayer; ///< Maximum layer to consider in calculation of shower transverse profiles
0463   float m_minDistanceToTrackCutLow;    ///< Minimum distance to track to consider
0464   float m_minDistanceToTrackCutHigh;   ///< Maximum distance to track to consider
0465   float m_energyCutForPid1;            ///< The energy cut for pid test range 1
0466   float m_pidCut1;                     ///< The pid cut to apply for photon cluster identification for energy in range 1
0467   float m_energyCutForPid2;            ///< The energy cut for pid test range 2
0468   float m_pidCut2;                     ///< The pid cut to apply for photon cluster identification for energy in range 2
0469   float m_pidCut3;                     ///< The pid cut to apply for photon cluster identification for energy in range 3
0470 
0471   // histogram settings
0472   std::string m_histogramFile;    ///< The name of the file containing (or to contain) pdf histograms
0473   bool m_shouldMakePdfHistograms; ///< Whether to create pdf histograms, rather than perform photon reconstruction
0474   bool m_shouldDrawPdfHistograms; ///< Whether to draw pdf histograms at end of reconstruction (requires monitoring)
0475 
0476   unsigned int m_nEnergyBins;                      ///< Number of pdf energy bins
0477   pandora::FloatVector m_energyBinLowerEdges;      ///< List of lower edges of the pdf energy bins
0478   pandora::IntVector m_nSignalEvents;              ///< Number of signal(photons) pfos in training
0479   pandora::IntVector m_nBackgroundEvents;          ///< Number of background pfos in training
0480   PDFVarLikelihoodPDFMap m_pdfVarLikelihoodPDFMap; ///< Histogram varible to signal background map
0481 };
0482 
0483 //------------------------------------------------------------------------------------------------------------------------------------------
0484 
0485 inline PhotonReconstructionAlgorithm::LikelihoodPDFObject::LikelihoodPDFObject(const std::string& pdfVarName)
0486     : m_pdfVarName(pdfVarName), m_nBins(0), m_lowValue(0.f), m_highValue(0.f), m_pSignalPDF(NULL),
0487       m_pBackgroundPDF(NULL) {}
0488 
0489 } // namespace lc_content
0490 
0491 #endif // #ifndef LC_PHOTON_RECONSTRUCTION_ALGORITHM_H