File indexing completed on 2023-03-17 11:20:37
0001 #include "CaloExtractorByAssociator.h"
0002
0003 #include "DataFormats/Common/interface/Handle.h"
0004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0005 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0006
0007 #include "DataFormats/CaloTowers/interface/CaloTowerCollection.h"
0008 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
0009 #include "DataFormats/HcalDetId/interface/HcalSubdetector.h"
0010
0011 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
0012
0013 #include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h"
0014
0015 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
0016 #include "TrackingTools/TrackAssociator/interface/TrackAssociatorParameters.h"
0017 #include "TrackingTools/TrackAssociator/interface/TrackDetectorAssociator.h"
0018
0019 #include "DataFormats/Math/interface/deltaR.h"
0020
0021 using namespace edm;
0022 using namespace std;
0023 using namespace reco;
0024 using namespace muonisolation;
0025 using reco::isodeposit::Direction;
0026
0027 namespace {
0028 constexpr double dRMax_CandDep = 1.0;
0029 }
0030
0031 CaloExtractorByAssociator::CaloExtractorByAssociator(const ParameterSet& par, edm::ConsumesCollector&& iC)
0032 : theUseRecHitsFlag(par.getParameter<bool>("UseRecHitsFlag")),
0033 theDepositLabel(par.getUntrackedParameter<string>("DepositLabel")),
0034 theDepositInstanceLabels(par.getParameter<std::vector<std::string> >("DepositInstanceLabels")),
0035 thePropagatorName(par.getParameter<std::string>("PropagatorName")),
0036 theThreshold_E(par.getParameter<double>("Threshold_E")),
0037 theThreshold_H(par.getParameter<double>("Threshold_H")),
0038 theThreshold_HO(par.getParameter<double>("Threshold_HO")),
0039 theDR_Veto_E(par.getParameter<double>("DR_Veto_E")),
0040 theDR_Veto_H(par.getParameter<double>("DR_Veto_H")),
0041 theDR_Veto_HO(par.getParameter<double>("DR_Veto_HO")),
0042 theCenterConeOnCalIntersection(par.getParameter<bool>("CenterConeOnCalIntersection")),
0043 theDR_Max(par.getParameter<double>("DR_Max")),
0044 theNoise_EB(par.getParameter<double>("Noise_EB")),
0045 theNoise_EE(par.getParameter<double>("Noise_EE")),
0046 theNoise_HB(par.getParameter<double>("Noise_HB")),
0047 theNoise_HE(par.getParameter<double>("Noise_HE")),
0048 theNoise_HO(par.getParameter<double>("Noise_HO")),
0049 theNoiseTow_EB(par.getParameter<double>("NoiseTow_EB")),
0050 theNoiseTow_EE(par.getParameter<double>("NoiseTow_EE")),
0051 theService(nullptr),
0052 theAssociator(nullptr),
0053 bFieldToken_(iC.esConsumes()),
0054 thePrintTimeReport(par.getUntrackedParameter<bool>("PrintTimeReport")) {
0055 ParameterSet serviceParameters = par.getParameter<ParameterSet>("ServiceParameters");
0056 theService = new MuonServiceProxy(serviceParameters, edm::ConsumesCollector(iC));
0057
0058
0059 theAssociatorParameters = new TrackAssociatorParameters();
0060 theAssociatorParameters->loadParameters(par.getParameter<edm::ParameterSet>("TrackAssociatorParameters"), iC);
0061 theAssociator = new TrackDetectorAssociator();
0062
0063 if (theUseRecHitsFlag) {
0064 caloGeomToken_ = iC.esConsumes();
0065 }
0066 }
0067
0068 CaloExtractorByAssociator::~CaloExtractorByAssociator() {
0069 if (theAssociatorParameters)
0070 delete theAssociatorParameters;
0071 if (theService)
0072 delete theService;
0073 if (theAssociator)
0074 delete theAssociator;
0075 }
0076
0077 void CaloExtractorByAssociator::fillVetos(const edm::Event& event,
0078 const edm::EventSetup& eventSetup,
0079 const TrackCollection& muons) {
0080
0081
0082
0083 }
0084
0085 IsoDeposit CaloExtractorByAssociator::deposit(const Event& event,
0086 const EventSetup& eventSetup,
0087 const Track& muon) const {
0088 IsoDeposit::Direction muonDir(muon.eta(), muon.phi());
0089 IsoDeposit dep(muonDir);
0090
0091
0092
0093
0094
0095 return dep;
0096 }
0097
0098
0099 std::vector<IsoDeposit> CaloExtractorByAssociator::deposits(const Event& event,
0100 const EventSetup& eventSetup,
0101 const Track& muon) const {
0102 theService->update(eventSetup);
0103 theAssociator->setPropagator(&*(theService->propagator(thePropagatorName)));
0104
0105
0106
0107 if (theDepositInstanceLabels.size() != 3) {
0108 LogError("MuonIsolation") << "Configuration is inconsistent: Need 3 deposit instance labels";
0109 }
0110 if (!(theDepositInstanceLabels[0].compare(0, 1, std::string("e")) == 0) ||
0111 !(theDepositInstanceLabels[1].compare(0, 1, std::string("h")) == 0) ||
0112 !(theDepositInstanceLabels[2].compare(0, 2, std::string("ho")) == 0)) {
0113 LogWarning("MuonIsolation")
0114 << "Deposit instance labels do not look like (e*, h*, ho*):"
0115 << "proceed at your own risk. The extractor interprets lab0=from ecal; lab1=from hcal; lab2=from ho";
0116 }
0117
0118 typedef IsoDeposit::Veto Veto;
0119
0120
0121 IsoDeposit::Direction muonDir(muon.eta(), muon.phi());
0122
0123 IsoDeposit depEcal(muonDir);
0124 IsoDeposit depHcal(muonDir);
0125 IsoDeposit depHOcal(muonDir);
0126
0127 auto const& bField = eventSetup.getData(bFieldToken_);
0128
0129 reco::TransientTrack tMuon(muon, &bField);
0130 FreeTrajectoryState iFTS = tMuon.initialFreeState();
0131 TrackDetMatchInfo mInfo = theAssociator->associate(event, eventSetup, iFTS, *theAssociatorParameters);
0132
0133
0134 depEcal.setVeto(
0135 Veto(reco::isodeposit::Direction(mInfo.trkGlobPosAtEcal.eta(), mInfo.trkGlobPosAtEcal.phi()), theDR_Veto_E));
0136 depHcal.setVeto(
0137 Veto(reco::isodeposit::Direction(mInfo.trkGlobPosAtHcal.eta(), mInfo.trkGlobPosAtHcal.phi()), theDR_Veto_H));
0138 depHOcal.setVeto(
0139 Veto(reco::isodeposit::Direction(mInfo.trkGlobPosAtHO.eta(), mInfo.trkGlobPosAtHO.phi()), theDR_Veto_HO));
0140
0141 if (theCenterConeOnCalIntersection) {
0142 reco::isodeposit::Direction dirTmp = depEcal.veto().vetoDir;
0143 double dRtmp = depEcal.veto().dR;
0144 depEcal = IsoDeposit(dirTmp);
0145 depEcal.setVeto(Veto(dirTmp, dRtmp));
0146
0147 dirTmp = depHcal.veto().vetoDir;
0148 dRtmp = depHcal.veto().dR;
0149 depHcal = IsoDeposit(dirTmp);
0150 depHcal.setVeto(Veto(dirTmp, dRtmp));
0151
0152 dirTmp = depHOcal.veto().vetoDir;
0153 dRtmp = depHOcal.veto().dR;
0154 depHOcal = IsoDeposit(dirTmp);
0155 depHOcal.setVeto(Veto(dirTmp, dRtmp));
0156 }
0157
0158 if (theUseRecHitsFlag) {
0159
0160
0161 auto const& caloGeom = eventSetup.getData(caloGeomToken_);
0162
0163
0164 std::vector<const EcalRecHit*>::const_iterator eHitCI = mInfo.ecalRecHits.begin();
0165 for (; eHitCI != mInfo.ecalRecHits.end(); ++eHitCI) {
0166 const EcalRecHit* eHitCPtr = *eHitCI;
0167 GlobalPoint eHitPos = caloGeom.getPosition(eHitCPtr->detid());
0168 double deltar0 = reco::deltaR(muon, eHitPos);
0169 double cosTheta = 1. / cosh(eHitPos.eta());
0170 double energy = eHitCPtr->energy();
0171 double et = energy * cosTheta;
0172 if (deltar0 > std::max(dRMax_CandDep, theDR_Max) ||
0173 !(et > theThreshold_E && energy > 3 * noiseRecHit(eHitCPtr->detid())))
0174 continue;
0175
0176 bool vetoHit = false;
0177 double deltar = reco::deltaR(mInfo.trkGlobPosAtEcal, eHitPos);
0178
0179 if (deltar < theDR_Veto_E) {
0180 LogDebug("RecoMuon|CaloExtractorByAssociator") << " >>> Veto ECAL hit: Calo deltaR= " << deltar;
0181 LogDebug("RecoMuon|CaloExtractorByAssociator")
0182 << " >>> Calo eta phi ethcal: " << eHitPos.eta() << " " << eHitPos.phi() << " " << et;
0183 vetoHit = true;
0184 }
0185
0186 if (!vetoHit) {
0187 for (unsigned int iH = 0; iH < mInfo.crossedEcalIds.size() && !vetoHit; ++iH) {
0188 if (mInfo.crossedEcalIds[iH].rawId() == eHitCPtr->detid().rawId())
0189 vetoHit = true;
0190 }
0191 }
0192
0193
0194 if (deltar0 > theDR_Max && !vetoHit)
0195 continue;
0196
0197 if (vetoHit) {
0198 depEcal.addCandEnergy(et);
0199 } else {
0200 depEcal.addDeposit(reco::isodeposit::Direction(eHitPos.eta(), eHitPos.phi()), et);
0201 }
0202 }
0203
0204
0205 std::vector<const HBHERecHit*>::const_iterator hHitCI = mInfo.hcalRecHits.begin();
0206 for (; hHitCI != mInfo.hcalRecHits.end(); ++hHitCI) {
0207 const HBHERecHit* hHitCPtr = *hHitCI;
0208 GlobalPoint hHitPos = caloGeom.getPosition(hHitCPtr->detid());
0209 double deltar0 = reco::deltaR(muon, hHitPos);
0210 double cosTheta = 1. / cosh(hHitPos.eta());
0211 double energy = hHitCPtr->energy();
0212 double et = energy * cosTheta;
0213 if (deltar0 > std::max(dRMax_CandDep, theDR_Max) ||
0214 !(et > theThreshold_H && energy > 3 * noiseRecHit(hHitCPtr->detid())))
0215 continue;
0216
0217 bool vetoHit = false;
0218 double deltar = reco::deltaR(mInfo.trkGlobPosAtHcal, hHitPos);
0219
0220 if (deltar < theDR_Veto_H) {
0221 LogDebug("RecoMuon|CaloExtractorByAssociator") << " >>> Veto HBHE hit: Calo deltaR= " << deltar;
0222 LogDebug("RecoMuon|CaloExtractorByAssociator")
0223 << " >>> Calo eta phi ethcal: " << hHitPos.eta() << " " << hHitPos.phi() << " " << et;
0224 vetoHit = true;
0225 }
0226
0227 if (!vetoHit) {
0228 for (unsigned int iH = 0; iH < mInfo.crossedHcalIds.size() && !vetoHit; ++iH) {
0229 if (mInfo.crossedHcalIds[iH].rawId() == hHitCPtr->detid().rawId())
0230 vetoHit = true;
0231 }
0232 }
0233
0234
0235 if (deltar0 > theDR_Max && !vetoHit)
0236 continue;
0237
0238 if (vetoHit) {
0239 depHcal.addCandEnergy(et);
0240 } else {
0241 depHcal.addDeposit(reco::isodeposit::Direction(hHitPos.eta(), hHitPos.phi()), et);
0242 }
0243 }
0244
0245
0246 std::vector<const HORecHit*>::const_iterator hoHitCI = mInfo.hoRecHits.begin();
0247 for (; hoHitCI != mInfo.hoRecHits.end(); ++hoHitCI) {
0248 const HORecHit* hoHitCPtr = *hoHitCI;
0249 GlobalPoint hoHitPos = caloGeom.getPosition(hoHitCPtr->detid());
0250 double deltar0 = reco::deltaR(muon, hoHitPos);
0251 double cosTheta = 1. / cosh(hoHitPos.eta());
0252 double energy = hoHitCPtr->energy();
0253 double et = energy * cosTheta;
0254 if (deltar0 > std::max(dRMax_CandDep, theDR_Max) ||
0255 !(et > theThreshold_HO && energy > 3 * noiseRecHit(hoHitCPtr->detid())))
0256 continue;
0257
0258 bool vetoHit = false;
0259 double deltar = reco::deltaR(mInfo.trkGlobPosAtHO, hoHitPos);
0260
0261 if (deltar < theDR_Veto_HO) {
0262 LogDebug("RecoMuon|CaloExtractorByAssociator") << " >>> Veto HO hit: Calo deltaR= " << deltar;
0263 LogDebug("RecoMuon|CaloExtractorByAssociator")
0264 << " >>> Calo eta phi ethcal: " << hoHitPos.eta() << " " << hoHitPos.phi() << " " << et;
0265 vetoHit = true;
0266 }
0267
0268 if (!vetoHit) {
0269 for (unsigned int iH = 0; iH < mInfo.crossedHOIds.size() && !vetoHit; ++iH) {
0270 if (mInfo.crossedHOIds[iH].rawId() == hoHitCPtr->detid().rawId())
0271 vetoHit = true;
0272 }
0273 }
0274
0275
0276 if (deltar0 > theDR_Max && !vetoHit)
0277 continue;
0278
0279 if (vetoHit) {
0280 depHOcal.addCandEnergy(et);
0281 } else {
0282 depHOcal.addDeposit(reco::isodeposit::Direction(hoHitPos.eta(), hoHitPos.phi()), et);
0283 }
0284 }
0285
0286 } else {
0287
0288 std::vector<const CaloTower*>::const_iterator calCI = mInfo.towers.begin();
0289 for (; calCI != mInfo.towers.end(); ++calCI) {
0290 const CaloTower* calCPtr = *calCI;
0291 double deltar0 = reco::deltaR(muon, *calCPtr);
0292 if (deltar0 > std::max(dRMax_CandDep, theDR_Max))
0293 continue;
0294
0295
0296 double etecal = calCPtr->emEt();
0297 double eecal = calCPtr->emEnergy();
0298 bool doEcal = etecal > theThreshold_E && eecal > 3 * noiseEcal(*calCPtr);
0299 double ethcal = calCPtr->hadEt();
0300 double ehcal = calCPtr->hadEnergy();
0301 bool doHcal = ethcal > theThreshold_H && ehcal > 3 * noiseHcal(*calCPtr);
0302 double ethocal = calCPtr->outerEt();
0303 double ehocal = calCPtr->outerEnergy();
0304 bool doHOcal = ethocal > theThreshold_HO && ehocal > 3 * noiseHOcal(*calCPtr);
0305 if ((!doEcal) && (!doHcal) && (!doHcal))
0306 continue;
0307
0308 bool vetoTowerEcal = false;
0309 double deltarEcal = reco::deltaR(mInfo.trkGlobPosAtEcal, *calCPtr);
0310
0311 if (deltarEcal < theDR_Veto_E) {
0312 LogDebug("RecoMuon|CaloExtractorByAssociator") << " >>> Veto ecal tower: Calo deltaR= " << deltarEcal;
0313 LogDebug("RecoMuon|CaloExtractorByAssociator")
0314 << " >>> Calo eta phi ethcal: " << calCPtr->eta() << " " << calCPtr->phi() << " " << ethcal;
0315 vetoTowerEcal = true;
0316 }
0317 bool vetoTowerHcal = false;
0318 double deltarHcal = reco::deltaR(mInfo.trkGlobPosAtHcal, *calCPtr);
0319
0320 if (deltarHcal < theDR_Veto_H) {
0321 LogDebug("RecoMuon|CaloExtractorByAssociator") << " >>> Veto hcal tower: Calo deltaR= " << deltarHcal;
0322 LogDebug("RecoMuon|CaloExtractorByAssociator")
0323 << " >>> Calo eta phi ethcal: " << calCPtr->eta() << " " << calCPtr->phi() << " " << ethcal;
0324 vetoTowerHcal = true;
0325 }
0326 bool vetoTowerHOCal = false;
0327 double deltarHOcal = reco::deltaR(mInfo.trkGlobPosAtHO, *calCPtr);
0328
0329 if (deltarHOcal < theDR_Veto_HO) {
0330 LogDebug("RecoMuon|CaloExtractorByAssociator") << " >>> Veto HO tower: Calo deltaR= " << deltarHOcal;
0331 LogDebug("RecoMuon|CaloExtractorByAssociator")
0332 << " >>> Calo eta phi ethcal: " << calCPtr->eta() << " " << calCPtr->phi() << " " << ethcal;
0333 vetoTowerHOCal = true;
0334 }
0335
0336
0337 if (!(vetoTowerHOCal && vetoTowerHcal && vetoTowerEcal)) {
0338 for (unsigned int iH = 0; iH < mInfo.crossedTowerIds.size(); ++iH) {
0339 if (mInfo.crossedTowerIds[iH].rawId() == calCPtr->id().rawId()) {
0340 vetoTowerEcal = true;
0341 vetoTowerHcal = true;
0342 vetoTowerHOCal = true;
0343 break;
0344 }
0345 }
0346 }
0347
0348 if (deltar0 > theDR_Max && !(vetoTowerEcal || vetoTowerHcal || vetoTowerHOCal))
0349 continue;
0350
0351 reco::isodeposit::Direction towerDir(calCPtr->eta(), calCPtr->phi());
0352
0353 if (doEcal) {
0354 if (vetoTowerEcal)
0355 depEcal.addCandEnergy(etecal);
0356 else if (deltar0 <= theDR_Max)
0357 depEcal.addDeposit(towerDir, etecal);
0358 }
0359 if (doHcal) {
0360 if (vetoTowerHcal)
0361 depHcal.addCandEnergy(ethcal);
0362 else if (deltar0 <= theDR_Max)
0363 depHcal.addDeposit(towerDir, ethcal);
0364 }
0365 if (doHOcal) {
0366 if (vetoTowerHOCal)
0367 depHOcal.addCandEnergy(ethocal);
0368 else if (deltar0 <= theDR_Max)
0369 depHOcal.addDeposit(towerDir, ethocal);
0370 }
0371 }
0372 }
0373
0374 std::vector<IsoDeposit> resultDeps;
0375 resultDeps.push_back(depEcal);
0376 resultDeps.push_back(depHcal);
0377 resultDeps.push_back(depHOcal);
0378
0379 return resultDeps;
0380 }
0381
0382 double CaloExtractorByAssociator::noiseEcal(const CaloTower& tower) const {
0383 double noise = theNoiseTow_EB;
0384 double eta = tower.eta();
0385 if (fabs(eta) > 1.479)
0386 noise = theNoiseTow_EE;
0387 return noise;
0388 }
0389
0390 double CaloExtractorByAssociator::noiseHcal(const CaloTower& tower) const {
0391 double noise = fabs(tower.eta()) > 1.479 ? theNoise_HE : theNoise_HB;
0392 return noise;
0393 }
0394
0395 double CaloExtractorByAssociator::noiseHOcal(const CaloTower& tower) const {
0396 double noise = theNoise_HO;
0397 return noise;
0398 }
0399
0400 double CaloExtractorByAssociator::noiseRecHit(const DetId& detId) const {
0401 double noise = 100;
0402 DetId::Detector det = detId.det();
0403 if (det == DetId::Ecal) {
0404 EcalSubdetector subDet = (EcalSubdetector)(detId.subdetId());
0405 if (subDet == EcalBarrel) {
0406 noise = theNoise_EB;
0407 } else if (subDet == EcalEndcap) {
0408 noise = theNoise_EE;
0409 }
0410 } else if (det == DetId::Hcal) {
0411 HcalSubdetector subDet = (HcalSubdetector)(detId.subdetId());
0412 if (subDet == HcalBarrel) {
0413 noise = theNoise_HB;
0414 } else if (subDet == HcalEndcap) {
0415 noise = theNoise_HE;
0416 } else if (subDet == HcalOuter) {
0417 noise = theNoise_HO;
0418 }
0419 }
0420 return noise;
0421 }