Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-03-09 00:50:55

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