Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:25:00

0001 /** \class PhotonProducer
0002  **  
0003  **
0004  **  \author Nancy Marinelli, U. of Notre Dame, US
0005  **
0006  ***/
0007 
0008 #include "CommonTools/Utils/interface/StringToEnumValue.h"
0009 #include "CondFormats/EcalObjects/interface/EcalFunctionParameters.h"
0010 #include "DataFormats/Common/interface/Handle.h"
0011 #include "DataFormats/EgammaCandidates/interface/Conversion.h"
0012 #include "DataFormats/EgammaCandidates/interface/Photon.h"
0013 #include "DataFormats/EgammaCandidates/interface/PhotonCore.h"
0014 #include "DataFormats/EgammaReco/interface/BasicCluster.h"
0015 #include "DataFormats/EgammaReco/interface/BasicClusterShapeAssociation.h"
0016 #include "DataFormats/EgammaReco/interface/ClusterShape.h"
0017 #include "DataFormats/EgammaReco/interface/SuperCluster.h"
0018 #include "DataFormats/VertexReco/interface/Vertex.h"
0019 #include "FWCore/Framework/interface/ESHandle.h"
0020 #include "FWCore/Framework/interface/Event.h"
0021 #include "FWCore/Framework/interface/EventSetup.h"
0022 #include "FWCore/Framework/interface/stream/EDProducer.h"
0023 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0024 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0025 #include "FWCore/Utilities/interface/Exception.h"
0026 #include "Geometry/Records/interface/CaloTopologyRecord.h"
0027 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
0028 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
0029 #include "Geometry/CaloTopology/interface/CaloTopology.h"
0030 #include "Geometry/Records/interface/CaloGeometryRecord.h"
0031 #include "RecoCaloTools/Selectors/interface/CaloConeSelector.h"
0032 #include "RecoEcal/EgammaCoreTools/interface/EcalClusterTools.h"
0033 #include "RecoEcal/EgammaCoreTools/interface/PositionCalc.h"
0034 #include "RecoEgamma/EgammaPhotonAlgos/interface/PhotonEnergyCorrector.h"
0035 #include "RecoEgamma/PhotonIdentification/interface/PhotonIsolationCalculator.h"
0036 #include "RecoEgamma/PhotonIdentification/interface/PhotonMIPHaloTagger.h"
0037 #include "RecoEgamma/PhotonIdentification/interface/PhotonMVABasedHaloTagger.h"
0038 #include "RecoLocalCalo/EcalRecAlgos/interface/EcalSeverityLevelAlgo.h"
0039 #include "RecoLocalCalo/EcalRecAlgos/interface/EcalSeverityLevelAlgoRcd.h"
0040 #include "RecoEgamma/EgammaElectronAlgos/interface/ElectronHcalHelper.h"
0041 #include "CondFormats/DataRecord/interface/HcalPFCutsRcd.h"
0042 #include "CondTools/Hcal/interface/HcalPFCutsHandler.h"
0043 #include "Geometry/CaloTopology/interface/HcalTopology.h"
0044 
0045 #include <vector>
0046 
0047 // PhotonProducer inherits from EDProducer, so it can be a module:
0048 class PhotonProducer : public edm::stream::EDProducer<> {
0049 public:
0050   PhotonProducer(const edm::ParameterSet& ps);
0051 
0052   void produce(edm::Event& evt, const edm::EventSetup& es) override;
0053 
0054 private:
0055   void fillPhotonCollection(edm::Event& evt,
0056                             edm::EventSetup const& es,
0057                             const edm::Handle<reco::PhotonCoreCollection>& photonCoreHandle,
0058                             const CaloTopology* topology,
0059                             const HcalPFCuts* hcalCuts,
0060                             const EcalRecHitCollection* ecalBarrelHits,
0061                             const EcalRecHitCollection* ecalEndcapHits,
0062                             ElectronHcalHelper const& hcalHelperCone,
0063                             ElectronHcalHelper const& hcalHelperBc,
0064                             reco::VertexCollection& pvVertices,
0065                             reco::PhotonCollection& outputCollection,
0066                             int& iSC);
0067 
0068   // std::string PhotonCoreCollection_;
0069   std::string PhotonCollection_;
0070   edm::EDGetTokenT<reco::PhotonCoreCollection> photonCoreProducer_;
0071   edm::EDGetTokenT<EcalRecHitCollection> barrelEcalHits_;
0072   edm::EDGetTokenT<EcalRecHitCollection> endcapEcalHits_;
0073   edm::EDGetTokenT<HBHERecHitCollection> hbheRecHits_;
0074   edm::EDGetTokenT<reco::VertexCollection> vertexProducer_;
0075   const edm::ESGetToken<CaloGeometry, CaloGeometryRecord> caloGeomToken_;
0076   const edm::ESGetToken<CaloTopology, CaloTopologyRecord> topologyToken_;
0077 
0078   //AA
0079   //Flags and severities to be excluded from calculations
0080 
0081   std::vector<int> flagsexclEB_;
0082   std::vector<int> flagsexclEE_;
0083   std::vector<int> severitiesexclEB_;
0084   std::vector<int> severitiesexclEE_;
0085 
0086   double hOverEConeSize_;
0087   double highEt_;
0088   double minR9Barrel_;
0089   double minR9Endcap_;
0090   bool runMIPTagger_;
0091   bool runMVABasedHaloTagger_;
0092 
0093   bool validConversions_;
0094 
0095   bool usePrimaryVertex_;
0096 
0097   PositionCalc posCalculator_;
0098 
0099   bool validPixelSeeds_;
0100   PhotonIsolationCalculator photonIsolationCalculator_;
0101 
0102   //MIP
0103   PhotonMIPHaloTagger photonMIPHaloTagger_;
0104   //MVA based Halo tagger for the EE photons
0105   std::unique_ptr<PhotonMVABasedHaloTagger> photonMVABasedHaloTagger_ = nullptr;
0106 
0107   std::vector<double> preselCutValuesBarrel_;
0108   std::vector<double> preselCutValuesEndcap_;
0109 
0110   PhotonEnergyCorrector photonEnergyCorrector_;
0111   std::string candidateP4type_;
0112 
0113   // additional configuration and helpers
0114   std::unique_ptr<ElectronHcalHelper> hcalHelperCone_;
0115   std::unique_ptr<ElectronHcalHelper> hcalHelperBc_;
0116   bool hcalRun2EffDepth_;
0117 
0118   edm::ESGetToken<HcalPFCuts, HcalPFCutsRcd> hcalCutsToken_;
0119   bool cutsFromDB_;
0120 };
0121 
0122 #include "FWCore/Framework/interface/MakerMacros.h"
0123 DEFINE_FWK_MODULE(PhotonProducer);
0124 
0125 PhotonProducer::PhotonProducer(const edm::ParameterSet& config)
0126     : caloGeomToken_(esConsumes()), topologyToken_(esConsumes()), photonEnergyCorrector_(config, consumesCollector()) {
0127   // use configuration file to setup input/output collection names
0128 
0129   photonCoreProducer_ = consumes<reco::PhotonCoreCollection>(config.getParameter<edm::InputTag>("photonCoreProducer"));
0130   barrelEcalHits_ = consumes<EcalRecHitCollection>(config.getParameter<edm::InputTag>("barrelEcalHits"));
0131   endcapEcalHits_ = consumes<EcalRecHitCollection>(config.getParameter<edm::InputTag>("endcapEcalHits"));
0132   vertexProducer_ = consumes<reco::VertexCollection>(config.getParameter<edm::InputTag>("primaryVertexProducer"));
0133   hbheRecHits_ = consumes<HBHERecHitCollection>(config.getParameter<edm::InputTag>("hbheRecHits"));
0134   hOverEConeSize_ = config.getParameter<double>("hOverEConeSize");
0135   highEt_ = config.getParameter<double>("highEt");
0136   // R9 value to decide converted/unconverted
0137   minR9Barrel_ = config.getParameter<double>("minR9Barrel");
0138   minR9Endcap_ = config.getParameter<double>("minR9Endcap");
0139   usePrimaryVertex_ = config.getParameter<bool>("usePrimaryVertex");
0140   runMIPTagger_ = config.getParameter<bool>("runMIPTagger");
0141   runMVABasedHaloTagger_ = config.getParameter<bool>("runMVABasedHaloTagger");
0142 
0143   candidateP4type_ = config.getParameter<std::string>("candidateP4type");
0144 
0145   edm::ParameterSet posCalcParameters = config.getParameter<edm::ParameterSet>("posCalcParameters");
0146   posCalculator_ = PositionCalc(posCalcParameters);
0147 
0148   //Retrieve HCAL PF thresholds - from config or from DB
0149   cutsFromDB_ = config.getParameter<bool>("usePFThresholdsFromDB");
0150   if (cutsFromDB_) {
0151     hcalCutsToken_ = esConsumes<HcalPFCuts, HcalPFCutsRcd>(edm::ESInputTag("", "withTopo"));
0152   }
0153 
0154   //AA
0155   //Flags and Severities to be excluded from photon calculations
0156   const std::vector<std::string> flagnamesEB =
0157       config.getParameter<std::vector<std::string>>("RecHitFlagToBeExcludedEB");
0158 
0159   const std::vector<std::string> flagnamesEE =
0160       config.getParameter<std::vector<std::string>>("RecHitFlagToBeExcludedEE");
0161 
0162   flagsexclEB_ = StringToEnumValue<EcalRecHit::Flags>(flagnamesEB);
0163 
0164   flagsexclEE_ = StringToEnumValue<EcalRecHit::Flags>(flagnamesEE);
0165 
0166   const std::vector<std::string> severitynamesEB =
0167       config.getParameter<std::vector<std::string>>("RecHitSeverityToBeExcludedEB");
0168 
0169   severitiesexclEB_ = StringToEnumValue<EcalSeverityLevel::SeverityLevel>(severitynamesEB);
0170 
0171   const std::vector<std::string> severitynamesEE =
0172       config.getParameter<std::vector<std::string>>("RecHitSeverityToBeExcludedEE");
0173 
0174   severitiesexclEE_ = StringToEnumValue<EcalSeverityLevel::SeverityLevel>(severitynamesEE);
0175 
0176   ElectronHcalHelper::Configuration cfgCone, cfgBc;
0177   cfgCone.hOverEConeSize = hOverEConeSize_;
0178   if (cfgCone.hOverEConeSize > 0) {
0179     cfgCone.onlyBehindCluster = false;
0180     cfgCone.checkHcalStatus = false;
0181 
0182     cfgCone.hbheRecHits = hbheRecHits_;
0183 
0184     cfgCone.eThresHB = config.getParameter<EgammaHcalIsolation::arrayHB>("recHitEThresholdHB");
0185     cfgCone.maxSeverityHB = config.getParameter<int>("maxHcalRecHitSeverity");
0186     cfgCone.eThresHE = config.getParameter<EgammaHcalIsolation::arrayHE>("recHitEThresholdHE");
0187     cfgCone.maxSeverityHE = cfgCone.maxSeverityHB;
0188   }
0189 
0190   cfgBc.hOverEConeSize = 0.;
0191   cfgBc.onlyBehindCluster = true;
0192   cfgBc.checkHcalStatus = false;
0193 
0194   cfgBc.hbheRecHits = hbheRecHits_;
0195 
0196   cfgBc.eThresHB = config.getParameter<EgammaHcalIsolation::arrayHB>("recHitEThresholdHB");
0197   cfgBc.maxSeverityHB = config.getParameter<int>("maxHcalRecHitSeverity");
0198   cfgBc.eThresHE = config.getParameter<EgammaHcalIsolation::arrayHE>("recHitEThresholdHE");
0199   cfgBc.maxSeverityHE = cfgBc.maxSeverityHB;
0200 
0201   hcalHelperCone_ = std::make_unique<ElectronHcalHelper>(cfgCone, consumesCollector());
0202   hcalHelperBc_ = std::make_unique<ElectronHcalHelper>(cfgBc, consumesCollector());
0203 
0204   hcalRun2EffDepth_ = config.getParameter<bool>("hcalRun2EffDepth");
0205 
0206   //AA
0207 
0208   //
0209 
0210   // Parameters for the position calculation:
0211   //  std::map<std::string,double> providedParameters;
0212   // providedParameters.insert(std::make_pair("LogWeighted",config.getParameter<bool>("posCalc_logweight")));
0213   //providedParameters.insert(std::make_pair("T0_barl",config.getParameter<double>("posCalc_t0_barl")));
0214   //providedParameters.insert(std::make_pair("T0_endc",config.getParameter<double>("posCalc_t0_endc")));
0215   //providedParameters.insert(std::make_pair("T0_endcPresh",config.getParameter<double>("posCalc_t0_endcPresh")));
0216   //providedParameters.insert(std::make_pair("W0",config.getParameter<double>("posCalc_w0")));
0217   //providedParameters.insert(std::make_pair("X0",config.getParameter<double>("posCalc_x0")));
0218   //posCalculator_ = PositionCalc(providedParameters);
0219   // cut values for pre-selection
0220   preselCutValuesBarrel_.push_back(config.getParameter<double>("minSCEtBarrel"));
0221   preselCutValuesBarrel_.push_back(config.getParameter<double>("maxHoverEBarrel"));
0222   preselCutValuesBarrel_.push_back(config.getParameter<double>("ecalRecHitSumEtOffsetBarrel"));
0223   preselCutValuesBarrel_.push_back(config.getParameter<double>("ecalRecHitSumEtSlopeBarrel"));
0224   preselCutValuesBarrel_.push_back(config.getParameter<double>("hcalRecHitSumEtOffsetBarrel"));
0225   preselCutValuesBarrel_.push_back(config.getParameter<double>("hcalRecHitSumEtSlopeBarrel"));
0226   preselCutValuesBarrel_.push_back(config.getParameter<double>("nTrackSolidConeBarrel"));
0227   preselCutValuesBarrel_.push_back(config.getParameter<double>("nTrackHollowConeBarrel"));
0228   preselCutValuesBarrel_.push_back(config.getParameter<double>("trackPtSumSolidConeBarrel"));
0229   preselCutValuesBarrel_.push_back(config.getParameter<double>("trackPtSumHollowConeBarrel"));
0230   preselCutValuesBarrel_.push_back(config.getParameter<double>("sigmaIetaIetaCutBarrel"));
0231   //
0232   preselCutValuesEndcap_.push_back(config.getParameter<double>("minSCEtEndcap"));
0233   preselCutValuesEndcap_.push_back(config.getParameter<double>("maxHoverEEndcap"));
0234   preselCutValuesEndcap_.push_back(config.getParameter<double>("ecalRecHitSumEtOffsetEndcap"));
0235   preselCutValuesEndcap_.push_back(config.getParameter<double>("ecalRecHitSumEtSlopeEndcap"));
0236   preselCutValuesEndcap_.push_back(config.getParameter<double>("hcalRecHitSumEtOffsetEndcap"));
0237   preselCutValuesEndcap_.push_back(config.getParameter<double>("hcalRecHitSumEtSlopeEndcap"));
0238   preselCutValuesEndcap_.push_back(config.getParameter<double>("nTrackSolidConeEndcap"));
0239   preselCutValuesEndcap_.push_back(config.getParameter<double>("nTrackHollowConeEndcap"));
0240   preselCutValuesEndcap_.push_back(config.getParameter<double>("trackPtSumSolidConeEndcap"));
0241   preselCutValuesEndcap_.push_back(config.getParameter<double>("trackPtSumHollowConeEndcap"));
0242   preselCutValuesEndcap_.push_back(config.getParameter<double>("sigmaIetaIetaCutEndcap"));
0243   //
0244 
0245   edm::ParameterSet isolationSumsCalculatorSet = config.getParameter<edm::ParameterSet>("isolationSumsCalculatorSet");
0246   photonIsolationCalculator_.setup(
0247       isolationSumsCalculatorSet, flagsexclEB_, flagsexclEE_, severitiesexclEB_, severitiesexclEE_, consumesCollector());
0248 
0249   edm::ParameterSet mipVariableSet = config.getParameter<edm::ParameterSet>("mipVariableSet");
0250   photonMIPHaloTagger_.setup(mipVariableSet, consumesCollector());
0251 
0252   // Register the product
0253   produces<reco::PhotonCollection>(PhotonCollection_);
0254 }
0255 
0256 void PhotonProducer::produce(edm::Event& theEvent, const edm::EventSetup& theEventSetup) {
0257   HcalPFCuts const* hcalCuts = nullptr;
0258   if (cutsFromDB_) {
0259     hcalCuts = &theEventSetup.getData(hcalCutsToken_);
0260   }
0261   using namespace edm;
0262   //  nEvt_++;
0263 
0264   reco::PhotonCollection outputPhotonCollection;
0265   auto outputPhotonCollection_p = std::make_unique<reco::PhotonCollection>();
0266 
0267   // Get the PhotonCore collection
0268   bool validPhotonCoreHandle = true;
0269   Handle<reco::PhotonCoreCollection> photonCoreHandle;
0270   theEvent.getByToken(photonCoreProducer_, photonCoreHandle);
0271   if (!photonCoreHandle.isValid()) {
0272     edm::LogError("PhotonProducer") << "Error! Can't get the photonCoreProducer";
0273     validPhotonCoreHandle = false;
0274   }
0275 
0276   // Get EcalRecHits
0277   bool validEcalRecHits = true;
0278   Handle<EcalRecHitCollection> barrelHitHandle;
0279   EcalRecHitCollection barrelRecHits;
0280   theEvent.getByToken(barrelEcalHits_, barrelHitHandle);
0281   if (!barrelHitHandle.isValid()) {
0282     edm::LogError("PhotonProducer") << "Error! Can't get the barrelEcalHits";
0283     validEcalRecHits = false;
0284   }
0285   if (validEcalRecHits)
0286     barrelRecHits = *(barrelHitHandle.product());
0287 
0288   Handle<EcalRecHitCollection> endcapHitHandle;
0289   theEvent.getByToken(endcapEcalHits_, endcapHitHandle);
0290   EcalRecHitCollection endcapRecHits;
0291   if (!endcapHitHandle.isValid()) {
0292     edm::LogError("PhotonProducer") << "Error! Can't get the endcapEcalHits";
0293     validEcalRecHits = false;
0294   }
0295   if (validEcalRecHits)
0296     endcapRecHits = *(endcapHitHandle.product());
0297 
0298   const CaloTopology* topology = &theEventSetup.getData(topologyToken_);
0299 
0300   // prepare access to hcal data
0301   hcalHelperCone_->beginEvent(theEvent, theEventSetup);
0302   hcalHelperBc_->beginEvent(theEvent, theEventSetup);
0303 
0304   // Get the primary event vertex
0305   Handle<reco::VertexCollection> vertexHandle;
0306   reco::VertexCollection vertexCollection;
0307   bool validVertex = true;
0308   if (usePrimaryVertex_) {
0309     theEvent.getByToken(vertexProducer_, vertexHandle);
0310     if (!vertexHandle.isValid()) {
0311       edm::LogWarning("PhotonProducer") << "Error! Can't get the product primary Vertex Collection "
0312                                         << "\n";
0313       validVertex = false;
0314     }
0315     if (validVertex)
0316       vertexCollection = *(vertexHandle.product());
0317   }
0318 
0319   int iSC = 0;  // index in photon collection
0320   // Loop over barrel and endcap SC collections and fill the  photon collection
0321   if (validPhotonCoreHandle)
0322     fillPhotonCollection(theEvent,
0323                          theEventSetup,
0324                          photonCoreHandle,
0325                          topology,
0326                          hcalCuts,
0327                          &barrelRecHits,
0328                          &endcapRecHits,
0329                          *hcalHelperCone_,
0330                          *hcalHelperBc_,
0331                          vertexCollection,
0332                          outputPhotonCollection,
0333                          iSC);
0334 
0335   // put the product in the event
0336   edm::LogInfo("PhotonProducer") << " Put in the event " << iSC << " Photon Candidates \n";
0337   outputPhotonCollection_p->assign(outputPhotonCollection.begin(), outputPhotonCollection.end());
0338 
0339   // 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
0340   if (hcalRun2EffDepth_) {
0341     for (auto& pho : *outputPhotonCollection_p)
0342       pho.hcalToRun2EffDepth();
0343   }
0344 
0345   theEvent.put(std::move(outputPhotonCollection_p), PhotonCollection_);
0346 }
0347 
0348 void PhotonProducer::fillPhotonCollection(edm::Event& evt,
0349                                           edm::EventSetup const& es,
0350                                           const edm::Handle<reco::PhotonCoreCollection>& photonCoreHandle,
0351                                           const CaloTopology* topology,
0352                                           const HcalPFCuts* hcalCuts,
0353                                           const EcalRecHitCollection* ecalBarrelHits,
0354                                           const EcalRecHitCollection* ecalEndcapHits,
0355                                           ElectronHcalHelper const& hcalHelperCone,
0356                                           ElectronHcalHelper const& hcalHelperBc,
0357                                           reco::VertexCollection& vertexCollection,
0358                                           reco::PhotonCollection& outputPhotonCollection,
0359                                           int& iSC) {
0360   // get the geometry from the event setup:
0361   const CaloGeometry* geometry = &es.getData(caloGeomToken_);
0362   const CaloSubdetectorGeometry* subDetGeometry = nullptr;
0363   const CaloSubdetectorGeometry* geometryES = geometry->getSubdetectorGeometry(DetId::Ecal, EcalPreshower);
0364   const EcalRecHitCollection* hits = nullptr;
0365   std::vector<double> preselCutValues;
0366   float minR9 = 0;
0367 
0368   photonEnergyCorrector_.init(es);
0369 
0370   std::vector<int> flags_, severitiesexcl_;
0371 
0372   for (unsigned int lSC = 0; lSC < photonCoreHandle->size(); lSC++) {
0373     reco::PhotonCoreRef coreRef(reco::PhotonCoreRef(photonCoreHandle, lSC));
0374     reco::SuperClusterRef scRef = coreRef->superCluster();
0375     iSC++;
0376 
0377     int subdet = scRef->seed()->hitsAndFractions()[0].first.subdetId();
0378     subDetGeometry = geometry->getSubdetectorGeometry(DetId::Ecal, subdet);
0379 
0380     if (subdet == EcalBarrel) {
0381       preselCutValues = preselCutValuesBarrel_;
0382       minR9 = minR9Barrel_;
0383       hits = ecalBarrelHits;
0384       flags_ = flagsexclEB_;
0385       severitiesexcl_ = severitiesexclEB_;
0386     } else if (subdet == EcalEndcap) {
0387       preselCutValues = preselCutValuesEndcap_;
0388       minR9 = minR9Endcap_;
0389       hits = ecalEndcapHits;
0390       flags_ = flagsexclEE_;
0391       severitiesexcl_ = severitiesexclEE_;
0392     } else {
0393       edm::LogWarning("") << "PhotonProducer: do not know if it is a barrel or endcap SuperCluster";
0394     }
0395     if (hits == nullptr)
0396       continue;
0397 
0398     // SC energy preselection
0399     if (scRef->energy() / cosh(scRef->eta()) <= preselCutValues[0])
0400       continue;
0401 
0402     // recalculate position of seed BasicCluster taking shower depth for unconverted photon
0403     math::XYZPoint unconvPos =
0404         posCalculator_.Calculate_Location(scRef->seed()->hitsAndFractions(), hits, subDetGeometry, geometryES);
0405 
0406     float maxXtal = EcalClusterTools::eMax(*(scRef->seed()), &(*hits));
0407     //AA
0408     //Change these to consider severity level of hits
0409     float e1x5 = EcalClusterTools::e1x5(*(scRef->seed()), &(*hits), &(*topology));
0410     float e2x5 = EcalClusterTools::e2x5Max(*(scRef->seed()), &(*hits), &(*topology));
0411     float e3x3 = EcalClusterTools::e3x3(*(scRef->seed()), &(*hits), &(*topology));
0412     float e5x5 = EcalClusterTools::e5x5(*(scRef->seed()), &(*hits), &(*topology));
0413     const auto& cov = EcalClusterTools::covariances(*(scRef->seed()), &(*hits), &(*topology), geometry);
0414     const auto& locCov = EcalClusterTools::localCovariances(*(scRef->seed()), &(*hits), &(*topology));
0415 
0416     float sigmaEtaEta = sqrt(cov[0]);
0417     float sigmaIetaIeta = sqrt(locCov[0]);
0418     float r9 = e3x3 / (scRef->rawEnergy());
0419 
0420     float full5x5_maxXtal = noZS::EcalClusterTools::eMax(*(scRef->seed()), &(*hits));
0421     //AA
0422     //Change these to consider severity level of hits
0423     float full5x5_e1x5 = noZS::EcalClusterTools::e1x5(*(scRef->seed()), &(*hits), &(*topology));
0424     float full5x5_e2x5 = noZS::EcalClusterTools::e2x5Max(*(scRef->seed()), &(*hits), &(*topology));
0425     float full5x5_e3x3 = noZS::EcalClusterTools::e3x3(*(scRef->seed()), &(*hits), &(*topology));
0426     float full5x5_e5x5 = noZS::EcalClusterTools::e5x5(*(scRef->seed()), &(*hits), &(*topology));
0427     const auto& full5x5_cov = noZS::EcalClusterTools::covariances(*(scRef->seed()), &(*hits), &(*topology), geometry);
0428     const auto& full5x5_locCov = noZS::EcalClusterTools::localCovariances(*(scRef->seed()), &(*hits), &(*topology));
0429 
0430     float full5x5_sigmaEtaEta = sqrt(full5x5_cov[0]);
0431     float full5x5_sigmaIetaIeta = sqrt(full5x5_locCov[0]);
0432 
0433     // compute position of ECAL shower
0434     math::XYZPoint caloPosition;
0435     if (r9 > minR9) {
0436       caloPosition = unconvPos;
0437     } else {
0438       caloPosition = scRef->position();
0439     }
0440 
0441     //// energy determination -- Default to create the candidate. Afterwards corrections are applied
0442     double photonEnergy = 1.;
0443     math::XYZPoint vtx(0., 0., 0.);
0444     if (!vertexCollection.empty())
0445       vtx = vertexCollection.begin()->position();
0446     // compute momentum vector of photon from primary vertex and cluster position
0447     math::XYZVector direction = caloPosition - vtx;
0448     math::XYZVector momentum = direction.unit();
0449 
0450     // Create dummy candidate with unit momentum and zero energy to allow setting of all variables. The energy is set for last.
0451     math::XYZTLorentzVectorD p4(momentum.x(), momentum.y(), momentum.z(), photonEnergy);
0452     reco::Photon newCandidate(p4, caloPosition, coreRef, vtx);
0453 
0454     // Calculate fiducial flags and isolation variable. Blocked are filled from the isolationCalculator
0455     reco::Photon::FiducialFlags fiducialFlags;
0456     reco::Photon::IsolationVariables isolVarR03, isolVarR04;
0457     photonIsolationCalculator_.calculate(&newCandidate, evt, es, fiducialFlags, isolVarR04, isolVarR03, hcalCuts);
0458     newCandidate.setFiducialVolumeFlags(fiducialFlags);
0459     newCandidate.setIsolationVariables(isolVarR04, isolVarR03);
0460 
0461     /// fill shower shape block
0462     reco::Photon::ShowerShape showerShape;
0463     showerShape.e1x5 = e1x5;
0464     showerShape.e2x5 = e2x5;
0465     showerShape.e3x3 = e3x3;
0466     showerShape.e5x5 = e5x5;
0467     showerShape.maxEnergyXtal = maxXtal;
0468     showerShape.sigmaEtaEta = sigmaEtaEta;
0469     showerShape.sigmaIetaIeta = sigmaIetaIeta;
0470     for (uint id = 0; id < showerShape.hcalOverEcal.size(); ++id) {
0471       showerShape.hcalOverEcal[id] = hcalHelperCone.hcalESum(*scRef, id + 1, hcalCuts) / scRef->energy();
0472       showerShape.hcalOverEcalBc[id] = hcalHelperBc.hcalESum(*scRef, id + 1, hcalCuts) / scRef->energy();
0473     }
0474     showerShape.hcalTowersBehindClusters = hcalHelperBc.hcalTowersBehindClusters(*scRef);
0475     showerShape.pre7DepthHcal = false;
0476     newCandidate.setShowerShapeVariables(showerShape);
0477 
0478     /// fill full5x5 shower shape block
0479     reco::Photon::ShowerShape full5x5_showerShape;
0480     full5x5_showerShape.e1x5 = full5x5_e1x5;
0481     full5x5_showerShape.e2x5 = full5x5_e2x5;
0482     full5x5_showerShape.e3x3 = full5x5_e3x3;
0483     full5x5_showerShape.e5x5 = full5x5_e5x5;
0484     full5x5_showerShape.maxEnergyXtal = full5x5_maxXtal;
0485     full5x5_showerShape.sigmaEtaEta = full5x5_sigmaEtaEta;
0486     full5x5_showerShape.sigmaIetaIeta = full5x5_sigmaIetaIeta;
0487     for (uint id = 0; id < full5x5_showerShape.hcalOverEcal.size(); ++id) {
0488       full5x5_showerShape.hcalOverEcal[id] = hcalHelperCone.hcalESum(*scRef, id + 1, hcalCuts) / full5x5_e5x5;
0489       full5x5_showerShape.hcalOverEcalBc[id] = hcalHelperBc.hcalESum(*scRef, id + 1, hcalCuts) / full5x5_e5x5;
0490     }
0491     full5x5_showerShape.hcalTowersBehindClusters = hcalHelperBc.hcalTowersBehindClusters(*scRef);
0492     full5x5_showerShape.pre7DepthHcal = false;
0493     newCandidate.full5x5_setShowerShapeVariables(full5x5_showerShape);
0494 
0495     /// get ecal photon specific corrected energy
0496     /// plus values from regressions     and store them in the Photon
0497     // Photon candidate takes by default (set in photons_cfi.py)  a 4-momentum derived from the ecal photon-specific corrections.
0498     photonEnergyCorrector_.calculate(evt, newCandidate, subdet, vertexCollection, es);
0499     if (candidateP4type_ == "fromEcalEnergy") {
0500       newCandidate.setP4(newCandidate.p4(reco::Photon::ecal_photons));
0501       newCandidate.setCandidateP4type(reco::Photon::ecal_photons);
0502     } else if (candidateP4type_ == "fromRegression") {
0503       newCandidate.setP4(newCandidate.p4(reco::Photon::regression1));
0504       newCandidate.setCandidateP4type(reco::Photon::regression1);
0505     }
0506 
0507     // fill MIP Vairables for Halo: Block for MIP are filled from PhotonMIPHaloTagger
0508     reco::Photon::MIPVariables mipVar;
0509     if (subdet == EcalBarrel && runMIPTagger_) {
0510       photonMIPHaloTagger_.MIPcalculate(&newCandidate, evt, es, mipVar);
0511       newCandidate.setMIPVariables(mipVar);
0512     }
0513 
0514     /// Pre-selection loose  isolation cuts
0515     bool isLooseEM = true;
0516     if (newCandidate.pt() < highEt_) {
0517       if (newCandidate.hadronicOverEm() >= preselCutValues[1])
0518         isLooseEM = false;
0519       if (newCandidate.ecalRecHitSumEtConeDR04() > preselCutValues[2] + preselCutValues[3] * newCandidate.pt())
0520         isLooseEM = false;
0521       if (newCandidate.hcalTowerSumEtConeDR04() > preselCutValues[4] + preselCutValues[5] * newCandidate.pt())
0522         isLooseEM = false;
0523       if (newCandidate.nTrkSolidConeDR04() > int(preselCutValues[6]))
0524         isLooseEM = false;
0525       if (newCandidate.nTrkHollowConeDR04() > int(preselCutValues[7]))
0526         isLooseEM = false;
0527       if (newCandidate.trkSumPtSolidConeDR04() > preselCutValues[8])
0528         isLooseEM = false;
0529       if (newCandidate.trkSumPtHollowConeDR04() > preselCutValues[9])
0530         isLooseEM = false;
0531       if (newCandidate.sigmaIetaIeta() > preselCutValues[10])
0532         isLooseEM = false;
0533     }
0534 
0535     if (isLooseEM)
0536       outputPhotonCollection.push_back(newCandidate);
0537   }
0538 }