File indexing completed on 2024-09-07 04:37:29
0001
0002
0003
0004
0005
0006
0007
0008 #include "CommonTools/Utils/interface/StringToEnumValue.h"
0009 #include "CondFormats/DataRecord/interface/HcalChannelQualityRcd.h"
0010 #include "CondFormats/EcalObjects/interface/EcalFunctionParameters.h"
0011 #include "DataFormats/Common/interface/Handle.h"
0012 #include "DataFormats/Common/interface/ValueMap.h"
0013 #include "DataFormats/EgammaCandidates/interface/Conversion.h"
0014 #include "DataFormats/EgammaCandidates/interface/Photon.h"
0015 #include "DataFormats/EgammaCandidates/interface/PhotonCore.h"
0016 #include "DataFormats/EgammaCandidates/interface/PhotonFwd.h"
0017 #include "DataFormats/EgammaReco/interface/BasicCluster.h"
0018 #include "DataFormats/EgammaReco/interface/BasicClusterShapeAssociation.h"
0019 #include "DataFormats/EgammaReco/interface/ClusterShape.h"
0020 #include "DataFormats/EgammaReco/interface/SuperCluster.h"
0021 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0022 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateEGammaExtra.h"
0023 #include "DataFormats/VertexReco/interface/Vertex.h"
0024 #include "FWCore/Framework/interface/ESHandle.h"
0025 #include "FWCore/Framework/interface/Event.h"
0026 #include "FWCore/Framework/interface/EventSetup.h"
0027 #include "FWCore/Framework/interface/stream/EDProducer.h"
0028 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0029 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0030 #include "FWCore/Utilities/interface/Exception.h"
0031 #include "FWCore/Utilities/interface/isFinite.h"
0032 #include "Geometry/Records/interface/CaloTopologyRecord.h"
0033 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
0034 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
0035 #include "Geometry/CaloTopology/interface/CaloTopology.h"
0036 #include "Geometry/Records/interface/CaloGeometryRecord.h"
0037 #include "RecoEcal/EgammaCoreTools/interface/EcalClusterFunctionBaseClass.h"
0038 #include "RecoEcal/EgammaCoreTools/interface/EcalClusterTools.h"
0039 #include "RecoEcal/EgammaCoreTools/interface/EcalTools.h"
0040 #include "RecoEgamma/EgammaPhotonAlgos/interface/PhotonEnergyCorrector.h"
0041 #include "RecoEgamma/PhotonIdentification/interface/PhotonIsolationCalculator.h"
0042 #include "RecoEgamma/PhotonIdentification/interface/PhotonMIPHaloTagger.h"
0043 #include "RecoEgamma/PhotonIdentification/interface/PhotonMVABasedHaloTagger.h"
0044 #include "RecoLocalCalo/EcalRecAlgos/interface/EcalSeverityLevelAlgo.h"
0045 #include "RecoLocalCalo/EcalRecAlgos/interface/EcalSeverityLevelAlgoRcd.h"
0046 #include "CondFormats/EcalObjects/interface/EcalPFRecHitThresholds.h"
0047 #include "CondFormats/DataRecord/interface/EcalPFRecHitThresholdsRcd.h"
0048 #include "RecoEcal/EgammaCoreTools/interface/EgammaLocalCovParamDefaults.h"
0049 #include "RecoEgamma/EgammaElectronAlgos/interface/ElectronHcalHelper.h"
0050 #include "RecoEgamma/PhotonIdentification/interface/PhotonDNNEstimator.h"
0051 #include "PhysicsTools/TensorFlow/interface/TensorFlow.h"
0052 #include "RecoEgamma/EgammaIsolationAlgos/interface/EcalPFClusterIsolation.h"
0053 #include "RecoEgamma/EgammaIsolationAlgos/interface/HcalPFClusterIsolation.h"
0054 #include "CondFormats/GBRForest/interface/GBRForest.h"
0055 #include "CommonTools/MVAUtils/interface/GBRForestTools.h"
0056 #include "CondFormats/DataRecord/interface/HcalPFCutsRcd.h"
0057 #include "CondTools/Hcal/interface/HcalPFCutsHandler.h"
0058 #include "Geometry/CaloTopology/interface/HcalTopology.h"
0059
0060 class CacheData {
0061 public:
0062 CacheData(const edm::ParameterSet& conf) {
0063
0064 egammaTools::DNNConfiguration config;
0065 const auto& pset_dnn = conf.getParameter<edm::ParameterSet>("PhotonDNNPFid");
0066 const auto dnnEnabled = pset_dnn.getParameter<bool>("enabled");
0067 if (dnnEnabled) {
0068 config.inputTensorName = pset_dnn.getParameter<std::string>("inputTensorName");
0069 config.outputTensorName = pset_dnn.getParameter<std::string>("outputTensorName");
0070 config.modelsFiles = pset_dnn.getParameter<std::vector<std::string>>("modelsFiles");
0071 config.scalersFiles = pset_dnn.getParameter<std::vector<std::string>>("scalersFiles");
0072 config.outputDim = pset_dnn.getParameter<std::vector<unsigned int>>("outputDim");
0073 const auto useEBModelInGap = pset_dnn.getParameter<bool>("useEBModelInGap");
0074 photonDNNEstimator = std::make_unique<PhotonDNNEstimator>(config, useEBModelInGap);
0075 }
0076
0077 const auto runMVABasedHaloTagger = conf.getParameter<bool>("runMVABasedHaloTagger");
0078 edm::ParameterSet mvaBasedHaloVariableSet = conf.getParameter<edm::ParameterSet>("mvaBasedHaloVariableSet");
0079 auto trainingFileName_ = mvaBasedHaloVariableSet.getParameter<edm::FileInPath>(("trainingFileName")).fullPath();
0080 if (runMVABasedHaloTagger) {
0081 haloTaggerGBR = createGBRForest(trainingFileName_);
0082 }
0083 }
0084 std::unique_ptr<const PhotonDNNEstimator> photonDNNEstimator;
0085 std::unique_ptr<const GBRForest> haloTaggerGBR;
0086 };
0087
0088 class GEDPhotonProducer : public edm::stream::EDProducer<edm::GlobalCache<CacheData>> {
0089 public:
0090 GEDPhotonProducer(const edm::ParameterSet& ps, const CacheData* gcache);
0091
0092 void produce(edm::Event& evt, const edm::EventSetup& es) override;
0093
0094 static std::unique_ptr<CacheData> initializeGlobalCache(const edm::ParameterSet&);
0095 static void globalEndJob(const CacheData*) {}
0096
0097 void endStream() override;
0098
0099 private:
0100 edm::ESGetToken<HcalPFCuts, HcalPFCutsRcd> hcalCutsToken_;
0101 bool cutsFromDB_;
0102 HcalPFCuts const* hcalCuts_ = nullptr;
0103
0104 class RecoStepInfo {
0105 public:
0106 enum FlagBits { kOOT = 0x1, kFinal = 0x2 };
0107 explicit RecoStepInfo(const std::string& recoStep);
0108
0109 bool isOOT() const { return flags_ & kOOT; }
0110 bool isFinal() const { return flags_ & kFinal; }
0111
0112 private:
0113 unsigned int flags_;
0114 };
0115
0116 void fillPhotonCollection(edm::Event& evt,
0117 edm::EventSetup const& es,
0118 const edm::Handle<reco::PhotonCoreCollection>& photonCoreHandle,
0119 const CaloTopology* topology,
0120 const EcalRecHitCollection* ecalBarrelHits,
0121 const EcalRecHitCollection* ecalEndcapHits,
0122 const EcalRecHitCollection* preshowerHits,
0123 const ElectronHcalHelper* hcalHelperCone,
0124 const ElectronHcalHelper* hcalHelperBc,
0125 const reco::VertexCollection& pvVertices,
0126 reco::PhotonCollection& outputCollection,
0127 int& iSC,
0128 EcalPFRecHitThresholds const& thresholds);
0129
0130 void fillPhotonCollection(edm::Event& evt,
0131 edm::EventSetup const& es,
0132 const edm::Handle<reco::PhotonCollection>& photonHandle,
0133 const edm::Handle<reco::PFCandidateCollection> pfCandidateHandle,
0134 const edm::Handle<reco::PFCandidateCollection> pfEGCandidateHandle,
0135 reco::VertexCollection const& pvVertices,
0136 reco::PhotonCollection& outputCollection,
0137 int& iSC,
0138 const edm::Handle<edm::ValueMap<float>>& chargedHadrons,
0139 const edm::Handle<edm::ValueMap<float>>& neutralHadrons,
0140 const edm::Handle<edm::ValueMap<float>>& photons,
0141 const edm::Handle<edm::ValueMap<float>>& chargedHadronsWorstVtx,
0142 const edm::Handle<edm::ValueMap<float>>& chargedHadronsWorstVtxGeomVeto,
0143 const edm::Handle<edm::ValueMap<float>>& chargedHadronsPFPV,
0144 const edm::Handle<edm::ValueMap<float>>& pfEcalClusters,
0145 const edm::Handle<edm::ValueMap<float>>& pfHcalClusters);
0146
0147
0148 std::string photonCollection_;
0149 const edm::InputTag photonProducer_;
0150
0151 edm::EDGetTokenT<reco::PhotonCoreCollection> photonCoreProducerT_;
0152 edm::EDGetTokenT<reco::PhotonCollection> photonProducerT_;
0153 edm::EDGetTokenT<EcalRecHitCollection> barrelEcalHits_;
0154 edm::EDGetTokenT<EcalRecHitCollection> endcapEcalHits_;
0155 edm::EDGetTokenT<EcalRecHitCollection> preshowerHits_;
0156 edm::EDGetTokenT<reco::PFCandidateCollection> pfEgammaCandidates_;
0157 edm::EDGetTokenT<reco::PFCandidateCollection> pfCandidates_;
0158 edm::EDGetTokenT<HBHERecHitCollection> hbheRecHits_;
0159 edm::EDGetTokenT<reco::VertexCollection> vertexProducer_;
0160
0161 edm::EDGetTokenT<edm::ValueMap<std::vector<reco::PFCandidateRef>>> particleBasedIsolationToken;
0162
0163 edm::EDGetTokenT<edm::ValueMap<float>> phoChargedIsolationToken_;
0164 edm::EDGetTokenT<edm::ValueMap<float>> phoNeutralHadronIsolationToken_;
0165 edm::EDGetTokenT<edm::ValueMap<float>> phoPhotonIsolationToken_;
0166 edm::EDGetTokenT<edm::ValueMap<float>> phoChargedWorstVtxIsoToken_;
0167 edm::EDGetTokenT<edm::ValueMap<float>> phoChargedWorstVtxGeomVetoIsoToken_;
0168 edm::EDGetTokenT<edm::ValueMap<float>> phoChargedPFPVIsoToken_;
0169
0170 edm::EDGetTokenT<edm::ValueMap<float>> phoPFECALClusIsolationToken_;
0171 edm::EDGetTokenT<edm::ValueMap<float>> phoPFHCALClusIsolationToken_;
0172
0173 const EcalClusterLazyTools::ESGetTokens ecalClusterESGetTokens_;
0174
0175 std::string valueMapPFCandPhoton_;
0176
0177 std::unique_ptr<PhotonIsolationCalculator> photonIsoCalculator_ = nullptr;
0178
0179
0180
0181
0182 std::vector<int> flagsexclEB_;
0183 std::vector<int> flagsexclEE_;
0184 std::vector<int> severitiesexclEB_;
0185 std::vector<int> severitiesexclEE_;
0186
0187 double multThresEB_;
0188 double multThresEE_;
0189 double hOverEConeSize_;
0190 bool checkHcalStatus_;
0191 double highEt_;
0192 double minR9Barrel_;
0193 double minR9Endcap_;
0194 bool runMIPTagger_;
0195 bool runMVABasedHaloTagger_;
0196
0197 RecoStepInfo recoStep_;
0198
0199 bool usePrimaryVertex_;
0200
0201 CaloGeometry const* caloGeom_ = nullptr;
0202
0203
0204 std::unique_ptr<PhotonMIPHaloTagger> photonMIPHaloTagger_ = nullptr;
0205
0206 std::unique_ptr<PhotonMVABasedHaloTagger> photonMVABasedHaloTagger_ = nullptr;
0207
0208 std::vector<double> preselCutValuesBarrel_;
0209 std::vector<double> preselCutValuesEndcap_;
0210
0211 std::unique_ptr<PhotonEnergyCorrector> photonEnergyCorrector_ = nullptr;
0212 std::string candidateP4type_;
0213
0214 const edm::ESGetToken<CaloTopology, CaloTopologyRecord> caloTopologyToken_;
0215 const edm::ESGetToken<CaloGeometry, CaloGeometryRecord> caloGeometryToken_;
0216 const edm::ESGetToken<EcalPFRecHitThresholds, EcalPFRecHitThresholdsRcd> ecalPFRechitThresholdsToken_;
0217
0218
0219 std::unique_ptr<ElectronHcalHelper> hcalHelperCone_;
0220 std::unique_ptr<ElectronHcalHelper> hcalHelperBc_;
0221 bool hcalRun2EffDepth_;
0222
0223
0224 bool dnnPFidEnabled_;
0225 std::vector<tensorflow::Session*> tfSessions_;
0226
0227 double ecaldrMax_;
0228 double ecaldrVetoBarrel_;
0229 double ecaldrVetoEndcap_;
0230 double ecaletaStripBarrel_;
0231 double ecaletaStripEndcap_;
0232 double ecalenergyBarrel_;
0233 double ecalenergyEndcap_;
0234 typedef EcalPFClusterIsolation<reco::Photon> PhotonEcalPFClusterIsolation;
0235 std::unique_ptr<PhotonEcalPFClusterIsolation> ecalisoAlgo = nullptr;
0236 edm::EDGetTokenT<reco::PFClusterCollection> pfClusterProducer_;
0237
0238 bool useHF_;
0239 double hcaldrMax_;
0240 double hcaldrVetoBarrel_;
0241 double hcaldrVetoEndcap_;
0242 double hcaletaStripBarrel_;
0243 double hcaletaStripEndcap_;
0244 double hcalenergyBarrel_;
0245 double hcalenergyEndcap_;
0246 double hcaluseEt_;
0247
0248 edm::EDGetTokenT<reco::PFClusterCollection> pfClusterProducerHCAL_;
0249 edm::EDGetTokenT<reco::PFClusterCollection> pfClusterProducerHFEM_;
0250 edm::EDGetTokenT<reco::PFClusterCollection> pfClusterProducerHFHAD_;
0251
0252 typedef HcalPFClusterIsolation<reco::Photon> PhotonHcalPFClusterIsolation;
0253 std::unique_ptr<PhotonHcalPFClusterIsolation> hcalisoAlgo = nullptr;
0254 };
0255
0256 #include "FWCore/Framework/interface/MakerMacros.h"
0257 DEFINE_FWK_MODULE(GEDPhotonProducer);
0258
0259 namespace {
0260 inline double ptFast(const double energy, const math::XYZPoint& position, const math::XYZPoint& origin) {
0261 const auto v = position - origin;
0262 return energy * std::sqrt(v.perp2() / v.mag2());
0263 }
0264 }
0265
0266 GEDPhotonProducer::RecoStepInfo::RecoStepInfo(const std::string& step) : flags_(0) {
0267 if (step == "final")
0268 flags_ = kFinal;
0269 else if (step == "oot")
0270 flags_ = kOOT;
0271 else if (step == "ootfinal")
0272 flags_ = (kOOT | kFinal);
0273 else if (step == "tmp")
0274 flags_ = 0;
0275 else {
0276 throw cms::Exception("InvalidConfig")
0277 << " reconstructStep " << step << " is invalid, the options are: tmp, final,oot or ootfinal" << std::endl;
0278 }
0279 }
0280
0281 GEDPhotonProducer::GEDPhotonProducer(const edm::ParameterSet& config, const CacheData* gcache)
0282 : photonProducer_{config.getParameter<edm::InputTag>("photonProducer")},
0283 ecalClusterESGetTokens_{consumesCollector()},
0284 recoStep_(config.getParameter<std::string>("reconstructionStep")),
0285 caloTopologyToken_{esConsumes()},
0286 caloGeometryToken_{esConsumes()},
0287 ecalPFRechitThresholdsToken_{esConsumes()},
0288 hcalHelperCone_(nullptr),
0289 hcalHelperBc_(nullptr) {
0290
0291 cutsFromDB_ = config.getParameter<bool>("usePFThresholdsFromDB");
0292 if (cutsFromDB_) {
0293 hcalCutsToken_ = esConsumes<HcalPFCuts, HcalPFCutsRcd>(edm::ESInputTag("", "withTopo"));
0294 }
0295
0296 if (recoStep_.isFinal()) {
0297 photonProducerT_ = consumes(photonProducer_);
0298 pfCandidates_ = consumes(config.getParameter<edm::InputTag>("pfCandidates"));
0299
0300 const edm::ParameterSet& pfIsolCfg = config.getParameter<edm::ParameterSet>("pfIsolCfg");
0301 auto getVMToken = [&pfIsolCfg, this](const std::string& name) {
0302 return consumes(pfIsolCfg.getParameter<edm::InputTag>(name));
0303 };
0304 phoChargedIsolationToken_ = getVMToken("chargedHadronIso");
0305 phoNeutralHadronIsolationToken_ = getVMToken("neutralHadronIso");
0306 phoPhotonIsolationToken_ = getVMToken("photonIso");
0307 phoChargedWorstVtxIsoToken_ = getVMToken("chargedHadronWorstVtxIso");
0308 phoChargedWorstVtxGeomVetoIsoToken_ = getVMToken("chargedHadronWorstVtxGeomVetoIso");
0309 phoChargedPFPVIsoToken_ = getVMToken("chargedHadronPFPVIso");
0310
0311
0312
0313 if (config.exists("pfECALClusIsolation")) {
0314 phoPFECALClusIsolationToken_ = consumes(config.getParameter<edm::InputTag>("pfECALClusIsolation"));
0315 }
0316 if (config.exists("pfHCALClusIsolation")) {
0317 phoPFHCALClusIsolationToken_ = consumes(config.getParameter<edm::InputTag>("pfHCALClusIsolation"));
0318 }
0319
0320 } else {
0321 photonCoreProducerT_ = consumes(photonProducer_);
0322 }
0323
0324 auto pfEg = config.getParameter<edm::InputTag>("pfEgammaCandidates");
0325 if (not pfEg.label().empty()) {
0326 pfEgammaCandidates_ = consumes(pfEg);
0327 }
0328 barrelEcalHits_ = consumes(config.getParameter<edm::InputTag>("barrelEcalHits"));
0329 endcapEcalHits_ = consumes(config.getParameter<edm::InputTag>("endcapEcalHits"));
0330 preshowerHits_ = consumes(config.getParameter<edm::InputTag>("preshowerHits"));
0331 vertexProducer_ = consumes(config.getParameter<edm::InputTag>("primaryVertexProducer"));
0332
0333 auto hbhetag = config.getParameter<edm::InputTag>("hbheRecHits");
0334 if (not hbhetag.label().empty())
0335 hbheRecHits_ = consumes<HBHERecHitCollection>(hbhetag);
0336
0337
0338 photonCollection_ = config.getParameter<std::string>("outputPhotonCollection");
0339 multThresEB_ = config.getParameter<double>("multThresEB");
0340 multThresEE_ = config.getParameter<double>("multThresEE");
0341 hOverEConeSize_ = config.getParameter<double>("hOverEConeSize");
0342 highEt_ = config.getParameter<double>("highEt");
0343
0344 minR9Barrel_ = config.getParameter<double>("minR9Barrel");
0345 minR9Endcap_ = config.getParameter<double>("minR9Endcap");
0346 usePrimaryVertex_ = config.getParameter<bool>("usePrimaryVertex");
0347 runMIPTagger_ = config.getParameter<bool>("runMIPTagger");
0348 runMVABasedHaloTagger_ = config.getParameter<bool>("runMVABasedHaloTagger");
0349
0350 candidateP4type_ = config.getParameter<std::string>("candidateP4type");
0351 valueMapPFCandPhoton_ = config.getParameter<std::string>("valueMapPhotons");
0352
0353
0354
0355 auto const& flagnamesEB = config.getParameter<std::vector<std::string>>("RecHitFlagToBeExcludedEB");
0356 auto const& flagnamesEE = config.getParameter<std::vector<std::string>>("RecHitFlagToBeExcludedEE");
0357
0358 flagsexclEB_ = StringToEnumValue<EcalRecHit::Flags>(flagnamesEB);
0359 flagsexclEE_ = StringToEnumValue<EcalRecHit::Flags>(flagnamesEE);
0360
0361 auto const& severitynamesEB = config.getParameter<std::vector<std::string>>("RecHitSeverityToBeExcludedEB");
0362 auto const& severitynamesEE = config.getParameter<std::vector<std::string>>("RecHitSeverityToBeExcludedEE");
0363
0364 severitiesexclEB_ = StringToEnumValue<EcalSeverityLevel::SeverityLevel>(severitynamesEB);
0365 severitiesexclEE_ = StringToEnumValue<EcalSeverityLevel::SeverityLevel>(severitynamesEE);
0366
0367 photonEnergyCorrector_ = std::make_unique<PhotonEnergyCorrector>(config, consumesCollector());
0368
0369 checkHcalStatus_ = config.getParameter<bool>("checkHcalStatus");
0370 if (not hbheRecHits_.isUninitialized()) {
0371 ElectronHcalHelper::Configuration cfgCone, cfgBc;
0372 cfgCone.hOverEConeSize = hOverEConeSize_;
0373 if (cfgCone.hOverEConeSize > 0) {
0374 cfgCone.onlyBehindCluster = false;
0375 cfgCone.checkHcalStatus = checkHcalStatus_;
0376
0377 cfgCone.hbheRecHits = hbheRecHits_;
0378
0379 cfgCone.eThresHB = config.getParameter<EgammaHcalIsolation::arrayHB>("recHitEThresholdHB");
0380 cfgCone.maxSeverityHB = config.getParameter<int>("maxHcalRecHitSeverity");
0381 cfgCone.eThresHE = config.getParameter<EgammaHcalIsolation::arrayHE>("recHitEThresholdHE");
0382 cfgCone.maxSeverityHE = cfgCone.maxSeverityHB;
0383 }
0384 cfgBc.hOverEConeSize = 0.;
0385 cfgBc.onlyBehindCluster = true;
0386 cfgBc.checkHcalStatus = checkHcalStatus_;
0387
0388 cfgBc.hbheRecHits = hbheRecHits_;
0389
0390 cfgBc.eThresHB = config.getParameter<EgammaHcalIsolation::arrayHB>("recHitEThresholdHB");
0391 cfgBc.maxSeverityHB = config.getParameter<int>("maxHcalRecHitSeverity");
0392 cfgBc.eThresHE = config.getParameter<EgammaHcalIsolation::arrayHE>("recHitEThresholdHE");
0393 cfgBc.maxSeverityHE = cfgBc.maxSeverityHB;
0394
0395 hcalHelperCone_ = std::make_unique<ElectronHcalHelper>(cfgCone, consumesCollector());
0396 hcalHelperBc_ = std::make_unique<ElectronHcalHelper>(cfgBc, consumesCollector());
0397 }
0398
0399 hcalRun2EffDepth_ = config.getParameter<bool>("hcalRun2EffDepth");
0400
0401
0402 preselCutValuesBarrel_ = {config.getParameter<double>("minSCEtBarrel"),
0403 config.getParameter<double>("maxHoverEBarrel"),
0404 config.getParameter<double>("ecalRecHitSumEtOffsetBarrel"),
0405 config.getParameter<double>("ecalRecHitSumEtSlopeBarrel"),
0406 config.getParameter<double>("hcalRecHitSumEtOffsetBarrel"),
0407 config.getParameter<double>("hcalRecHitSumEtSlopeBarrel"),
0408 config.getParameter<double>("nTrackSolidConeBarrel"),
0409 config.getParameter<double>("nTrackHollowConeBarrel"),
0410 config.getParameter<double>("trackPtSumSolidConeBarrel"),
0411 config.getParameter<double>("trackPtSumHollowConeBarrel"),
0412 config.getParameter<double>("sigmaIetaIetaCutBarrel")};
0413
0414 preselCutValuesEndcap_ = {config.getParameter<double>("minSCEtEndcap"),
0415 config.getParameter<double>("maxHoverEEndcap"),
0416 config.getParameter<double>("ecalRecHitSumEtOffsetEndcap"),
0417 config.getParameter<double>("ecalRecHitSumEtSlopeEndcap"),
0418 config.getParameter<double>("hcalRecHitSumEtOffsetEndcap"),
0419 config.getParameter<double>("hcalRecHitSumEtSlopeEndcap"),
0420 config.getParameter<double>("nTrackSolidConeEndcap"),
0421 config.getParameter<double>("nTrackHollowConeEndcap"),
0422 config.getParameter<double>("trackPtSumSolidConeEndcap"),
0423 config.getParameter<double>("trackPtSumHollowConeEndcap"),
0424 config.getParameter<double>("sigmaIetaIetaCutEndcap")};
0425
0426
0427
0428 if (!recoStep_.isFinal()) {
0429 photonIsoCalculator_ = std::make_unique<PhotonIsolationCalculator>();
0430 edm::ParameterSet isolationSumsCalculatorSet = config.getParameter<edm::ParameterSet>("isolationSumsCalculatorSet");
0431 photonIsoCalculator_->setup(isolationSumsCalculatorSet,
0432 flagsexclEB_,
0433 flagsexclEE_,
0434 severitiesexclEB_,
0435 severitiesexclEE_,
0436 consumesCollector());
0437 photonMIPHaloTagger_ = std::make_unique<PhotonMIPHaloTagger>();
0438 edm::ParameterSet mipVariableSet = config.getParameter<edm::ParameterSet>("mipVariableSet");
0439 photonMIPHaloTagger_->setup(mipVariableSet, consumesCollector());
0440 }
0441
0442 if (recoStep_.isFinal() && runMVABasedHaloTagger_) {
0443 edm::ParameterSet mvaBasedHaloVariableSet = config.getParameter<edm::ParameterSet>("mvaBasedHaloVariableSet");
0444 photonMVABasedHaloTagger_ =
0445 std::make_unique<PhotonMVABasedHaloTagger>(mvaBasedHaloVariableSet, consumesCollector());
0446 }
0447
0448
0449 const edm::ParameterSet& pfECALClusIsolCfg = config.getParameter<edm::ParameterSet>("pfECALClusIsolCfg");
0450 pfClusterProducer_ =
0451 consumes<reco::PFClusterCollection>(pfECALClusIsolCfg.getParameter<edm::InputTag>("pfClusterProducer"));
0452 ecaldrMax_ = pfECALClusIsolCfg.getParameter<double>("drMax");
0453 ecaldrVetoBarrel_ = pfECALClusIsolCfg.getParameter<double>("drVetoBarrel");
0454 ecaldrVetoEndcap_ = pfECALClusIsolCfg.getParameter<double>("drVetoEndcap");
0455 ecaletaStripBarrel_ = pfECALClusIsolCfg.getParameter<double>("etaStripBarrel");
0456 ecaletaStripEndcap_ = pfECALClusIsolCfg.getParameter<double>("etaStripEndcap");
0457 ecalenergyBarrel_ = pfECALClusIsolCfg.getParameter<double>("energyBarrel");
0458 ecalenergyEndcap_ = pfECALClusIsolCfg.getParameter<double>("energyEndcap");
0459
0460 const edm::ParameterSet& pfHCALClusIsolCfg = config.getParameter<edm::ParameterSet>("pfHCALClusIsolCfg");
0461 pfClusterProducerHCAL_ = consumes(pfHCALClusIsolCfg.getParameter<edm::InputTag>("pfClusterProducerHCAL"));
0462 pfClusterProducerHFEM_ = consumes(pfHCALClusIsolCfg.getParameter<edm::InputTag>("pfClusterProducerHFEM"));
0463 pfClusterProducerHFHAD_ = consumes(pfHCALClusIsolCfg.getParameter<edm::InputTag>("pfClusterProducerHFHAD"));
0464 useHF_ = pfHCALClusIsolCfg.getParameter<bool>("useHF");
0465 hcaldrMax_ = pfHCALClusIsolCfg.getParameter<double>("drMax");
0466 hcaldrVetoBarrel_ = pfHCALClusIsolCfg.getParameter<double>("drVetoBarrel");
0467 hcaldrVetoEndcap_ = pfHCALClusIsolCfg.getParameter<double>("drVetoEndcap");
0468 hcaletaStripBarrel_ = pfHCALClusIsolCfg.getParameter<double>("etaStripBarrel");
0469 hcaletaStripEndcap_ = pfHCALClusIsolCfg.getParameter<double>("etaStripEndcap");
0470 hcalenergyBarrel_ = pfHCALClusIsolCfg.getParameter<double>("energyBarrel");
0471 hcalenergyEndcap_ = pfHCALClusIsolCfg.getParameter<double>("energyEndcap");
0472 hcaluseEt_ = pfHCALClusIsolCfg.getParameter<bool>("useEt");
0473
0474
0475 produces<reco::PhotonCollection>(photonCollection_);
0476 if (not pfEgammaCandidates_.isUninitialized()) {
0477 produces<edm::ValueMap<reco::PhotonRef>>(valueMapPFCandPhoton_);
0478 }
0479
0480 const auto& pset_dnn = config.getParameter<edm::ParameterSet>("PhotonDNNPFid");
0481 dnnPFidEnabled_ = pset_dnn.getParameter<bool>("enabled");
0482 if (dnnPFidEnabled_) {
0483 tfSessions_ = gcache->photonDNNEstimator->getSessions();
0484 }
0485 }
0486
0487 std::unique_ptr<CacheData> GEDPhotonProducer::initializeGlobalCache(const edm::ParameterSet& config) {
0488
0489 return std::make_unique<CacheData>(config);
0490 }
0491
0492 void GEDPhotonProducer::endStream() {
0493 for (auto session : tfSessions_) {
0494 tensorflow::closeSession(session);
0495 }
0496 }
0497
0498 void GEDPhotonProducer::produce(edm::Event& theEvent, const edm::EventSetup& eventSetup) {
0499 using namespace edm;
0500
0501 if (cutsFromDB_) {
0502 hcalCuts_ = &eventSetup.getData(hcalCutsToken_);
0503 }
0504
0505 auto outputPhotonCollection_p = std::make_unique<reco::PhotonCollection>();
0506 edm::ValueMap<reco::PhotonRef> pfEGCandToPhotonMap;
0507
0508
0509 bool validPhotonCoreHandle = false;
0510 Handle<reco::PhotonCoreCollection> photonCoreHandle;
0511 bool validPhotonHandle = false;
0512 Handle<reco::PhotonCollection> photonHandle;
0513
0514 edm::Handle<edm::ValueMap<float>> phoChargedIsolationMap;
0515 edm::Handle<edm::ValueMap<float>> phoNeutralHadronIsolationMap;
0516 edm::Handle<edm::ValueMap<float>> phoPhotonIsolationMap;
0517 edm::Handle<edm::ValueMap<float>> phoChargedWorstVtxIsoMap;
0518 edm::Handle<edm::ValueMap<float>> phoChargedWorstVtxGeomVetoIsoMap;
0519 edm::Handle<edm::ValueMap<float>> phoChargedPFPVIsoMap;
0520
0521 edm::Handle<edm::ValueMap<float>> phoPFECALClusIsolationMap;
0522 edm::Handle<edm::ValueMap<float>> phoPFHCALClusIsolationMap;
0523
0524 if (recoStep_.isFinal()) {
0525 theEvent.getByToken(photonProducerT_, photonHandle);
0526
0527 theEvent.getByToken(phoChargedIsolationToken_, phoChargedIsolationMap);
0528 theEvent.getByToken(phoNeutralHadronIsolationToken_, phoNeutralHadronIsolationMap);
0529 theEvent.getByToken(phoPhotonIsolationToken_, phoPhotonIsolationMap);
0530 theEvent.getByToken(phoChargedWorstVtxIsoToken_, phoChargedWorstVtxIsoMap);
0531 theEvent.getByToken(phoChargedWorstVtxGeomVetoIsoToken_, phoChargedWorstVtxGeomVetoIsoMap);
0532 theEvent.getByToken(phoChargedPFPVIsoToken_, phoChargedPFPVIsoMap);
0533
0534
0535 if (!phoPFECALClusIsolationToken_.isUninitialized()) {
0536 theEvent.getByToken(phoPFECALClusIsolationToken_, phoPFECALClusIsolationMap);
0537 }
0538 if (!phoPFHCALClusIsolationToken_.isUninitialized()) {
0539 theEvent.getByToken(phoPFHCALClusIsolationToken_, phoPFHCALClusIsolationMap);
0540 }
0541
0542 if (photonHandle.isValid()) {
0543 validPhotonHandle = true;
0544 } else {
0545 throw cms::Exception("GEDPhotonProducer") << "Error! Can't get the product " << photonProducer_.label() << "\n";
0546 }
0547 } else {
0548 theEvent.getByToken(photonCoreProducerT_, photonCoreHandle);
0549 if (photonCoreHandle.isValid()) {
0550 validPhotonCoreHandle = true;
0551 } else {
0552 throw cms::Exception("GEDPhotonProducer")
0553 << "Error! Can't get the photonCoreProducer " << photonProducer_.label() << "\n";
0554 }
0555 }
0556
0557
0558 auto const& barrelRecHits = theEvent.get(barrelEcalHits_);
0559 auto const& endcapRecHits = theEvent.get(endcapEcalHits_);
0560 auto const& preshowerRecHits = theEvent.get(preshowerHits_);
0561
0562 Handle<reco::PFCandidateCollection> pfEGCandidateHandle;
0563
0564 if (not pfEgammaCandidates_.isUninitialized()) {
0565 theEvent.getByToken(pfEgammaCandidates_, pfEGCandidateHandle);
0566 if (!pfEGCandidateHandle.isValid()) {
0567 throw cms::Exception("GEDPhotonProducer") << "Error! Can't get the pfEgammaCandidates";
0568 }
0569 }
0570
0571 Handle<reco::PFCandidateCollection> pfCandidateHandle;
0572
0573 if (recoStep_.isFinal()) {
0574
0575 theEvent.getByToken(pfCandidates_, pfCandidateHandle);
0576
0577 if (!pfCandidateHandle.isValid() && !recoStep_.isOOT()) {
0578 throw cms::Exception("GEDPhotonProducer") << "Error! Can't get the pfCandidates";
0579 }
0580 }
0581
0582
0583 caloGeom_ = &eventSetup.getData(caloGeometryToken_);
0584
0585
0586 if (hcalHelperCone_ != nullptr and hcalHelperBc_ != nullptr) {
0587 hcalHelperCone_->beginEvent(theEvent, eventSetup);
0588 hcalHelperBc_->beginEvent(theEvent, eventSetup);
0589 }
0590
0591 auto const& topology = eventSetup.getData(caloTopologyToken_);
0592 auto const& thresholds = eventSetup.getData(ecalPFRechitThresholdsToken_);
0593
0594
0595 const reco::VertexCollection dummyVC;
0596 auto const& vertexCollection{usePrimaryVertex_ ? theEvent.get(vertexProducer_) : dummyVC};
0597
0598
0599
0600
0601
0602 photonEnergyCorrector_->init(eventSetup);
0603 if (photonEnergyCorrector_->gedRegression()) {
0604 photonEnergyCorrector_->gedRegression()->setEvent(theEvent);
0605 photonEnergyCorrector_->gedRegression()->setEventContent(eventSetup);
0606 }
0607
0608
0609 ecalisoAlgo = std::make_unique<PhotonEcalPFClusterIsolation>(ecaldrMax_,
0610 ecaldrVetoBarrel_,
0611 ecaldrVetoEndcap_,
0612 ecaletaStripBarrel_,
0613 ecaletaStripEndcap_,
0614 ecalenergyBarrel_,
0615 ecalenergyEndcap_);
0616
0617 hcalisoAlgo = std::make_unique<PhotonHcalPFClusterIsolation>(hcaldrMax_,
0618 hcaldrVetoBarrel_,
0619 hcaldrVetoEndcap_,
0620 hcaletaStripBarrel_,
0621 hcaletaStripEndcap_,
0622 hcalenergyBarrel_,
0623 hcalenergyEndcap_,
0624 hcaluseEt_);
0625
0626 int iSC = 0;
0627
0628 if (validPhotonCoreHandle)
0629 fillPhotonCollection(theEvent,
0630 eventSetup,
0631 photonCoreHandle,
0632 &topology,
0633 &barrelRecHits,
0634 &endcapRecHits,
0635 &preshowerRecHits,
0636 hcalHelperCone_.get(),
0637 hcalHelperBc_.get(),
0638
0639 vertexCollection,
0640 *outputPhotonCollection_p,
0641 iSC,
0642 thresholds);
0643
0644 iSC = 0;
0645 if (validPhotonHandle && recoStep_.isFinal())
0646 fillPhotonCollection(theEvent,
0647 eventSetup,
0648 photonHandle,
0649 pfCandidateHandle,
0650 pfEGCandidateHandle,
0651 theEvent.get(vertexProducer_),
0652 *outputPhotonCollection_p,
0653 iSC,
0654 phoChargedIsolationMap,
0655 phoNeutralHadronIsolationMap,
0656 phoPhotonIsolationMap,
0657 phoChargedWorstVtxIsoMap,
0658 phoChargedWorstVtxGeomVetoIsoMap,
0659 phoChargedPFPVIsoMap,
0660 phoPFECALClusIsolationMap,
0661 phoPFHCALClusIsolationMap);
0662
0663
0664 edm::LogInfo("GEDPhotonProducer") << " Put in the event " << iSC << " Photon Candidates \n";
0665
0666
0667 if (hcalRun2EffDepth_) {
0668 for (auto& pho : *outputPhotonCollection_p)
0669 pho.hcalToRun2EffDepth();
0670 }
0671 const auto photonOrphHandle = theEvent.put(std::move(outputPhotonCollection_p), photonCollection_);
0672
0673 if (!recoStep_.isFinal() && not pfEgammaCandidates_.isUninitialized()) {
0674
0675 auto pfEGCandToPhotonMap_p = std::make_unique<edm::ValueMap<reco::PhotonRef>>();
0676 edm::ValueMap<reco::PhotonRef>::Filler filler(*pfEGCandToPhotonMap_p);
0677 unsigned nObj = pfEGCandidateHandle->size();
0678 std::vector<reco::PhotonRef> values(nObj);
0679
0680 for (unsigned int lCand = 0; lCand < nObj; lCand++) {
0681 reco::PFCandidateRef pfCandRef(reco::PFCandidateRef(pfEGCandidateHandle, lCand));
0682 reco::SuperClusterRef pfScRef = pfCandRef->superClusterRef();
0683
0684 for (unsigned int lSC = 0; lSC < photonOrphHandle->size(); lSC++) {
0685 reco::PhotonRef photonRef(reco::PhotonRef(photonOrphHandle, lSC));
0686 reco::SuperClusterRef scRef = photonRef->superCluster();
0687 if (pfScRef != scRef)
0688 continue;
0689 values[lCand] = photonRef;
0690 }
0691 }
0692
0693 filler.insert(pfEGCandidateHandle, values.begin(), values.end());
0694 filler.fill();
0695 theEvent.put(std::move(pfEGCandToPhotonMap_p), valueMapPFCandPhoton_);
0696 }
0697 }
0698
0699 void GEDPhotonProducer::fillPhotonCollection(edm::Event& evt,
0700 edm::EventSetup const& es,
0701 const edm::Handle<reco::PhotonCoreCollection>& photonCoreHandle,
0702 const CaloTopology* topology,
0703 const EcalRecHitCollection* ecalBarrelHits,
0704 const EcalRecHitCollection* ecalEndcapHits,
0705 const EcalRecHitCollection* preshowerHits,
0706 const ElectronHcalHelper* hcalHelperCone,
0707 const ElectronHcalHelper* hcalHelperBc,
0708 const reco::VertexCollection& vertexCollection,
0709 reco::PhotonCollection& outputPhotonCollection,
0710 int& iSC,
0711 EcalPFRecHitThresholds const& thresholds) {
0712 const EcalRecHitCollection* hits = nullptr;
0713 std::vector<double> preselCutValues;
0714 std::vector<int> flags_, severitiesexcl_;
0715
0716 for (unsigned int lSC = 0; lSC < photonCoreHandle->size(); lSC++) {
0717 reco::PhotonCoreRef coreRef(reco::PhotonCoreRef(photonCoreHandle, lSC));
0718 reco::SuperClusterRef parentSCRef = coreRef->parentSuperCluster();
0719 reco::SuperClusterRef scRef = coreRef->superCluster();
0720
0721
0722 iSC++;
0723
0724 DetId::Detector thedet = scRef->seed()->hitsAndFractions()[0].first.det();
0725 int subdet = scRef->seed()->hitsAndFractions()[0].first.subdetId();
0726 if (subdet == EcalBarrel) {
0727 preselCutValues = preselCutValuesBarrel_;
0728 hits = ecalBarrelHits;
0729 flags_ = flagsexclEB_;
0730 severitiesexcl_ = severitiesexclEB_;
0731 } else if (subdet == EcalEndcap) {
0732 preselCutValues = preselCutValuesEndcap_;
0733 hits = ecalEndcapHits;
0734 flags_ = flagsexclEE_;
0735 severitiesexcl_ = severitiesexclEE_;
0736 } else if (EcalTools::isHGCalDet(thedet)) {
0737 preselCutValues = preselCutValuesEndcap_;
0738 hits = nullptr;
0739 flags_ = flagsexclEE_;
0740 severitiesexcl_ = severitiesexclEE_;
0741 } else {
0742 edm::LogWarning("") << "GEDPhotonProducer: do not know if it is a barrel or endcap SuperCluster: " << thedet
0743 << ' ' << subdet;
0744 }
0745
0746
0747 if (parentSCRef.isNonnull() &&
0748 ptFast(parentSCRef->energy(), parentSCRef->position(), {0, 0, 0}) <= preselCutValues[0])
0749 continue;
0750
0751 float maxXtal = (hits != nullptr ? EcalClusterTools::eMax(*(scRef->seed()), hits) : 0.f);
0752
0753
0754
0755 float e1x5 = (hits != nullptr ? EcalClusterTools::e1x5(*(scRef->seed()), hits, topology) : 0.f);
0756 float e2x5 = (hits != nullptr ? EcalClusterTools::e2x5Max(*(scRef->seed()), hits, topology) : 0.f);
0757 float e3x3 = (hits != nullptr ? EcalClusterTools::e3x3(*(scRef->seed()), hits, topology) : 0.f);
0758 float e5x5 = (hits != nullptr ? EcalClusterTools::e5x5(*(scRef->seed()), hits, topology) : 0.f);
0759 const auto& cov = (hits != nullptr ? EcalClusterTools::covariances(*(scRef->seed()), hits, topology, caloGeom_)
0760 : std::array<float, 3>({{0.f, 0.f, 0.f}}));
0761
0762 const auto& locCov = (hits != nullptr ? EcalClusterTools::localCovariances(*(scRef->seed()), hits, topology)
0763 : std::array<float, 3>({{0.f, 0.f, 0.f}}));
0764
0765 float sigmaEtaEta = std::sqrt(cov[0]);
0766 float sigmaIetaIeta = std::sqrt(locCov[0]);
0767
0768 float full5x5_maxXtal = (hits != nullptr ? noZS::EcalClusterTools::eMax(*(scRef->seed()), hits) : 0.f);
0769
0770
0771 float full5x5_e1x5 = (hits != nullptr ? noZS::EcalClusterTools::e1x5(*(scRef->seed()), hits, topology) : 0.f);
0772 float full5x5_e2x5 = (hits != nullptr ? noZS::EcalClusterTools::e2x5Max(*(scRef->seed()), hits, topology) : 0.f);
0773 float full5x5_e3x3 = (hits != nullptr ? noZS::EcalClusterTools::e3x3(*(scRef->seed()), hits, topology) : 0.f);
0774 float full5x5_e5x5 = (hits != nullptr ? noZS::EcalClusterTools::e5x5(*(scRef->seed()), hits, topology) : 0.f);
0775 const auto& full5x5_cov =
0776 (hits != nullptr ? noZS::EcalClusterTools::covariances(*(scRef->seed()), hits, topology, caloGeom_)
0777 : std::array<float, 3>({{0.f, 0.f, 0.f}}));
0778
0779
0780
0781 const auto& full5x5_locCov =
0782 (hits != nullptr ? noZS::EcalClusterTools::localCovariances(*(scRef->seed()),
0783 hits,
0784 topology,
0785 EgammaLocalCovParamDefaults::kRelEnCut,
0786 &thresholds,
0787 multThresEB_,
0788 multThresEE_)
0789 : std::array<float, 3>({{0.f, 0.f, 0.f}}));
0790
0791 float full5x5_sigmaEtaEta = sqrt(full5x5_cov[0]);
0792 float full5x5_sigmaIetaIeta = sqrt(full5x5_locCov[0]);
0793 float full5x5_sigmaIetaIphi = full5x5_locCov[1];
0794
0795
0796 math::XYZPoint caloPosition = scRef->position();
0797
0798
0799 double photonEnergy = 1.;
0800 math::XYZPoint vtx(0., 0., 0.);
0801 if (!vertexCollection.empty())
0802 vtx = vertexCollection.begin()->position();
0803
0804 math::XYZVector direction = caloPosition - vtx;
0805
0806 math::XYZVector momentum = direction.unit();
0807
0808
0809 math::XYZTLorentzVectorD p4(momentum.x(), momentum.y(), momentum.z(), photonEnergy);
0810 reco::Photon newCandidate(p4, caloPosition, coreRef, vtx);
0811
0812
0813
0814
0815
0816 reco::Photon::FiducialFlags fiducialFlags;
0817 reco::Photon::IsolationVariables isolVarR03, isolVarR04;
0818 if (!EcalTools::isHGCalDet(thedet)) {
0819 photonIsoCalculator_->calculate(&newCandidate, evt, es, fiducialFlags, isolVarR04, isolVarR03, hcalCuts_);
0820 }
0821 newCandidate.setFiducialVolumeFlags(fiducialFlags);
0822 newCandidate.setIsolationVariables(isolVarR04, isolVarR03);
0823
0824
0825 reco::Photon::ShowerShape showerShape;
0826 showerShape.e1x5 = e1x5;
0827 showerShape.e2x5 = e2x5;
0828 showerShape.e3x3 = e3x3;
0829 showerShape.e5x5 = e5x5;
0830 showerShape.maxEnergyXtal = maxXtal;
0831 showerShape.sigmaEtaEta = sigmaEtaEta;
0832 showerShape.sigmaIetaIeta = sigmaIetaIeta;
0833 for (uint id = 0; id < showerShape.hcalOverEcal.size(); ++id) {
0834 showerShape.hcalOverEcal[id] =
0835 (hcalHelperCone != nullptr) ? hcalHelperCone->hcalESum(*scRef, id + 1, hcalCuts_) / scRef->energy() : 0.f;
0836
0837 showerShape.hcalOverEcalBc[id] =
0838 (hcalHelperBc != nullptr) ? hcalHelperBc->hcalESum(*scRef, id + 1, hcalCuts_) / scRef->energy() : 0.f;
0839 }
0840 showerShape.invalidHcal = (hcalHelperBc != nullptr) ? !hcalHelperBc->hasActiveHcal(*scRef) : false;
0841 if (hcalHelperBc != nullptr)
0842 showerShape.hcalTowersBehindClusters = hcalHelperBc->hcalTowersBehindClusters(*scRef);
0843 showerShape.pre7DepthHcal = false;
0844
0845
0846 const float spp = (!edm::isFinite(locCov[2]) ? 0. : sqrt(locCov[2]));
0847 const float sep = locCov[1];
0848 showerShape.sigmaIetaIphi = sep;
0849 showerShape.sigmaIphiIphi = spp;
0850 showerShape.e2nd = (hits != nullptr ? EcalClusterTools::e2nd(*(scRef->seed()), hits) : 0.f);
0851 showerShape.eTop = (hits != nullptr ? EcalClusterTools::eTop(*(scRef->seed()), hits, topology) : 0.f);
0852 showerShape.eLeft = (hits != nullptr ? EcalClusterTools::eLeft(*(scRef->seed()), hits, topology) : 0.f);
0853 showerShape.eRight = (hits != nullptr ? EcalClusterTools::eRight(*(scRef->seed()), hits, topology) : 0.f);
0854 showerShape.eBottom = (hits != nullptr ? EcalClusterTools::eBottom(*(scRef->seed()), hits, topology) : 0.f);
0855 showerShape.e1x3 = (hits != nullptr ? EcalClusterTools::e1x3(*(scRef->seed()), hits, topology) : 0.f);
0856 showerShape.e2x2 = (hits != nullptr ? EcalClusterTools::e2x2(*(scRef->seed()), hits, topology) : 0.f);
0857 showerShape.e2x5Max = (hits != nullptr ? EcalClusterTools::e2x5Max(*(scRef->seed()), hits, topology) : 0.f);
0858 showerShape.e2x5Left = (hits != nullptr ? EcalClusterTools::e2x5Left(*(scRef->seed()), hits, topology) : 0.f);
0859 showerShape.e2x5Right = (hits != nullptr ? EcalClusterTools::e2x5Right(*(scRef->seed()), hits, topology) : 0.f);
0860 showerShape.e2x5Top = (hits != nullptr ? EcalClusterTools::e2x5Top(*(scRef->seed()), hits, topology) : 0.f);
0861 showerShape.e2x5Bottom = (hits != nullptr ? EcalClusterTools::e2x5Bottom(*(scRef->seed()), hits, topology) : 0.f);
0862 if (hits) {
0863 Cluster2ndMoments clus2ndMoments = EcalClusterTools::cluster2ndMoments(*(scRef->seed()), *hits);
0864 showerShape.smMajor = clus2ndMoments.sMaj;
0865 showerShape.smMinor = clus2ndMoments.sMin;
0866 showerShape.smAlpha = clus2ndMoments.alpha;
0867 } else {
0868 showerShape.smMajor = 0.f;
0869 showerShape.smMinor = 0.f;
0870 showerShape.smAlpha = 0.f;
0871 }
0872
0873
0874 EcalClusterLazyTools toolsforES(
0875 evt, ecalClusterESGetTokens_.get(es), barrelEcalHits_, endcapEcalHits_, preshowerHits_);
0876 const float sigmaRR = toolsforES.eseffsirir(*scRef);
0877 showerShape.effSigmaRR = sigmaRR;
0878 newCandidate.setShowerShapeVariables(showerShape);
0879
0880 const reco::CaloCluster& seedCluster = *(scRef->seed());
0881 DetId seedXtalId = seedCluster.seed();
0882 int nSaturatedXtals = 0;
0883 bool isSeedSaturated = false;
0884 if (hits != nullptr) {
0885 const auto hitsAndFractions = scRef->hitsAndFractions();
0886 for (auto const& hitFractionPair : hitsAndFractions) {
0887 auto&& ecalRecHit = hits->find(hitFractionPair.first);
0888 if (ecalRecHit == hits->end())
0889 continue;
0890 if (ecalRecHit->checkFlag(EcalRecHit::Flags::kSaturated)) {
0891 nSaturatedXtals++;
0892 if (seedXtalId == ecalRecHit->detid())
0893 isSeedSaturated = true;
0894 }
0895 }
0896 }
0897 reco::Photon::SaturationInfo saturationInfo;
0898 saturationInfo.nSaturatedXtals = nSaturatedXtals;
0899 saturationInfo.isSeedSaturated = isSeedSaturated;
0900 newCandidate.setSaturationInfo(saturationInfo);
0901
0902
0903 reco::Photon::ShowerShape full5x5_showerShape;
0904 full5x5_showerShape.e1x5 = full5x5_e1x5;
0905 full5x5_showerShape.e2x5 = full5x5_e2x5;
0906 full5x5_showerShape.e3x3 = full5x5_e3x3;
0907 full5x5_showerShape.e5x5 = full5x5_e5x5;
0908 full5x5_showerShape.maxEnergyXtal = full5x5_maxXtal;
0909 full5x5_showerShape.sigmaEtaEta = full5x5_sigmaEtaEta;
0910 full5x5_showerShape.sigmaIetaIeta = full5x5_sigmaIetaIeta;
0911
0912 const float full5x5_spp = (!edm::isFinite(full5x5_locCov[2]) ? 0. : std::sqrt(full5x5_locCov[2]));
0913 const float full5x5_sep = full5x5_sigmaIetaIphi;
0914 full5x5_showerShape.sigmaIetaIphi = full5x5_sep;
0915 full5x5_showerShape.sigmaIphiIphi = full5x5_spp;
0916 full5x5_showerShape.e2nd = (hits != nullptr ? noZS::EcalClusterTools::e2nd(*(scRef->seed()), hits) : 0.f);
0917 full5x5_showerShape.eTop = (hits != nullptr ? noZS::EcalClusterTools::eTop(*(scRef->seed()), hits, topology) : 0.f);
0918 full5x5_showerShape.eLeft =
0919 (hits != nullptr ? noZS::EcalClusterTools::eLeft(*(scRef->seed()), hits, topology) : 0.f);
0920 full5x5_showerShape.eRight =
0921 (hits != nullptr ? noZS::EcalClusterTools::eRight(*(scRef->seed()), hits, topology) : 0.f);
0922 full5x5_showerShape.eBottom =
0923 (hits != nullptr ? noZS::EcalClusterTools::eBottom(*(scRef->seed()), hits, topology) : 0.f);
0924 full5x5_showerShape.e1x3 = (hits != nullptr ? noZS::EcalClusterTools::e1x3(*(scRef->seed()), hits, topology) : 0.f);
0925 full5x5_showerShape.e2x2 = (hits != nullptr ? noZS::EcalClusterTools::e2x2(*(scRef->seed()), hits, topology) : 0.f);
0926 full5x5_showerShape.e2x5Max =
0927 (hits != nullptr ? noZS::EcalClusterTools::e2x5Max(*(scRef->seed()), hits, topology) : 0.f);
0928 full5x5_showerShape.e2x5Left =
0929 (hits != nullptr ? noZS::EcalClusterTools::e2x5Left(*(scRef->seed()), hits, topology) : 0.f);
0930 full5x5_showerShape.e2x5Right =
0931 (hits != nullptr ? noZS::EcalClusterTools::e2x5Right(*(scRef->seed()), hits, topology) : 0.f);
0932 full5x5_showerShape.e2x5Top =
0933 (hits != nullptr ? noZS::EcalClusterTools::e2x5Top(*(scRef->seed()), hits, topology) : 0.f);
0934 full5x5_showerShape.e2x5Bottom =
0935 (hits != nullptr ? noZS::EcalClusterTools::e2x5Bottom(*(scRef->seed()), hits, topology) : 0.f);
0936 if (hits) {
0937 Cluster2ndMoments clus2ndMoments = noZS::EcalClusterTools::cluster2ndMoments(*(scRef->seed()), *hits);
0938 full5x5_showerShape.smMajor = clus2ndMoments.sMaj;
0939 full5x5_showerShape.smMinor = clus2ndMoments.sMin;
0940 full5x5_showerShape.smAlpha = clus2ndMoments.alpha;
0941 } else {
0942 full5x5_showerShape.smMajor = 0.f;
0943 full5x5_showerShape.smMinor = 0.f;
0944 full5x5_showerShape.smAlpha = 0.f;
0945 }
0946
0947 full5x5_showerShape.effSigmaRR = sigmaRR;
0948 for (uint id = 0; id < full5x5_showerShape.hcalOverEcal.size(); ++id) {
0949 full5x5_showerShape.hcalOverEcal[id] =
0950 (hcalHelperCone != nullptr) ? hcalHelperCone->hcalESum(*scRef, id + 1, hcalCuts_) / full5x5_e5x5 : 0.f;
0951 full5x5_showerShape.hcalOverEcalBc[id] =
0952 (hcalHelperBc != nullptr) ? hcalHelperBc->hcalESum(*scRef, id + 1, hcalCuts_) / full5x5_e5x5 : 0.f;
0953 }
0954 full5x5_showerShape.pre7DepthHcal = false;
0955 newCandidate.full5x5_setShowerShapeVariables(full5x5_showerShape);
0956
0957
0958 edm::Ptr<reco::PhotonCore> photonPtr(photonCoreHandle, lSC);
0959
0960
0961
0962
0963
0964 if (dnnPFidEnabled_) {
0965 auto clusterHandle = evt.getHandle(pfClusterProducer_);
0966 std::vector<edm::Handle<reco::PFClusterCollection>> clusterHandles{evt.getHandle(pfClusterProducerHCAL_)};
0967 if (useHF_) {
0968 clusterHandles.push_back(evt.getHandle(pfClusterProducerHFEM_));
0969 clusterHandles.push_back(evt.getHandle(pfClusterProducerHFHAD_));
0970 }
0971 reco::Photon::PflowIsolationVariables pfIso;
0972 pfIso.sumEcalClusterEt = ecalisoAlgo->getSum(newCandidate, clusterHandle);
0973 pfIso.sumHcalClusterEt = hcalisoAlgo->getSum(newCandidate, clusterHandles);
0974
0975 newCandidate.setPflowIsolationVariables(pfIso);
0976 }
0977
0978
0979
0980
0981
0982 if (!EcalTools::isHGCalDet(thedet)) {
0983 photonEnergyCorrector_->calculate(evt, newCandidate, subdet, vertexCollection, es);
0984 if (candidateP4type_ == "fromEcalEnergy") {
0985 newCandidate.setP4(newCandidate.p4(reco::Photon::ecal_photons));
0986 newCandidate.setCandidateP4type(reco::Photon::ecal_photons);
0987 newCandidate.setMass(0.0);
0988 } else if (candidateP4type_ == "fromRegression1") {
0989 newCandidate.setP4(newCandidate.p4(reco::Photon::regression1));
0990 newCandidate.setCandidateP4type(reco::Photon::regression1);
0991 newCandidate.setMass(0.0);
0992 } else if (candidateP4type_ == "fromRegression2") {
0993 newCandidate.setP4(newCandidate.p4(reco::Photon::regression2));
0994 newCandidate.setCandidateP4type(reco::Photon::regression2);
0995 newCandidate.setMass(0.0);
0996 } else if (candidateP4type_ == "fromRefinedSCRegression") {
0997 newCandidate.setP4(newCandidate.p4(reco::Photon::regression2));
0998 newCandidate.setCandidateP4type(reco::Photon::regression2);
0999 newCandidate.setMass(0.0);
1000 }
1001 } else {
1002 math::XYZVector gamma_momentum = direction.unit() * scRef->energy();
1003 math::PtEtaPhiMLorentzVector p4(gamma_momentum.rho(), gamma_momentum.eta(), gamma_momentum.phi(), 0.0);
1004 newCandidate.setP4(p4);
1005 newCandidate.setCandidateP4type(reco::Photon::ecal_photons);
1006
1007 reco::Photon::FiducialFlags fiducialFlags;
1008 fiducialFlags.isEE = true;
1009 newCandidate.setFiducialVolumeFlags(fiducialFlags);
1010 }
1011
1012
1013 reco::Photon::MIPVariables mipVar;
1014 if (subdet == EcalBarrel && runMIPTagger_) {
1015 photonMIPHaloTagger_->MIPcalculate(&newCandidate, evt, es, mipVar);
1016 newCandidate.setMIPVariables(mipVar);
1017 }
1018
1019
1020 bool isLooseEM = true;
1021 if (newCandidate.pt() < highEt_) {
1022 if (newCandidate.hadronicOverEm() >= preselCutValues[1])
1023 isLooseEM = false;
1024 if (newCandidate.ecalRecHitSumEtConeDR04() > preselCutValues[2] + preselCutValues[3] * newCandidate.pt())
1025 isLooseEM = false;
1026 if (newCandidate.hcalTowerSumEtConeDR04() > preselCutValues[4] + preselCutValues[5] * newCandidate.pt())
1027 isLooseEM = false;
1028 if (newCandidate.nTrkSolidConeDR04() > int(preselCutValues[6]))
1029 isLooseEM = false;
1030 if (newCandidate.nTrkHollowConeDR04() > int(preselCutValues[7]))
1031 isLooseEM = false;
1032 if (newCandidate.trkSumPtSolidConeDR04() > preselCutValues[8])
1033 isLooseEM = false;
1034 if (newCandidate.trkSumPtHollowConeDR04() > preselCutValues[9])
1035 isLooseEM = false;
1036 if (newCandidate.sigmaIetaIeta() > preselCutValues[10])
1037 isLooseEM = false;
1038 }
1039
1040 if (isLooseEM)
1041 outputPhotonCollection.push_back(newCandidate);
1042 }
1043
1044 if (dnnPFidEnabled_) {
1045
1046 LogDebug("GEDPhotonProducer") << "Getting DNN PFId for photons";
1047 const auto& dnn_photon_pfid = globalCache()->photonDNNEstimator->evaluate(outputPhotonCollection, tfSessions_);
1048 size_t ipho = 0;
1049 for (auto& photon : outputPhotonCollection) {
1050 const auto& [iModel, values] = dnn_photon_pfid[ipho];
1051 reco::Photon::PflowIDVariables pfID;
1052
1053 pfID.dnn = values[0];
1054 photon.setPflowIDVariables(pfID);
1055 ipho++;
1056 }
1057 }
1058 }
1059
1060 void GEDPhotonProducer::fillPhotonCollection(edm::Event& evt,
1061 edm::EventSetup const& es,
1062 const edm::Handle<reco::PhotonCollection>& photonHandle,
1063 const edm::Handle<reco::PFCandidateCollection> pfCandidateHandle,
1064 const edm::Handle<reco::PFCandidateCollection> pfEGCandidateHandle,
1065 reco::VertexCollection const& vertexCollection,
1066 reco::PhotonCollection& outputPhotonCollection,
1067 int& iSC,
1068 const edm::Handle<edm::ValueMap<float>>& chargedHadrons,
1069 const edm::Handle<edm::ValueMap<float>>& neutralHadrons,
1070 const edm::Handle<edm::ValueMap<float>>& photons,
1071 const edm::Handle<edm::ValueMap<float>>& chargedHadronsWorstVtx,
1072 const edm::Handle<edm::ValueMap<float>>& chargedHadronsWorstVtxGeomVeto,
1073 const edm::Handle<edm::ValueMap<float>>& chargedHadronsPFPV,
1074 const edm::Handle<edm::ValueMap<float>>& pfEcalClusters,
1075 const edm::Handle<edm::ValueMap<float>>& pfHcalClusters) {
1076 std::vector<double> preselCutValues;
1077
1078 for (unsigned int lSC = 0; lSC < photonHandle->size(); lSC++) {
1079 reco::PhotonRef phoRef(reco::PhotonRef(photonHandle, lSC));
1080 reco::SuperClusterRef parentSCRef = phoRef->parentSuperCluster();
1081 reco::SuperClusterRef scRef = phoRef->superCluster();
1082 DetId::Detector thedet = scRef->seed()->hitsAndFractions()[0].first.det();
1083 int subdet = scRef->seed()->hitsAndFractions()[0].first.subdetId();
1084 if (subdet == EcalBarrel) {
1085 preselCutValues = preselCutValuesBarrel_;
1086 } else if (subdet == EcalEndcap) {
1087 preselCutValues = preselCutValuesEndcap_;
1088 } else if (EcalTools::isHGCalDet(thedet)) {
1089 preselCutValues = preselCutValuesEndcap_;
1090 } else {
1091 edm::LogWarning("") << "GEDPhotonProducer: do not know if it is a barrel or endcap SuperCluster" << thedet << ' '
1092 << subdet;
1093 }
1094
1095
1096 if (parentSCRef.isNonnull() &&
1097 ptFast(parentSCRef->energy(), parentSCRef->position(), {0, 0, 0}) <= preselCutValues[0])
1098 continue;
1099
1100 reco::Photon newCandidate(*phoRef);
1101 iSC++;
1102
1103 if (runMVABasedHaloTagger_) {
1104 float BHmva = photonMVABasedHaloTagger_->calculateMVA(&newCandidate, globalCache()->haloTaggerGBR.get(), evt, es);
1105 newCandidate.setHaloTaggerMVAVal(BHmva);
1106 }
1107
1108
1109 reco::Photon::PflowIsolationVariables pfIso;
1110
1111
1112
1113 edm::Ptr<reco::Photon> photonPtr(photonHandle, lSC);
1114
1115 if (!recoStep_.isOOT()) {
1116 pfIso.chargedHadronIso = (*chargedHadrons)[photonPtr];
1117 pfIso.neutralHadronIso = (*neutralHadrons)[photonPtr];
1118 pfIso.photonIso = (*photons)[photonPtr];
1119 pfIso.chargedHadronWorstVtxIso = (*chargedHadronsWorstVtx)[photonPtr];
1120 pfIso.chargedHadronWorstVtxGeomVetoIso = (*chargedHadronsWorstVtxGeomVeto)[photonPtr];
1121 pfIso.chargedHadronPFPVIso = (*chargedHadronsPFPV)[photonPtr];
1122 }
1123
1124
1125
1126 pfIso.sumEcalClusterEt = !phoPFECALClusIsolationToken_.isUninitialized() ? (*pfEcalClusters)[photonPtr] : 0.;
1127 pfIso.sumHcalClusterEt = !phoPFHCALClusIsolationToken_.isUninitialized() ? (*pfHcalClusters)[photonPtr] : 0.;
1128 newCandidate.setPflowIsolationVariables(pfIso);
1129
1130
1131 photonEnergyCorrector_->calculate(evt, newCandidate, subdet, vertexCollection, es);
1132 if (candidateP4type_ == "fromEcalEnergy") {
1133 newCandidate.setP4(newCandidate.p4(reco::Photon::ecal_photons));
1134 newCandidate.setCandidateP4type(reco::Photon::ecal_photons);
1135 newCandidate.setMass(0.0);
1136 } else if (candidateP4type_ == "fromRegression1") {
1137 newCandidate.setP4(newCandidate.p4(reco::Photon::regression1));
1138 newCandidate.setCandidateP4type(reco::Photon::regression1);
1139 newCandidate.setMass(0.0);
1140 } else if (candidateP4type_ == "fromRegression2") {
1141 newCandidate.setP4(newCandidate.p4(reco::Photon::regression2));
1142 newCandidate.setCandidateP4type(reco::Photon::regression2);
1143 newCandidate.setMass(0.0);
1144 } else if (candidateP4type_ == "fromRefinedSCRegression") {
1145 newCandidate.setP4(newCandidate.p4(reco::Photon::regression2));
1146 newCandidate.setCandidateP4type(reco::Photon::regression2);
1147 newCandidate.setMass(0.0);
1148 }
1149
1150 outputPhotonCollection.push_back(newCandidate);
1151 }
1152 }