00001 #include "CaloExtractorByAssociator.h"
00002
00003 #include "DataFormats/Common/interface/Handle.h"
00004 #include "FWCore/Framework/interface/ESHandle.h"
00005 #include "DataFormats/TrackReco/interface/Track.h"
00006 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00009 #include "Utilities/Timing/interface/TimingReport.h"
00010
00011 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
00012 #include "DataFormats/CaloTowers/interface/CaloTowerCollection.h"
00013 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
00014 #include "DataFormats/HcalDetId/interface/HcalSubdetector.h"
00015
00016 #include "MagneticField/Engine/interface/MagneticField.h"
00017 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00018 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00019 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00020
00021 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00022 #include "TrackingTools/TrackAssociator/interface/TrackAssociatorParameters.h"
00023 #include "TrackingTools/TrackAssociator/interface/TrackDetectorAssociator.h"
00024
00025 #include "PhysicsTools/Utilities/interface/deltaR.h"
00026
00027 using namespace edm;
00028 using namespace std;
00029 using namespace reco;
00030 using namespace muonisolation;
00031 using reco::isodeposit::Direction;
00032
00033 CaloExtractorByAssociator::CaloExtractorByAssociator(const ParameterSet& par) :
00034 theUseRecHitsFlag(par.getParameter<bool>("UseRecHitsFlag")),
00035 theDepositLabel(par.getUntrackedParameter<string>("DepositLabel")),
00036 theDepositInstanceLabels(par.getParameter<std::vector<std::string> >("DepositInstanceLabels")),
00037 thePropagatorName(par.getParameter<std::string>("PropagatorName")),
00038 theThreshold_E(par.getParameter<double>("Threshold_E")),
00039 theThreshold_H(par.getParameter<double>("Threshold_H")),
00040 theThreshold_HO(par.getParameter<double>("Threshold_HO")),
00041 theDR_Veto_E(par.getParameter<double>("DR_Veto_E")),
00042 theDR_Veto_H(par.getParameter<double>("DR_Veto_H")),
00043 theDR_Veto_HO(par.getParameter<double>("DR_Veto_HO")),
00044 theDR_Max(par.getParameter<double>("DR_Max")),
00045 theNoise_EB(par.getParameter<double>("Noise_EB")),
00046 theNoise_EE(par.getParameter<double>("Noise_EE")),
00047 theNoise_HB(par.getParameter<double>("Noise_HB")),
00048 theNoise_HE(par.getParameter<double>("Noise_HE")),
00049 theNoise_HO(par.getParameter<double>("Noise_HO")),
00050 theNoiseTow_EB(par.getParameter<double>("NoiseTow_EB")),
00051 theNoiseTow_EE(par.getParameter<double>("NoiseTow_EE")),
00052 theAssociator(0),
00053 thePropagator(0),
00054 thePrintTimeReport(par.getUntrackedParameter<bool>("PrintTimeReport"))
00055 {
00056 theAssociatorParameters = new TrackAssociatorParameters(par.getParameter<edm::ParameterSet>("TrackAssociatorParameters"));
00057 theAssociator = new TrackDetectorAssociator();
00058 }
00059
00060 CaloExtractorByAssociator::~CaloExtractorByAssociator(){
00061 if (thePrintTimeReport) TimingReport::current()->dump(std::cout);
00062 if (theAssociatorParameters) delete theAssociatorParameters;
00063 if (theAssociator) delete theAssociator;
00064 if (thePropagator) delete thePropagator;
00065 }
00066
00067 void CaloExtractorByAssociator::fillVetos(const edm::Event& event, const edm::EventSetup& eventSetup, const TrackCollection& muons)
00068 {
00069
00070
00071
00072
00073 }
00074
00075 IsoDeposit CaloExtractorByAssociator::deposit( const Event & event, const EventSetup& eventSetup, const Track & muon) const
00076 {
00077 IsoDeposit::Direction muonDir(muon.eta(), muon.phi());
00078 IsoDeposit dep(muonDir );
00079
00080
00081
00082
00083
00084 return dep;
00085
00086 }
00087
00088
00090 std::vector<IsoDeposit> CaloExtractorByAssociator::deposits( const Event & event, const EventSetup& eventSetup, const Track & muon) const
00091 {
00092
00093 if (thePropagator == 0){
00095 ESHandle<Propagator> prop;
00096 eventSetup.get<TrackingComponentsRecord>().get(thePropagatorName, prop);
00097 thePropagator = prop->clone();
00098 theAssociator->setPropagator(thePropagator);
00099 }
00100
00103 if (theDepositInstanceLabels.size() != 3){
00104 LogError("MuonIsolation")<<"Configuration is inconsistent: Need 3 deposit instance labels";
00105 }
00106 if (! theDepositInstanceLabels[0].compare(0,1, std::string("e")) == 0
00107 || ! theDepositInstanceLabels[1].compare(0,1, std::string("h")) == 0
00108 || ! theDepositInstanceLabels[2].compare(0,2, std::string("ho")) == 0){
00109 LogWarning("MuonIsolation")<<"Deposit instance labels do not look like (e*, h*, ho*):"
00110 <<"proceed at your own risk. The extractor interprets lab0=from ecal; lab1=from hcal; lab2=from ho";
00111 }
00112
00113 typedef IsoDeposit::Veto Veto;
00116 IsoDeposit::Direction muonDir(muon.eta(), muon.phi());
00117
00118 IsoDeposit depEcal(muonDir);
00119 IsoDeposit depHcal(muonDir);
00120 IsoDeposit depHOcal(muonDir);
00121
00122 edm::ESHandle<MagneticField> bField;
00123 eventSetup.get<IdealMagneticFieldRecord>().get(bField);
00124
00125
00126 reco::TransientTrack tMuon(muon, &*bField);
00127 FreeTrajectoryState iFTS = tMuon.initialFreeState();
00128 TrackDetMatchInfo mInfo = theAssociator->associate(event, eventSetup, iFTS, *theAssociatorParameters);
00129
00131 depEcal.setVeto(Veto(reco::isodeposit::Direction(mInfo.trkGlobPosAtEcal.eta(), mInfo.trkGlobPosAtEcal.phi()),
00132 theDR_Veto_E));
00133 depHcal.setVeto(Veto(reco::isodeposit::Direction(mInfo.trkGlobPosAtHcal.eta(), mInfo.trkGlobPosAtHcal.phi()),
00134 theDR_Veto_H));
00135 depHOcal.setVeto(Veto(reco::isodeposit::Direction(mInfo.trkGlobPosAtHO.eta(), mInfo.trkGlobPosAtHO.phi()),
00136 theDR_Veto_HO));
00137
00138 if (theUseRecHitsFlag){
00141 edm::ESHandle<CaloGeometry> caloGeom;
00142 eventSetup.get<CaloGeometryRecord>().get(caloGeom);
00143
00144
00145 std::vector<const EcalRecHit*>::const_iterator eHitCI = mInfo.ecalRecHits.begin();
00146 for (; eHitCI != mInfo.ecalRecHits.end(); ++eHitCI){
00147 const EcalRecHit* eHitCPtr = *eHitCI;
00148 GlobalPoint eHitPos = caloGeom->getPosition(eHitCPtr->detid());
00149 double deltar0 = reco::deltaR(muon, eHitPos);
00150 double cosTheta = 1./cosh(eHitPos.eta());
00151 double energy = eHitCPtr->energy();
00152 double et = energy*cosTheta;
00153 if (deltar0 > theDR_Max
00154 || ! (et > theThreshold_E && energy > 3*noiseRecHit(eHitCPtr->detid()))) continue;
00155
00156 bool vetoHit = false;
00157 double deltar = reco::deltaR(mInfo.trkGlobPosAtEcal, eHitPos);
00159 if (deltar < theDR_Veto_E ){
00160 LogDebug("RecoMuon|CaloExtractorByAssociator")
00161 << " >>> Veto ECAL hit: Calo deltaR= " << deltar;
00162 LogDebug("RecoMuon|CaloExtractorByAssociator")
00163 << " >>> Calo eta phi ethcal: " << eHitPos.eta() << " " << eHitPos.phi() << " " << et;
00164 vetoHit = true;
00165 }
00167 if (! vetoHit){
00168 for (uint iH = 0; iH< mInfo.crossedEcalIds.size() && ! vetoHit; ++iH){
00169 if (mInfo.crossedEcalIds[iH].rawId() == eHitCPtr->detid().rawId()) vetoHit = true;
00170 }
00171 }
00172
00173 if (vetoHit ){
00174 depEcal.addCandEnergy(et);
00175 } else {
00176 depEcal.addDeposit(reco::isodeposit::Direction(eHitPos.eta(), eHitPos.phi()), et);
00177 }
00178 }
00179
00180
00181 std::vector<const HBHERecHit*>::const_iterator hHitCI = mInfo.hcalRecHits.begin();
00182 for (; hHitCI != mInfo.hcalRecHits.end(); ++hHitCI){
00183 const HBHERecHit* hHitCPtr = *hHitCI;
00184 GlobalPoint hHitPos = caloGeom->getPosition(hHitCPtr->detid());
00185 double deltar0 = reco::deltaR(muon, hHitPos);
00186 double cosTheta = 1./cosh(hHitPos.eta());
00187 double energy = hHitCPtr->energy();
00188 double et = energy*cosTheta;
00189 if (deltar0 > theDR_Max
00190 || ! (et > theThreshold_H && energy > 3*noiseRecHit(hHitCPtr->detid()))) continue;
00191
00192 bool vetoHit = false;
00193 double deltar = reco::deltaR(mInfo.trkGlobPosAtHcal, hHitPos);
00195 if (deltar < theDR_Veto_H ){
00196 LogDebug("RecoMuon|CaloExtractorByAssociator")
00197 << " >>> Veto HBHE hit: Calo deltaR= " << deltar;
00198 LogDebug("RecoMuon|CaloExtractorByAssociator")
00199 << " >>> Calo eta phi ethcal: " << hHitPos.eta() << " " << hHitPos.phi() << " " << et;
00200 vetoHit = true;
00201 }
00203 if (! vetoHit){
00204 for (uint iH = 0; iH< mInfo.crossedHcalIds.size() && ! vetoHit; ++iH){
00205 if (mInfo.crossedHcalIds[iH].rawId() == hHitCPtr->detid().rawId()) vetoHit = true;
00206 }
00207 }
00208
00209 if (vetoHit ){
00210 depHcal.addCandEnergy(et);
00211 } else {
00212 depHcal.addDeposit(reco::isodeposit::Direction(hHitPos.eta(), hHitPos.phi()), et);
00213 }
00214 }
00215
00216
00217 std::vector<const HORecHit*>::const_iterator hoHitCI = mInfo.hoRecHits.begin();
00218 for (; hoHitCI != mInfo.hoRecHits.end(); ++hoHitCI){
00219 const HORecHit* hoHitCPtr = *hoHitCI;
00220 GlobalPoint hoHitPos = caloGeom->getPosition(hoHitCPtr->detid());
00221 double deltar0 = reco::deltaR(muon, hoHitPos);
00222 double cosTheta = 1./cosh(hoHitPos.eta());
00223 double energy = hoHitCPtr->energy();
00224 double et = energy*cosTheta;
00225 if (deltar0 > theDR_Max
00226 || ! (et > theThreshold_HO && energy > 3*noiseRecHit(hoHitCPtr->detid()))) continue;
00227
00228 bool vetoHit = false;
00229 double deltar = reco::deltaR(mInfo.trkGlobPosAtHO, hoHitPos);
00231 if (deltar < theDR_Veto_HO ){
00232 LogDebug("RecoMuon|CaloExtractorByAssociator")
00233 << " >>> Veto HO hit: Calo deltaR= " << deltar;
00234 LogDebug("RecoMuon|CaloExtractorByAssociator")
00235 << " >>> Calo eta phi ethcal: " << hoHitPos.eta() << " " << hoHitPos.phi() << " " << et;
00236 vetoHit = true;
00237 }
00239 if (! vetoHit){
00240 for (uint iH = 0; iH< mInfo.crossedHOIds.size() && ! vetoHit; ++iH){
00241 if (mInfo.crossedHOIds[iH].rawId() == hoHitCPtr->detid().rawId()) vetoHit = true;
00242 }
00243 }
00244
00245 if (vetoHit ){
00246 depHOcal.addCandEnergy(et);
00247 } else {
00248 depHOcal.addDeposit(reco::isodeposit::Direction(hoHitPos.eta(), hoHitPos.phi()), et);
00249 }
00250 }
00251
00252
00253 } else {
00255 std::vector<const CaloTower*>::const_iterator calCI = mInfo.towers.begin();
00256 for (; calCI != mInfo.towers.end(); ++calCI){
00257 const CaloTower* calCPtr = *calCI;
00258 double deltar0 = reco::deltaR(muon,*calCPtr);
00259 if (deltar0>theDR_Max) continue;
00260
00261
00262 double etecal = calCPtr->emEt();
00263 double eecal = calCPtr->emEnergy();
00264 bool doEcal = etecal>theThreshold_E && eecal>3*noiseEcal(*calCPtr);
00265 double ethcal = calCPtr->hadEt();
00266 double ehcal = calCPtr->hadEnergy();
00267 bool doHcal = ethcal>theThreshold_H && ehcal>3*noiseHcal(*calCPtr);
00268 double ethocal = calCPtr->outerEt();
00269 double ehocal = calCPtr->outerEnergy();
00270 bool doHOcal = ethocal>theThreshold_HO && ehocal>3*noiseHOcal(*calCPtr);
00271 if ((!doEcal) && (!doHcal) && (!doHcal)) continue;
00272
00273 bool vetoTowerEcal = false;
00274 double deltarEcal = reco::deltaR(mInfo.trkGlobPosAtEcal, *calCPtr);
00276 if (deltarEcal < theDR_Veto_E ){
00277 LogDebug("RecoMuon|CaloExtractorByAssociator")
00278 << " >>> Veto ecal tower: Calo deltaR= " << deltarEcal;
00279 LogDebug("RecoMuon|CaloExtractorByAssociator")
00280 << " >>> Calo eta phi ethcal: " << calCPtr->eta() << " " << calCPtr->phi() << " " << ethcal;
00281 vetoTowerEcal = true;
00282 }
00283 bool vetoTowerHcal = false;
00284 double deltarHcal = reco::deltaR(mInfo.trkGlobPosAtHcal, *calCPtr);
00286 if (deltarHcal < theDR_Veto_H ){
00287 LogDebug("RecoMuon|CaloExtractorByAssociator")
00288 << " >>> Veto hcal tower: Calo deltaR= " << deltarHcal;
00289 LogDebug("RecoMuon|CaloExtractorByAssociator")
00290 << " >>> Calo eta phi ethcal: " << calCPtr->eta() << " " << calCPtr->phi() << " " << ethcal;
00291 vetoTowerHcal = true;
00292 }
00293 bool vetoTowerHOCal = false;
00294 double deltarHOcal = reco::deltaR(mInfo.trkGlobPosAtHO, *calCPtr);
00296 if (deltarHOcal < theDR_Veto_HO ){
00297 LogDebug("RecoMuon|CaloExtractorByAssociator")
00298 << " >>> Veto HO tower: Calo deltaR= " << deltarHOcal;
00299 LogDebug("RecoMuon|CaloExtractorByAssociator")
00300 << " >>> Calo eta phi ethcal: " << calCPtr->eta() << " " << calCPtr->phi() << " " << ethcal;
00301 vetoTowerHOCal = true;
00302 }
00303
00305 if (! (vetoTowerHOCal && vetoTowerHcal && vetoTowerEcal )){
00306 for (uint iH = 0; iH< mInfo.crossedTowerIds.size(); ++iH){
00307 if (mInfo.crossedTowerIds[iH].rawId() == calCPtr->id().rawId()){
00308 vetoTowerEcal = true;
00309 vetoTowerHcal = true;
00310 vetoTowerHOCal = true;
00311 break;
00312 }
00313 }
00314 }
00315
00316 reco::isodeposit::Direction towerDir(calCPtr->eta(), calCPtr->phi());
00318 if (doEcal){
00319 if (vetoTowerEcal) depEcal.addCandEnergy(etecal);
00320 else depEcal.addDeposit(towerDir, etecal);
00321 }
00322 if (doHcal){
00323 if (vetoTowerHcal) depHcal.addCandEnergy(ethcal);
00324 else depHcal.addDeposit(towerDir, ethcal);
00325 }
00326 if (doHOcal){
00327 if (vetoTowerHOCal) depHOcal.addCandEnergy(ethocal);
00328 else depHOcal.addDeposit(towerDir, ethocal);
00329 }
00330 }
00331 }
00332
00333 std::vector<IsoDeposit> resultDeps;
00334 resultDeps.push_back(depEcal);
00335 resultDeps.push_back(depHcal);
00336 resultDeps.push_back(depHOcal);
00337
00338 return resultDeps;
00339
00340 }
00341
00342 double CaloExtractorByAssociator::noiseEcal(const CaloTower& tower) const {
00343 double noise = theNoiseTow_EB;
00344 double eta = tower.eta();
00345 if (fabs(eta)>1.479) noise = theNoiseTow_EE;
00346 return noise;
00347 }
00348
00349 double CaloExtractorByAssociator::noiseHcal(const CaloTower& tower) const {
00350 double noise = fabs(tower.eta())> 1.479 ? theNoise_HE : theNoise_HB;
00351 return noise;
00352 }
00353
00354 double CaloExtractorByAssociator::noiseHOcal(const CaloTower& tower) const {
00355 double noise = theNoise_HO;
00356 return noise;
00357 }
00358
00359
00360 double CaloExtractorByAssociator::noiseRecHit(const DetId& detId) const {
00361 double noise = 100;
00362 DetId::Detector det = detId.det();
00363 if (det == DetId::Ecal){
00364 EcalSubdetector subDet = (EcalSubdetector)(detId.subdetId());
00365 if (subDet == EcalBarrel){
00366 noise = theNoise_EB;
00367 } else if (subDet == EcalEndcap){
00368 noise = theNoise_EE;
00369 }
00370 } else if (det == DetId::Hcal){
00371 HcalSubdetector subDet = (HcalSubdetector)(detId.subdetId());
00372 if (subDet == HcalBarrel){
00373 noise = theNoise_HB;
00374 } else if (subDet == HcalEndcap){
00375 noise = theNoise_HE;
00376 } else if (subDet == HcalOuter){
00377 noise = theNoise_HO;
00378 }
00379 }
00380 return noise;
00381 }
00382