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