File indexing completed on 2024-04-06 12:25:11
0001
0002
0003
0004
0005
0006
0007
0008 #include "RecoEgamma/PhotonIdentification/interface/PhotonMVABasedHaloTagger.h"
0009 #include "DataFormats/DetId/interface/DetId.h"
0010 #include "DataFormats/EcalDetId/interface/EBDetId.h"
0011 #include "DataFormats/EcalRecHit/interface/EcalRecHit.h"
0012
0013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0014 #include "RecoEcal/EgammaCoreTools/interface/EcalClusterTools.h"
0015 #include <DataFormats/Math/interface/deltaPhi.h>
0016 #include "CommonTools/MVAUtils/interface/GBRForestTools.h"
0017
0018 PhotonMVABasedHaloTagger::PhotonMVABasedHaloTagger(const edm::ParameterSet& conf, edm::ConsumesCollector&& iC)
0019 : geometryToken_(iC.esConsumes()),
0020 ecalPFRechitThresholdsToken_(iC.esConsumes()),
0021 ecalClusterToolsESGetTokens_(std::move(iC)) {
0022 rhoLabel_ = iC.consumes<double>(conf.getParameter<edm::InputTag>("rhoLabel"));
0023
0024 EBecalCollection_ = iC.consumes<EcalRecHitCollection>(conf.getParameter<edm::InputTag>("barrelEcalRecHitCollection"));
0025 EEecalCollection_ = iC.consumes<EcalRecHitCollection>(conf.getParameter<edm::InputTag>("endcapEcalRecHitCollection"));
0026 ESCollection_ = iC.consumes<EcalRecHitCollection>(conf.getParameter<edm::InputTag>("esRecHitCollection"));
0027 HBHERecHitsCollection_ = iC.consumes<HBHERecHitCollection>(conf.getParameter<edm::InputTag>("HBHERecHitsCollection"));
0028 recHitEThresholdHB_ = conf.getParameter<EgammaHcalIsolation::arrayHB>("recHitEThresholdHB");
0029 recHitEThresholdHE_ = conf.getParameter<EgammaHcalIsolation::arrayHE>("recHitEThresholdHE");
0030
0031 noiseThrES_ = conf.getParameter<double>("noiseThrES");
0032 }
0033
0034 double PhotonMVABasedHaloTagger::calculateMVA(const reco::Photon* pho,
0035 const GBRForest* gbr_,
0036 const edm::Event& iEvent,
0037 const edm::EventSetup& es) {
0038 bool isEB = pho->isEB();
0039
0040 if (isEB)
0041 return 1.0;
0042
0043
0044 double rho_ = iEvent.get(rhoLabel_);
0045
0046
0047 const auto& ecalRecHitsBarrel = iEvent.get(EBecalCollection_);
0048 const auto& ecalRecHitsEndcap = iEvent.get(EEecalCollection_);
0049 const auto& esRecHits = iEvent.get(ESCollection_);
0050 const auto& hbheRecHits = iEvent.get(HBHERecHitsCollection_);
0051
0052
0053 pG_ = es.getHandle(geometryToken_);
0054 const CaloGeometry* geo = pG_.product();
0055
0056
0057 auto const& thresholds = es.getData(ecalPFRechitThresholdsToken_);
0058
0059 noZS::EcalClusterLazyTools lazyToolnoZS(
0060 iEvent, ecalClusterToolsESGetTokens_.get(es), EBecalCollection_, EEecalCollection_);
0061
0062
0063 if (isEB)
0064 calphoClusCoordinECAL(geo, pho, &thresholds, ecalRecHitsBarrel);
0065 else
0066 calphoClusCoordinECAL(geo, pho, &thresholds, ecalRecHitsEndcap);
0067
0068
0069 calmatchedHBHECoordForBothHypothesis(geo, pho, hbheRecHits);
0070 calmatchedESCoordForBothHypothesis(geo, pho, esRecHits);
0071
0072
0073
0074 double angle_EE_HE_samedPhi = calAngleBetweenEEAndSubDet(
0075 hcalClusNhits_samedPhi_,
0076 hcalClusX_samedPhi_,
0077 hcalClusY_samedPhi_,
0078 hcalClusZ_samedPhi_);
0079
0080 double angle_EE_HE_samedR =
0081 calAngleBetweenEEAndSubDet(hcalClusNhits_samedR_, hcalClusX_samedR_, hcalClusY_samedR_, hcalClusZ_samedR_);
0082
0083 double angle_EE_ES_samedPhi = calAngleBetweenEEAndSubDet(
0084 preshowerNhits_samedPhi_, preshowerX_samedPhi_, preshowerY_samedPhi_, preshowerZ_samedPhi_);
0085
0086 double angle_EE_ES_samedR =
0087 calAngleBetweenEEAndSubDet(preshowerNhits_samedR_, preshowerX_samedR_, preshowerY_samedR_, preshowerZ_samedR_);
0088
0089
0090
0091 const auto& vCov = lazyToolnoZS.localCovariances(*(pho->superCluster()->seed()));
0092 double spp = (std::isnan(vCov[2]) ? 0. : sqrt(vCov[2]));
0093
0094
0095
0096 float vars[15];
0097
0098 vars[0] = preshowerE_samedPhi_;
0099 vars[1] = hcalClusE_samedPhi_;
0100 vars[2] = preshowerE_samedR_;
0101 vars[3] = hcalClusE_samedR_;
0102 vars[4] = pho->full5x5_r9();
0103 vars[5] = pho->superCluster()->etaWidth();
0104 vars[6] = pho->superCluster()->phiWidth();
0105 vars[7] = pho->full5x5_sigmaIetaIeta();
0106 vars[8] = spp;
0107 vars[9] = angle_EE_ES_samedR;
0108 vars[10] = angle_EE_HE_samedR;
0109 vars[11] = angle_EE_ES_samedPhi;
0110 vars[12] = angle_EE_HE_samedPhi;
0111 vars[13] = (pho->superCluster()->preshowerEnergyPlane1() + pho->superCluster()->preshowerEnergyPlane2()) /
0112 pho->superCluster()->rawEnergy();
0113 vars[14] = rho_;
0114
0115 double BHmva = gbr_->GetGradBoostClassifier(vars);
0116 return BHmva;
0117 }
0118
0119 void PhotonMVABasedHaloTagger::calphoClusCoordinECAL(const CaloGeometry* geo,
0120 const reco::Photon* pho,
0121 const EcalPFRecHitThresholds* thresholds,
0122 const EcalRecHitCollection& ecalRecHits) {
0123 ecalClusX_ = 0;
0124 ecalClusY_ = 0;
0125 ecalClusZ_ = 0;
0126 ecalClusNhits_ = 0;
0127 ecalClusE_ = 0;
0128
0129 double phoSCEta = pho->superCluster()->eta();
0130 double phoSCPhi = pho->superCluster()->phi();
0131
0132 for (const auto& ecalrechit : ecalRecHits) {
0133 auto const det = ecalrechit.id();
0134 double rhE = ecalrechit.energy();
0135 const GlobalPoint& rechitPoint = geo->getPosition(det);
0136
0137 double rhEta = rechitPoint.eta();
0138 double rhPhi = rechitPoint.phi();
0139 double rhX = rechitPoint.x();
0140 double rhY = rechitPoint.y();
0141 double rhZ = rechitPoint.z();
0142
0143 if (thresholds == nullptr) {
0144 throw cms::Exception("EmptyPFRechHitThresCollection")
0145 << "In PhotonMVABasedHaloTagger::calphoClusCoordinECAL, EcalPFRecHitThresholds cannot be = nulptr";
0146 }
0147
0148 float rhThres = (*thresholds)[det];
0149
0150 if (rhE <= rhThres)
0151 continue;
0152
0153 if (phoSCEta * rhEta < 0)
0154 continue;
0155
0156 double dR2 = reco::deltaR2(rhEta, rhPhi, phoSCEta, phoSCPhi);
0157
0158 if (dR2 < dr2Max_ECALClus_) {
0159 ecalClusX_ += rhX * rhE;
0160 ecalClusY_ += rhY * rhE;
0161 ecalClusZ_ += rhZ * rhE;
0162 ecalClusE_ += rhE;
0163 ecalClusNhits_++;
0164 }
0165 }
0166
0167 if (ecalClusNhits_ > 0) {
0168 ecalClusX_ = ecalClusX_ / ecalClusE_;
0169 ecalClusY_ = ecalClusY_ / ecalClusE_;
0170 ecalClusZ_ = ecalClusZ_ / ecalClusE_;
0171 }
0172 }
0173
0174 void PhotonMVABasedHaloTagger::calmatchedHBHECoordForBothHypothesis(const CaloGeometry* geo,
0175 const reco::Photon* pho,
0176 const HBHERecHitCollection& HBHERecHits) {
0177 hcalClusX_samedPhi_ = 0;
0178 hcalClusY_samedPhi_ = 0;
0179 hcalClusZ_samedPhi_ = 0;
0180
0181 hcalClusNhits_samedPhi_ = 0;
0182 hcalClusE_samedPhi_ = 0;
0183
0184 hcalClusX_samedR_ = 0;
0185 hcalClusY_samedR_ = 0;
0186 hcalClusZ_samedR_ = 0;
0187 hcalClusNhits_samedR_ = 0;
0188 hcalClusE_samedR_ = 0;
0189
0190 double phoSCEta = pho->superCluster()->eta();
0191 double phoSCPhi = pho->superCluster()->phi();
0192
0193
0194 for (const auto& hbherechit : HBHERecHits) {
0195 HcalDetId det = hbherechit.id();
0196 const GlobalPoint& rechitPoint = geo->getPosition(det);
0197
0198 double rhEta = rechitPoint.eta();
0199 double rhPhi = rechitPoint.phi();
0200 double rhX = rechitPoint.x();
0201 double rhY = rechitPoint.y();
0202 double rhZ = rechitPoint.z();
0203 double rhE = hbherechit.energy();
0204
0205 int depth = det.depth();
0206
0207 if ((det.subdet() == HcalBarrel and (depth < 1 or depth > int(recHitEThresholdHB_.size()))) or
0208 (det.subdet() == HcalEndcap and (depth < 1 or depth > int(recHitEThresholdHE_.size())))) {
0209 edm::LogWarning("PhotonMVABasedHaloTagger")
0210 << " hit in subdet " << det.subdet() << " has an unaccounted for depth of " << depth
0211 << "!! Leaving this hit!!";
0212 continue;
0213 }
0214
0215 const bool goodHBe = det.subdet() == HcalBarrel and rhE > recHitEThresholdHB_[depth - 1];
0216 const bool goodHEe = det.subdet() == HcalEndcap and rhE > recHitEThresholdHE_[depth - 1];
0217 if (!(goodHBe or goodHEe))
0218 continue;
0219
0220 if (phoSCEta * rhEta < 0)
0221 continue;
0222
0223 double dPhi = deltaPhi(phoSCPhi, rhPhi);
0224
0225
0226 bool isRHBehindECAL = std::abs(dPhi) < dPhiMax_HCALClus_SamePhi_;
0227 if (isRHBehindECAL) {
0228 double rho2 = pow(rhX, 2) + pow(rhY, 2);
0229 isRHBehindECAL &= (rho2 >= rho2Min_ECALpos_ && rho2 <= rho2Max_ECALpos_);
0230 if (isRHBehindECAL) {
0231 double dRho2 = pow(rhX - ecalClusX_, 2) + pow(rhY - ecalClusY_, 2);
0232 isRHBehindECAL &= dRho2 <= dRho2Max_HCALClus_SamePhi_;
0233 if (isRHBehindECAL) {
0234 hcalClusX_samedPhi_ += rhX * rhE;
0235 hcalClusY_samedPhi_ += rhY * rhE;
0236 hcalClusZ_samedPhi_ += rhZ * rhE;
0237 hcalClusE_samedPhi_ += rhE;
0238 hcalClusNhits_samedPhi_++;
0239 }
0240 }
0241 }
0242
0243
0244 if (!isRHBehindECAL) {
0245 double dR2 = reco::deltaR2(phoSCEta, phoSCPhi, rhEta, rhPhi);
0246 if (dR2 < dR2Max_HCALClus_SamePhi_) {
0247 hcalClusX_samedR_ += rhX * rhE;
0248 hcalClusY_samedR_ += rhY * rhE;
0249 hcalClusZ_samedR_ += rhZ * rhE;
0250 hcalClusE_samedR_ += rhE;
0251 hcalClusNhits_samedR_++;
0252 }
0253 }
0254 }
0255
0256 if (hcalClusNhits_samedPhi_ > 0) {
0257 hcalClusX_samedPhi_ = hcalClusX_samedPhi_ / hcalClusE_samedPhi_;
0258 hcalClusY_samedPhi_ = hcalClusY_samedPhi_ / hcalClusE_samedPhi_;
0259 hcalClusZ_samedPhi_ = hcalClusZ_samedPhi_ / hcalClusE_samedPhi_;
0260 }
0261
0262 if (hcalClusNhits_samedR_ > 0) {
0263 hcalClusX_samedR_ = hcalClusX_samedR_ / hcalClusE_samedR_;
0264 hcalClusY_samedR_ = hcalClusY_samedR_ / hcalClusE_samedR_;
0265 hcalClusZ_samedR_ = hcalClusZ_samedR_ / hcalClusE_samedR_;
0266 }
0267 }
0268
0269 void PhotonMVABasedHaloTagger::calmatchedESCoordForBothHypothesis(const CaloGeometry* geo,
0270 const reco::Photon* pho,
0271 const EcalRecHitCollection& ESRecHits) {
0272 preshowerX_samedPhi_ = 0;
0273 preshowerY_samedPhi_ = 0;
0274 preshowerZ_samedPhi_ = 0;
0275 preshowerNhits_samedPhi_ = 0;
0276 preshowerE_samedPhi_ = 0;
0277
0278 preshowerX_samedR_ = 0;
0279 preshowerY_samedR_ = 0;
0280 preshowerZ_samedR_ = 0;
0281 preshowerNhits_samedR_ = 0;
0282 preshowerE_samedR_ = 0;
0283
0284 double phoSCEta = pho->superCluster()->eta();
0285 double phoSCPhi = pho->superCluster()->phi();
0286
0287 double tmpDiffdRho = 999;
0288 double matchX_samephi = -999;
0289 double matchY_samephi = -999;
0290 bool foundESRH_samephi = false;
0291
0292 double tmpDiffdRho_samedR = 999;
0293 double matchX_samedR = -999;
0294 double matchY_samedR = -999;
0295 bool foundESRH_samedR = false;
0296
0297
0298 double tan_theta = 1. / sinh(phoSCEta);
0299
0300 double cos_phi = cos(phoSCPhi);
0301 double sin_phi = sin(phoSCPhi);
0302
0303 for (const auto& esrechit : ESRecHits) {
0304 const GlobalPoint& rechitPoint = geo->getPosition(esrechit.id());
0305
0306 double rhEta = rechitPoint.eta();
0307 double rhX = rechitPoint.x();
0308 double rhY = rechitPoint.y();
0309 double rhZ = rechitPoint.z();
0310 double rhE = esrechit.energy();
0311
0312 if (phoSCEta * rhEta < 0)
0313 continue;
0314
0315 if (rhE < noiseThrES_)
0316 continue;
0317
0318
0319
0320
0321
0322
0323 double dRho2 = pow(rhX - ecalClusX_, 2) + pow(rhY - ecalClusY_, 2);
0324
0325 if (dRho2 < tmpDiffdRho && dRho2 < dRho2Max_ESClus_) {
0326 tmpDiffdRho = dRho2;
0327 matchX_samephi = rhX;
0328 matchY_samephi = rhY;
0329 foundESRH_samephi = true;
0330 }
0331
0332
0333
0334 double exp_ESRho = rhZ * tan_theta;
0335 double exp_ESX = cos_phi * exp_ESRho;
0336 double exp_ESY = sin_phi * exp_ESRho;
0337
0338 double dRho_samedR2 = pow(rhX - exp_ESX, 2) + pow(rhY - exp_ESY, 2);
0339
0340 if (dRho_samedR2 < tmpDiffdRho_samedR) {
0341 tmpDiffdRho_samedR = dRho_samedR2;
0342 matchX_samedR = rhX;
0343 matchY_samedR = rhY;
0344 foundESRH_samedR = true;
0345 }
0346
0347 }
0348
0349
0350
0351
0352 for (const auto& esrechit : ESRecHits) {
0353 const GlobalPoint& rechitPoint = geo->getPosition(esrechit.id());
0354
0355 double rhEta = rechitPoint.eta();
0356 double rhX = rechitPoint.x();
0357 double rhY = rechitPoint.y();
0358 double rhZ = rechitPoint.z();
0359 double rhE = esrechit.energy();
0360
0361 if (phoSCEta * rhEta < 0)
0362 continue;
0363 if (rhE < noiseThrES_)
0364 continue;
0365
0366
0367 bool isRHBehindECAL = foundESRH_samephi;
0368 if (isRHBehindECAL) {
0369 double dX_samephi = std::abs(matchX_samephi - rhX);
0370 double dY_samephi = std::abs(matchY_samephi - rhY);
0371 isRHBehindECAL &= (dX_samephi < dXY_ESClus_SamePhi_ && dY_samephi < dXY_ESClus_SamePhi_);
0372 if (isRHBehindECAL) {
0373 preshowerX_samedPhi_ += rhX * rhE;
0374 preshowerY_samedPhi_ += rhY * rhE;
0375 preshowerZ_samedPhi_ += rhZ * rhE;
0376 preshowerE_samedPhi_ += rhE;
0377 preshowerNhits_samedPhi_++;
0378 }
0379 }
0380
0381
0382 if (!isRHBehindECAL && foundESRH_samedR) {
0383 double dX_samedR = std::abs(matchX_samedR - rhX);
0384 double dY_samedR = std::abs(matchY_samedR - rhY);
0385
0386 if (dX_samedR < dXY_ESClus_SamedR_ && dY_samedR < dXY_ESClus_SamedR_) {
0387 preshowerX_samedR_ += rhX * rhE;
0388 preshowerY_samedR_ += rhY * rhE;
0389 preshowerZ_samedR_ += rhZ * rhE;
0390 preshowerE_samedR_ += rhE;
0391 preshowerNhits_samedR_++;
0392 }
0393 }
0394 }
0395
0396 if (preshowerNhits_samedPhi_ > 0) {
0397 preshowerX_samedPhi_ = preshowerX_samedPhi_ / preshowerE_samedPhi_;
0398 preshowerY_samedPhi_ = preshowerY_samedPhi_ / preshowerE_samedPhi_;
0399 preshowerZ_samedPhi_ = preshowerZ_samedPhi_ / preshowerE_samedPhi_;
0400 }
0401
0402 if (preshowerNhits_samedR_ > 0) {
0403 preshowerX_samedR_ = preshowerX_samedR_ / preshowerE_samedR_;
0404 preshowerY_samedR_ = preshowerY_samedR_ / preshowerE_samedR_;
0405 preshowerZ_samedR_ = preshowerZ_samedR_ / preshowerE_samedR_;
0406 }
0407 }
0408
0409 double PhotonMVABasedHaloTagger::calAngleBetweenEEAndSubDet(int nhits,
0410 double subdetClusX,
0411 double subdetClusY,
0412 double subdetClusZ) {
0413
0414
0415 double angle = -999;
0416
0417 if (ecalClusNhits_ > 0 && nhits > 0) {
0418 double dR =
0419 sqrt(pow(subdetClusX - ecalClusX_, 2) + pow(subdetClusY - ecalClusY_, 2) + pow(subdetClusZ - ecalClusZ_, 2));
0420
0421 double cosTheta = std::abs(subdetClusZ - ecalClusZ_) / dR;
0422
0423 angle = acos(cosTheta);
0424 }
0425
0426 return angle;
0427 }