Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-07 04:35:52

0001 #ifndef EgammaCandidates_Photon_h
0002 #define EgammaCandidates_Photon_h
0003 /** \class reco::Photon 
0004  *
0005  * \author  N. Marinelli Univ. of Notre Dame
0006  * Photon object built out of PhotonCore
0007  * stores isolation, shower shape and additional info
0008  * needed for identification
0009  * 
0010  *
0011  */
0012 #include "DataFormats/RecoCandidate/interface/RecoCandidate.h"
0013 #include "DataFormats/EgammaCandidates/interface/Conversion.h"
0014 #include "DataFormats/EgammaCandidates/interface/ConversionFwd.h"
0015 #include "DataFormats/EgammaCandidates/interface/PhotonCore.h"
0016 #include "DataFormats/EgammaReco/interface/ElectronSeed.h"
0017 #include "DataFormats/EgammaReco/interface/SuperCluster.h"
0018 #include <numeric>
0019 
0020 namespace reco {
0021 
0022   class Photon : public RecoCandidate {
0023   public:
0024     /// Forward declaration of data structures included in the object
0025     struct FiducialFlags;
0026     struct IsolationVariables;
0027     struct ShowerShape;
0028     struct MIPVariables;
0029     struct SaturationInfo;
0030 
0031     /// default constructor
0032     Photon() : RecoCandidate() {
0033       pixelSeed_ = false;
0034       haloTaggerMVAVal_ = 99;
0035     }
0036 
0037     /// copy constructor
0038     Photon(const Photon&);
0039 
0040     /// constructor from values
0041     Photon(const LorentzVector& p4, const Point& caloPos, const PhotonCoreRef& core, const Point& vtx = Point(0, 0, 0));
0042 
0043     /// assignment operator
0044     Photon& operator=(const Photon&) = default;
0045 
0046     /// destructor
0047     ~Photon() override;
0048 
0049     /// returns a clone of the candidate
0050     Photon* clone() const override;
0051 
0052     /// returns a reference to the core photon object
0053     reco::PhotonCoreRef photonCore() const { return photonCore_; }
0054     void setPhotonCore(const reco::PhotonCoreRef& photonCore) { photonCore_ = photonCore; }
0055 
0056     //
0057     /// Retrieve photonCore attributes
0058     //
0059     // retrieve provenance
0060     bool isPFlowPhoton() const { return this->photonCore()->isPFlowPhoton(); }
0061     bool isStandardPhoton() const { return this->photonCore()->isStandardPhoton(); }
0062     /// Ref to SuperCluster
0063     reco::SuperClusterRef superCluster() const override;
0064     /// Ref to PFlow SuperCluster
0065     reco::SuperClusterRef parentSuperCluster() const { return this->photonCore()->parentSuperCluster(); }
0066     /// vector of references to  Conversion's
0067     reco::ConversionRefVector conversions() const { return this->photonCore()->conversions(); }
0068     enum ConversionProvenance { egamma = 0, pflow = 1, both = 2 };
0069 
0070     /// vector of references to  one leg Conversion's
0071     reco::ConversionRefVector conversionsOneLeg() const { return this->photonCore()->conversionsOneLeg(); }
0072     /// Bool flagging photons with a vector of refereces to conversions with size >0
0073     bool hasConversionTracks() const {
0074       if (!this->photonCore()->conversions().empty() || !this->photonCore()->conversionsOneLeg().empty())
0075         return true;
0076       else
0077         return false;
0078     }
0079     /// reference to electron Pixel seed
0080     reco::ElectronSeedRefVector electronPixelSeeds() const { return this->photonCore()->electronPixelSeeds(); }
0081     /// Bool flagging photons having a non-zero size vector of Ref to electornPixel seeds
0082     bool hasPixelSeed() const {
0083       if (!(this->photonCore()->electronPixelSeeds()).empty())
0084         return true;
0085       else
0086         return false;
0087     }
0088     int conversionTrackProvenance(const edm::RefToBase<reco::Track>& convTrack) const;
0089 
0090     /// position in ECAL: this is th SC position if r9<0.93. If r8>0.93 is position of seed BasicCluster taking shower depth for unconverted photon
0091     math::XYZPointF caloPosition() const { return caloPosition_; }
0092     /// set primary event vertex used to define photon direction
0093     void setVertex(const Point& vertex) override;
0094     /// Implement Candidate method for particle species
0095     bool isPhoton() const override { return true; }
0096 
0097     //=======================================================
0098     // Fiducial Flags
0099     //=======================================================
0100     struct FiducialFlags {
0101       //Fiducial flags
0102       bool isEB;         //Photon is in EB
0103       bool isEE;         //Photon is in EE
0104       bool isEBEtaGap;   //Photon is in supermodule/supercrystal eta gap in EB
0105       bool isEBPhiGap;   //Photon is in supermodule/supercrystal phi gap in EB
0106       bool isEERingGap;  //Photon is in crystal ring gap in EE
0107       bool isEEDeeGap;   //Photon is in crystal dee gap in EE
0108       bool isEBEEGap;    //Photon is in border between EB and EE.
0109 
0110       FiducialFlags()
0111           : isEB(false),
0112             isEE(false),
0113             isEBEtaGap(false),
0114             isEBPhiGap(false),
0115             isEERingGap(false),
0116             isEEDeeGap(false),
0117             isEBEEGap(false)
0118 
0119       {}
0120     };
0121 
0122     /// set flags for photons in the ECAL fiducial volume
0123     void setFiducialVolumeFlags(const FiducialFlags& a) { fiducialFlagBlock_ = a; }
0124     /// Ritrievs fiducial flags
0125     /// true if photon is in ECAL barrel
0126     bool isEB() const { return fiducialFlagBlock_.isEB; }
0127     // true if photon is in ECAL endcap
0128     bool isEE() const { return fiducialFlagBlock_.isEE; }
0129     /// true if photon is in EB, and inside the boundaries in super crystals/modules
0130     bool isEBGap() const { return (isEBEtaGap() || isEBPhiGap()); }
0131     bool isEBEtaGap() const { return fiducialFlagBlock_.isEBEtaGap; }
0132     bool isEBPhiGap() const { return fiducialFlagBlock_.isEBPhiGap; }
0133     /// true if photon is in EE, and inside the boundaries in supercrystal/D
0134     bool isEEGap() const { return (isEERingGap() || isEEDeeGap()); }
0135     bool isEERingGap() const { return fiducialFlagBlock_.isEERingGap; }
0136     bool isEEDeeGap() const { return fiducialFlagBlock_.isEEDeeGap; }
0137     /// true if photon is in boundary between EB and EE
0138     bool isEBEEGap() const { return fiducialFlagBlock_.isEBEEGap; }
0139 
0140     //=======================================================
0141     // Shower Shape Variables
0142     //=======================================================
0143 
0144     struct ShowerShape {
0145       float sigmaEtaEta;
0146       float sigmaIetaIeta;
0147       float e1x5;
0148       float e2x5;
0149       float e3x3;
0150       float e5x5;
0151       float maxEnergyXtal;
0152       float hcalDepth1OverEcal;  // hcal over ecal energy using first hcal depth
0153       float hcalDepth2OverEcal;  // hcal over ecal energy using 2nd hcal depth
0154       float hcalDepth1OverEcalBc;
0155       float hcalDepth2OverEcalBc;
0156       std::array<float, 7> hcalOverEcal;  // hcal over ecal seed cluster energy per depth (using rechits within a cone)
0157       std::array<float, 7>
0158           hcalOverEcalBc;  // hcal over ecal seed cluster energy per depth (using rechits behind clusters)
0159       std::vector<CaloTowerDetId> hcalTowersBehindClusters;
0160       bool invalidHcal;
0161       bool pre7DepthHcal;  // to work around an ioread rule issue on legacy RECO files
0162       float effSigmaRR;
0163       float sigmaIetaIphi;
0164       float sigmaIphiIphi;
0165       float e2nd;
0166       float eTop;
0167       float eLeft;
0168       float eRight;
0169       float eBottom;
0170       float e1x3;
0171       float e2x2;
0172       float e2x5Max;
0173       float e2x5Left;
0174       float e2x5Right;
0175       float e2x5Top;
0176       float e2x5Bottom;
0177       float smMajor;
0178       float smMinor;
0179       float smAlpha;
0180       ShowerShape()
0181           : sigmaEtaEta(std::numeric_limits<float>::max()),
0182             sigmaIetaIeta(std::numeric_limits<float>::max()),
0183             e1x5(0.f),
0184             e2x5(0.f),
0185             e3x3(0.f),
0186             e5x5(0.f),
0187             maxEnergyXtal(0.f),
0188             hcalDepth1OverEcal(0.f),
0189             hcalDepth2OverEcal(0.f),
0190             hcalDepth1OverEcalBc(0.f),
0191             hcalDepth2OverEcalBc(0.f),
0192             hcalOverEcal{{0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}},
0193             hcalOverEcalBc{{0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}},
0194             invalidHcal(false),
0195             pre7DepthHcal(true),
0196             effSigmaRR(std::numeric_limits<float>::max()),
0197             sigmaIetaIphi(std::numeric_limits<float>::max()),
0198             sigmaIphiIphi(std::numeric_limits<float>::max()),
0199             e2nd(0.f),
0200             eTop(0.f),
0201             eLeft(0.f),
0202             eRight(0.f),
0203             eBottom(0.f),
0204             e1x3(0.f),
0205             e2x2(0.f),
0206             e2x5Max(0.f),
0207             e2x5Left(0.f),
0208             e2x5Right(0.f),
0209             e2x5Top(0.f),
0210             e2x5Bottom(0.f),
0211             smMajor(0.f),
0212             smMinor(0.f),
0213             smAlpha(0.f) {}
0214     };
0215     const ShowerShape& showerShapeVariables() const { return showerShapeBlock_; }
0216     const ShowerShape& full5x5_showerShapeVariables() const { return full5x5_showerShapeBlock_; }
0217 
0218     void setShowerShapeVariables(const ShowerShape& a) { showerShapeBlock_ = a; }
0219     void full5x5_setShowerShapeVariables(const ShowerShape& a) { full5x5_showerShapeBlock_ = a; }
0220 
0221     /// the total hadronic over electromagnetic fraction
0222     float hcalOverEcal(const ShowerShape& ss, int depth) const {
0223       if (ss.pre7DepthHcal) {
0224         if (depth == 0)
0225           return ss.hcalDepth1OverEcal + ss.hcalDepth2OverEcal;
0226         else if (depth == 1)
0227           return ss.hcalDepth1OverEcal;
0228         else if (depth == 2)
0229           return ss.hcalDepth2OverEcal;
0230 
0231         return 0.f;
0232       } else {
0233         const auto& hovere = ss.hcalOverEcal;
0234         return (!(depth > 0 and depth < 8)) ? std::accumulate(std::begin(hovere), std::end(hovere), 0.f)
0235                                             : hovere[depth - 1];
0236       }
0237     }
0238     float hcalOverEcal(int depth = 0) const { return hcalOverEcal(showerShapeBlock_, depth); }
0239     float hadronicOverEm(int depth = 0) const { return hcalOverEcal(depth); }
0240 
0241     /// the ratio of total energy of hcal rechits behind the SC and the SC energy
0242     float hcalOverEcalBc(const ShowerShape& ss, int depth) const {
0243       if (ss.pre7DepthHcal) {
0244         if (depth == 0)
0245           return ss.hcalDepth1OverEcalBc + ss.hcalDepth2OverEcalBc;
0246         else if (depth == 1)
0247           return ss.hcalDepth1OverEcalBc;
0248         else if (depth == 2)
0249           return ss.hcalDepth2OverEcalBc;
0250 
0251         return 0.f;
0252       } else {
0253         const auto& hovere = ss.hcalOverEcalBc;
0254         return (!(depth > 0 and depth < 8)) ? std::accumulate(std::begin(hovere), std::end(hovere), 0.f)
0255                                             : hovere[depth - 1];
0256       }
0257     }
0258     float hcalOverEcalBc(int depth = 0) const { return hcalOverEcalBc(showerShapeBlock_, depth); }
0259     float hadTowOverEm(int depth = 0) const { return hcalOverEcalBc(depth); }
0260 
0261     const std::vector<CaloTowerDetId>& hcalTowersBehindClusters() const {
0262       return showerShapeBlock_.hcalTowersBehindClusters;
0263     }
0264 
0265     /// returns false if H/E is not reliably estimated (e.g. because hcal was off or masked)
0266     bool hadronicOverEmValid() const { return !showerShapeBlock_.invalidHcal; }
0267     bool hadTowOverEmValid() const { return !showerShapeBlock_.invalidHcal; }
0268 
0269     ///  Shower shape variables
0270     float e1x5() const { return showerShapeBlock_.e1x5; }
0271     float e2x5() const { return showerShapeBlock_.e2x5; }
0272     float e3x3() const { return showerShapeBlock_.e3x3; }
0273     float e5x5() const { return showerShapeBlock_.e5x5; }
0274     float maxEnergyXtal() const { return showerShapeBlock_.maxEnergyXtal; }
0275     float sigmaEtaEta() const { return showerShapeBlock_.sigmaEtaEta; }
0276     float sigmaIetaIeta() const { return showerShapeBlock_.sigmaIetaIeta; }
0277     float r1x5() const { return showerShapeBlock_.e1x5 / showerShapeBlock_.e5x5; }
0278     float r2x5() const { return showerShapeBlock_.e2x5 / showerShapeBlock_.e5x5; }
0279     float r9() const { return showerShapeBlock_.e3x3 / this->superCluster()->rawEnergy(); }
0280 
0281     ///full5x5 Shower shape variables
0282     float full5x5_e1x5() const { return full5x5_showerShapeBlock_.e1x5; }
0283     float full5x5_e2x5() const { return full5x5_showerShapeBlock_.e2x5; }
0284     float full5x5_e3x3() const { return full5x5_showerShapeBlock_.e3x3; }
0285     float full5x5_e5x5() const { return full5x5_showerShapeBlock_.e5x5; }
0286     float full5x5_maxEnergyXtal() const { return full5x5_showerShapeBlock_.maxEnergyXtal; }
0287     float full5x5_sigmaEtaEta() const { return full5x5_showerShapeBlock_.sigmaEtaEta; }
0288     float full5x5_sigmaIetaIeta() const { return full5x5_showerShapeBlock_.sigmaIetaIeta; }
0289     float full5x5_r1x5() const { return full5x5_showerShapeBlock_.e1x5 / full5x5_showerShapeBlock_.e5x5; }
0290     float full5x5_r2x5() const { return full5x5_showerShapeBlock_.e2x5 / full5x5_showerShapeBlock_.e5x5; }
0291     float full5x5_r9() const { return full5x5_showerShapeBlock_.e3x3 / this->superCluster()->rawEnergy(); }
0292 
0293     /// the total hadronic over electromagnetic fraction
0294     float full5x5_hcalOverEcal(int depth = 0) const { return hcalOverEcal(full5x5_showerShapeBlock_, depth); }
0295     float full5x5_hadronicOverEm(int depth = 0) const { return full5x5_hcalOverEcal(depth); }
0296 
0297     /// the ratio of total energy of hcal rechits behind the SC and the SC energy
0298     float full5x5_hcalOverEcalBc(int depth = 0) const { return hcalOverEcalBc(full5x5_showerShapeBlock_, depth); }
0299     float full5x5_hadTowOverEm(int depth = 0) const { return full5x5_hcalOverEcalBc(depth); }
0300 
0301     //=======================================================
0302     // SaturationInfo
0303     //=======================================================
0304 
0305     struct SaturationInfo {
0306       int nSaturatedXtals;
0307       bool isSeedSaturated;
0308       SaturationInfo() : nSaturatedXtals(0), isSeedSaturated(false) {}
0309     };
0310 
0311     // accessors
0312     float nSaturatedXtals() const { return saturationInfo_.nSaturatedXtals; }
0313     float isSeedSaturated() const { return saturationInfo_.isSeedSaturated; }
0314     const SaturationInfo& saturationInfo() const { return saturationInfo_; }
0315     void setSaturationInfo(const SaturationInfo& s) { saturationInfo_ = s; }
0316 
0317     //=======================================================
0318     // Energy Determinations
0319     //=======================================================
0320     enum P4type { undefined = -1, ecal_standard = 0, ecal_photons = 1, regression1 = 2, regression2 = 3 };
0321 
0322     struct EnergyCorrections {
0323       float scEcalEnergy;
0324       float scEcalEnergyError;
0325       LorentzVector scEcalP4;
0326       float phoEcalEnergy;
0327       float phoEcalEnergyError;
0328       LorentzVector phoEcalP4;
0329       float regression1Energy;
0330       float regression1EnergyError;
0331       LorentzVector regression1P4;
0332       float regression2Energy;
0333       float regression2EnergyError;
0334       LorentzVector regression2P4;
0335       P4type candidateP4type;
0336       EnergyCorrections()
0337           : scEcalEnergy(0.),
0338             scEcalEnergyError(999.),
0339             scEcalP4(0., 0., 0., 0.),
0340             phoEcalEnergy(0.),
0341             phoEcalEnergyError(999.),
0342             phoEcalP4(0., 0., 0., 0.),
0343             regression1Energy(0.),
0344             regression1EnergyError(999.),
0345             regression1P4(0., 0., 0., 0.),
0346             regression2Energy(0.),
0347             regression2EnergyError(999.),
0348             regression2P4(0., 0., 0., 0.),
0349             candidateP4type(undefined) {}
0350     };
0351 
0352     using RecoCandidate::p4;
0353     using RecoCandidate::setP4;
0354 
0355     //sets both energy and its uncertainty
0356     void setCorrectedEnergy(P4type type, float E, float dE, bool toCand = true);
0357     void setP4(P4type type, const LorentzVector& p4, float p4Error, bool setToRecoCandidate);
0358     void setEnergyCorrections(const EnergyCorrections& e) { eCorrections_ = e; }
0359     void setCandidateP4type(const P4type type) { eCorrections_.candidateP4type = type; }
0360 
0361     float getCorrectedEnergy(P4type type) const;
0362     float getCorrectedEnergyError(P4type type) const;
0363     P4type getCandidateP4type() const { return eCorrections_.candidateP4type; }
0364     const LorentzVector& p4(P4type type) const;
0365     const EnergyCorrections& energyCorrections() const { return eCorrections_; }
0366 
0367     //=======================================================
0368     // MIP Variables
0369     //=======================================================
0370 
0371     struct MIPVariables {
0372       float mipChi2;
0373       float mipTotEnergy;
0374       float mipSlope;
0375       float mipIntercept;
0376       int mipNhitCone;
0377       bool mipIsHalo;
0378 
0379       MIPVariables()
0380           :
0381 
0382             mipChi2(0),
0383             mipTotEnergy(0),
0384             mipSlope(0),
0385             mipIntercept(0),
0386             mipNhitCone(0),
0387             mipIsHalo(false) {}
0388     };
0389 
0390     ///  MIP variables
0391     float mipChi2() const { return mipVariableBlock_.mipChi2; }
0392     float mipTotEnergy() const { return mipVariableBlock_.mipTotEnergy; }
0393     float mipSlope() const { return mipVariableBlock_.mipSlope; }
0394     float mipIntercept() const { return mipVariableBlock_.mipIntercept; }
0395     int mipNhitCone() const { return mipVariableBlock_.mipNhitCone; }
0396     bool mipIsHalo() const { return mipVariableBlock_.mipIsHalo; }
0397 
0398     ///set mip Variables
0399     void setMIPVariables(const MIPVariables& mipVar) { mipVariableBlock_ = mipVar; }
0400 
0401     //=======================================================
0402     // Isolation Variables
0403     //=======================================================
0404 
0405     struct IsolationVariables {
0406       //These are analysis quantities calculated in the PhotonIDAlgo class
0407 
0408       //EcalRecHit isolation
0409       float ecalRecHitSumEt;
0410       //HcalTower isolation
0411       float hcalTowerSumEt;
0412       //HcalDepth1Tower isolation
0413       float hcalDepth1TowerSumEt;
0414       //HcalDepth2Tower isolation
0415       float hcalDepth2TowerSumEt;
0416       //HcalTower isolation subtracting the hadronic energy in towers behind the BCs in the SC
0417       float hcalTowerSumEtBc;
0418       //HcalDepth1Tower isolation subtracting the hadronic energy in towers behind the BCs in the SC
0419       float hcalDepth1TowerSumEtBc;
0420       //HcalDepth2Tower isolation subtracting the hadronic energy in towers behind the BCs in the SC
0421       float hcalDepth2TowerSumEtBc;
0422       std::array<float, 7> hcalRecHitSumEt;    // ...per depth, with photon footprint within a cone removed
0423       std::array<float, 7> hcalRecHitSumEtBc;  // ...per depth, with hcal rechits behind cluster removed
0424       bool pre7DepthHcal;                      // to work around an ioread rule issue on legacy RECO files
0425       //Sum of track pT in a cone of dR
0426       float trkSumPtSolidCone;
0427       //Sum of track pT in a hollow cone of outer radius, inner radius
0428       float trkSumPtHollowCone;
0429       //Number of tracks in a cone of dR
0430       int nTrkSolidCone;
0431       //Number of tracks in a hollow cone of outer radius, inner radius
0432       int nTrkHollowCone;
0433       IsolationVariables()
0434           :
0435 
0436             ecalRecHitSumEt(0.f),
0437             hcalTowerSumEt(0.f),
0438             hcalDepth1TowerSumEt(0.f),
0439             hcalDepth2TowerSumEt(0.f),
0440             hcalTowerSumEtBc(0.f),
0441             hcalDepth1TowerSumEtBc(0.f),
0442             hcalDepth2TowerSumEtBc(0.f),
0443             hcalRecHitSumEt{{0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}},
0444             hcalRecHitSumEtBc{{0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}},
0445             pre7DepthHcal(true),
0446             trkSumPtSolidCone(0.f),
0447             trkSumPtHollowCone(0.f),
0448             nTrkSolidCone(0),
0449             nTrkHollowCone(0) {}
0450     };
0451 
0452     /// set relevant isolation variables
0453     void setIsolationVariables(const IsolationVariables& isolInDr04, const IsolationVariables& isolInDr03) {
0454       isolationR04_ = isolInDr04;
0455       isolationR03_ = isolInDr03;
0456     }
0457 
0458     /// Egamma Isolation variables in cone dR=0.4
0459     ///Ecal isolation sum calculated from recHits
0460     float ecalRecHitSumEtConeDR04() const { return isolationR04_.ecalRecHitSumEt; }
0461     /// Hcal isolation sum for each depth excluding the region containing the rechits used for hcalOverEcal()
0462     float hcalTowerSumEt(const IsolationVariables& iv, int depth) const {
0463       if (iv.pre7DepthHcal) {
0464         if (depth == 0)
0465           return iv.hcalTowerSumEt;
0466         else if (depth == 1)
0467           return iv.hcalDepth1TowerSumEt;
0468         else if (depth == 2)
0469           return iv.hcalDepth2TowerSumEt;
0470 
0471         return 0.f;
0472       } else {
0473         const auto& hcaliso = iv.hcalRecHitSumEt;
0474         return (!(depth > 0 and depth < 8)) ? std::accumulate(std::begin(hcaliso), std::end(hcaliso), 0.f)
0475                                             : hcaliso[depth - 1];
0476       }
0477     }
0478     float hcalTowerSumEtConeDR04(int depth = 0) const { return hcalTowerSumEt(isolationR04_, depth); }
0479     /// Hcal isolation sum for each depth excluding the region containing the rechits used for hcalOverEcalBc()
0480     float hcalTowerSumEtBc(const IsolationVariables& iv, int depth) const {
0481       if (iv.pre7DepthHcal) {
0482         if (depth == 0)
0483           return iv.hcalTowerSumEtBc;
0484         else if (depth == 1)
0485           return iv.hcalDepth1TowerSumEtBc;
0486         else if (depth == 2)
0487           return iv.hcalDepth2TowerSumEtBc;
0488 
0489         return 0.f;
0490       } else {
0491         const auto& hcaliso = iv.hcalRecHitSumEtBc;
0492         return (!(depth > 0 and depth < 8)) ? std::accumulate(std::begin(hcaliso), std::end(hcaliso), 0.f)
0493                                             : hcaliso[depth - 1];
0494       }
0495     }
0496     float hcalTowerSumEtBcConeDR04(int depth = 0) const { return hcalTowerSumEtBc(isolationR04_, depth); }
0497     //  Track pT sum
0498     float trkSumPtSolidConeDR04() const { return isolationR04_.trkSumPtSolidCone; }
0499     //As above, excluding the core at the center of the cone
0500     float trkSumPtHollowConeDR04() const { return isolationR04_.trkSumPtHollowCone; }
0501     //Returns number of tracks in a cone of dR
0502     int nTrkSolidConeDR04() const { return isolationR04_.nTrkSolidCone; }
0503     //As above, excluding the core at the center of the cone
0504     int nTrkHollowConeDR04() const { return isolationR04_.nTrkHollowCone; }
0505     //
0506     /// Isolation variables in cone dR=0.3
0507     float ecalRecHitSumEtConeDR03() const { return isolationR03_.ecalRecHitSumEt; }
0508     /// Hcal isolation sum for each depth excluding the region containing the rechits used for hcalOverEcal()
0509     float hcalTowerSumEtConeDR03(int depth = 0) const { return hcalTowerSumEt(isolationR03_, depth); }
0510     /// Hcal isolation sum for each depth excluding the region containing the rechits used for hcalOverEcalBc()
0511     float hcalTowerSumEtBcConeDR03(int depth = 0) const { return hcalTowerSumEtBc(isolationR03_, depth); }
0512     //  Track pT sum c
0513     float trkSumPtSolidConeDR03() const { return isolationR03_.trkSumPtSolidCone; }
0514     //As above, excluding the core at the center of the cone
0515     float trkSumPtHollowConeDR03() const { return isolationR03_.trkSumPtHollowCone; }
0516     //Returns number of tracks in a cone of dR
0517     int nTrkSolidConeDR03() const { return isolationR03_.nTrkSolidCone; }
0518     //As above, excluding the core at the center of the cone
0519     int nTrkHollowConeDR03() const { return isolationR03_.nTrkHollowCone; }
0520 
0521     //=======================================================
0522     // PFlow based Isolation Variables
0523     //=======================================================
0524 
0525     struct PflowIsolationVariables {
0526       float chargedHadronIso;                  //charged hadron isolation with dxy,dz match to pv
0527       float chargedHadronWorstVtxIso;          //max charged hadron isolation when dxy/dz matching to given vtx
0528       float chargedHadronWorstVtxGeomVetoIso;  //as chargedHadronWorstVtxIso but an additional geometry based veto cone
0529       float chargedHadronPFPVIso;  //only considers particles assigned to the primary vertex (PV) by particle flow, corresponds to <10_6 chargedHadronIso
0530       float neutralHadronIso;
0531       float photonIso;
0532       float sumEcalClusterEt;  //sum pt of ecal clusters, vetoing clusters part of photon
0533       float sumHcalClusterEt;  //sum pt of hcal clusters, vetoing clusters part of photon
0534       PflowIsolationVariables()
0535           :
0536 
0537             chargedHadronIso(0.),
0538             chargedHadronWorstVtxIso(0.),
0539             chargedHadronWorstVtxGeomVetoIso(0.),
0540             chargedHadronPFPVIso(0.),
0541             neutralHadronIso(0.),
0542             photonIso(0.),
0543             sumEcalClusterEt(0.),
0544             sumHcalClusterEt(0.) {}
0545     };
0546 
0547     /// Accessors for Particle Flow Isolation variables
0548     float chargedHadronIso() const { return pfIsolation_.chargedHadronIso; }
0549     float chargedHadronWorstVtxIso() const { return pfIsolation_.chargedHadronWorstVtxIso; }
0550     float chargedHadronWorstVtxGeomVetoIso() const { return pfIsolation_.chargedHadronWorstVtxGeomVetoIso; }
0551     float chargedHadronPFPVIso() const { return pfIsolation_.chargedHadronPFPVIso; }
0552     float neutralHadronIso() const { return pfIsolation_.neutralHadronIso; }
0553     float photonIso() const { return pfIsolation_.photonIso; }
0554 
0555     //backwards compat functions for pat::Photon
0556     float ecalPFClusterIso() const { return pfIsolation_.sumEcalClusterEt; };
0557     float hcalPFClusterIso() const { return pfIsolation_.sumHcalClusterEt; };
0558 
0559     /// Get Particle Flow Isolation variables block
0560     const PflowIsolationVariables& getPflowIsolationVariables() const { return pfIsolation_; }
0561 
0562     /// Set Particle Flow Isolation variables
0563     void setPflowIsolationVariables(const PflowIsolationVariables& pfisol) { pfIsolation_ = pfisol; }
0564 
0565     static constexpr float mvaPlaceholder = -999999999.;
0566 
0567     struct PflowIDVariables {
0568       int nClusterOutsideMustache;
0569       float etOutsideMustache;
0570       float mva;
0571       float dnn;
0572 
0573       PflowIDVariables()
0574           : nClusterOutsideMustache(-1), etOutsideMustache(mvaPlaceholder), mva(mvaPlaceholder), dnn(mvaPlaceholder) {}
0575     };
0576 
0577     // getters
0578     int nClusterOutsideMustache() const { return pfID_.nClusterOutsideMustache; }
0579     float etOutsideMustache() const { return pfID_.etOutsideMustache; }
0580     float pfMVA() const { return pfID_.mva; }
0581     float pfDNN() const { return pfID_.dnn; }
0582     // setters
0583     void setPflowIDVariables(const PflowIDVariables& pfid) { pfID_ = pfid; }
0584 
0585     // go back to run2-like 2 effective depths if desired - depth 1 is the normal depth 1, depth 2 is the sum over the rest
0586     void hcalToRun2EffDepth();
0587 
0588     ///MVA based beam halo tagger - trained for EE and for pT > 200 GeV
0589     float haloTaggerMVAVal() const { return haloTaggerMVAVal_; }
0590 
0591     ///set the haloTaggerMVAVal here
0592     void setHaloTaggerMVAVal(float x) { haloTaggerMVAVal_ = x; }
0593 
0594   private:
0595     /// check overlap with another candidate
0596     bool overlap(const Candidate&) const override;
0597     /// position of seed BasicCluster for shower depth of unconverted photon
0598     math::XYZPointF caloPosition_;
0599     /// reference to the PhotonCore
0600     reco::PhotonCoreRef photonCore_;
0601     //
0602     bool pixelSeed_;
0603     //
0604     FiducialFlags fiducialFlagBlock_;
0605     IsolationVariables isolationR04_;
0606     IsolationVariables isolationR03_;
0607     ShowerShape showerShapeBlock_;
0608     ShowerShape full5x5_showerShapeBlock_;
0609     SaturationInfo saturationInfo_;
0610     EnergyCorrections eCorrections_;
0611     MIPVariables mipVariableBlock_;
0612     PflowIsolationVariables pfIsolation_;
0613     PflowIDVariables pfID_;
0614     float haloTaggerMVAVal_;
0615   };
0616 
0617 }  // namespace reco
0618 
0619 #endif