CMS 3D CMS Logo

CaloExtractor.cc

Go to the documentation of this file.
00001 #include "CaloExtractor.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 
00010 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
00011 #include "DataFormats/CaloTowers/interface/CaloTowerCollection.h"
00012 
00013 #include "MagneticField/Engine/interface/MagneticField.h"
00014 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00015 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00016 #include "PhysicsTools/Utilities/interface/deltaR.h"
00017 #include "PhysicsTools/Utilities/interface/normalizedPhi.h"
00018 
00019 using namespace edm;
00020 using namespace std;
00021 using namespace reco;
00022 using namespace muonisolation;
00023 using reco::isodeposit::Direction;
00024 
00025 CaloExtractor::CaloExtractor(const ParameterSet& par) :
00026   theCaloTowerCollectionLabel(par.getParameter<edm::InputTag>("CaloTowerCollectionLabel")),
00027   theDepositLabel(par.getUntrackedParameter<string>("DepositLabel")),
00028   theWeight_E(par.getParameter<double>("Weight_E")),
00029   theWeight_H(par.getParameter<double>("Weight_H")),
00030   theThreshold_E(par.getParameter<double>("Threshold_E")),
00031   theThreshold_H(par.getParameter<double>("Threshold_H")),
00032   theDR_Veto_E(par.getParameter<double>("DR_Veto_E")),
00033   theDR_Veto_H(par.getParameter<double>("DR_Veto_H")),
00034   theDR_Max(par.getParameter<double>("DR_Max")),
00035   vertexConstraintFlag_XY(par.getParameter<bool>("Vertex_Constraint_XY")),
00036   vertexConstraintFlag_Z(par.getParameter<bool>("Vertex_Constraint_Z"))
00037 {
00038 }
00039 
00040 void CaloExtractor::fillVetos(const edm::Event& event, const edm::EventSetup& eventSetup, const TrackCollection& muons)
00041 {
00042   theVetoCollection.clear();
00043 
00044   Handle<CaloTowerCollection> towers;
00045   event.getByLabel(theCaloTowerCollectionLabel,towers);
00046 
00047   edm::ESHandle<CaloGeometry> caloGeom;
00048   eventSetup.get<CaloGeometryRecord>().get(caloGeom);
00049 
00050   edm::ESHandle<MagneticField> bField;
00051   eventSetup.get<IdealMagneticFieldRecord>().get(bField);
00052   double bz = bField->inInverseGeV(GlobalPoint(0.,0.,0.)).z();
00053 
00054   TrackCollection::const_iterator mu;
00055   TrackCollection::const_iterator muEnd(muons.end());
00056   
00057   CaloTowerCollection::const_iterator cal;
00058   CaloTowerCollection::const_iterator calEnd(towers->end());
00059   
00060   for ( mu = muons.begin(); mu != muEnd; ++mu ) {
00061     for ( cal = towers->begin(); cal != calEnd; ++cal ) {
00063       double dEta = fabs(mu->eta()-cal->eta());
00064       if (fabs(dEta) > theDR_Max) continue;
00065 
00066             double deltar0 = reco::deltaR(*mu,*cal);
00067             if (deltar0>theDR_Max) continue;
00068 
00069             double etecal = cal->emEt();
00070             double eecal = cal->emEnergy();
00071             bool doEcal = theWeight_E>0 && etecal>theThreshold_E && eecal>3*noiseEcal(*cal);
00072             double ethcal = cal->hadEt();
00073             double ehcal = cal->hadEnergy();
00074             bool doHcal = theWeight_H>0 && ethcal>theThreshold_H && ehcal>3*noiseHcal(*cal);
00075             if ((!doEcal) && (!doHcal)) continue;
00076 
00077             DetId calId = cal->id();
00078             GlobalPoint endpos = caloGeom->getPosition(calId);
00079             GlobalPoint muatcal = MuonAtCaloPosition(*mu,bz,endpos, vertexConstraintFlag_XY, vertexConstraintFlag_Z);
00080             double deltar = reco::deltaR(muatcal,endpos);
00081 
00082             if (doEcal) {
00083                   if (deltar<theDR_Veto_E) theVetoCollection.push_back(calId);
00084             } else {
00085                   if (deltar<theDR_Veto_H) theVetoCollection.push_back(calId);
00086             }
00087       }
00088   }
00089      
00090 }
00091 
00092 IsoDeposit CaloExtractor::deposit( const Event & event, const EventSetup& eventSetup, const Track & muon) const
00093 {
00094   IsoDeposit dep(muon.eta(), muon.phi() );
00095   LogDebug("Muon|RecoMuon|L2MuonIsolationProducer")
00096           << " >>> Muon: pt " << muon.pt()
00097           << " eta " << muon.eta()
00098           << " phi " << muon.phi();
00099 
00100   Handle<CaloTowerCollection> towers;
00101   event.getByLabel(theCaloTowerCollectionLabel,towers);
00102 
00103   edm::ESHandle<CaloGeometry> caloGeom;
00104   eventSetup.get<CaloGeometryRecord>().get(caloGeom);
00105 
00106   edm::ESHandle<MagneticField> bField;
00107   eventSetup.get<IdealMagneticFieldRecord>().get(bField);
00108   double bz = bField->inInverseGeV(GlobalPoint(0.,0.,0.)).z();
00109 
00110   CaloTowerCollection::const_iterator cal;
00111   CaloTowerCollection::const_iterator calEnd(towers->end());
00112   for ( cal = towers->begin(); cal != calEnd; ++cal ) {
00114       double dEta = fabs(muon.eta()-cal->eta());
00115       if (fabs(dEta) > theDR_Max) continue;
00116     
00117       double deltar0 = reco::deltaR(muon,*cal);
00118       if (deltar0>theDR_Max) continue;
00119 
00120       double etecal = cal->emEt();
00121       double eecal = cal->emEnergy();
00122       bool doEcal = theWeight_E>0 && etecal>theThreshold_E && eecal>3*noiseEcal(*cal);
00123       double ethcal = cal->hadEt();
00124       double ehcal = cal->hadEnergy();
00125       bool doHcal = theWeight_H>0 && ethcal>theThreshold_H && ehcal>3*noiseHcal(*cal);
00126       if ((!doEcal) && (!doHcal)) continue;
00127 
00128       DetId calId = cal->id();
00129       GlobalPoint endpos = caloGeom->getPosition(calId);
00130       GlobalPoint muatcal = MuonAtCaloPosition(muon,bz,endpos,vertexConstraintFlag_XY, vertexConstraintFlag_Z);
00131       double deltar = reco::deltaR(muatcal,endpos);
00132 
00133       if (deltar<theDR_Veto_H) {
00134               dep.setVeto(IsoDeposit::Veto(reco::isodeposit::Direction(muatcal.eta(), muatcal.phi()), theDR_Veto_H));
00135       }
00136 
00137       if (doEcal) {
00138             if (deltar<theDR_Veto_E) { 
00139                   double calodep = theWeight_E*etecal;
00140                   if (doHcal) calodep += theWeight_H*ethcal;
00141                   dep.addCandEnergy(calodep);
00142                     LogDebug("Muon|RecoMuon|L2MuonIsolationProducer")
00143                     << " >>> Calo deposit inside veto (with ECAL): deltar " << deltar
00144                     << " calodep " << calodep
00145                     << " ecaldep " << etecal
00146                     << " hcaldep " << ethcal
00147                     << " eta " << cal->eta()
00148                     << " phi " << cal->phi();
00149                   continue;
00150             }
00151       } else {
00152             if (deltar<theDR_Veto_H) { 
00153                   dep.addCandEnergy(theWeight_H*ethcal);
00154                     LogDebug("Muon|RecoMuon|L2MuonIsolationProducer")
00155                     << " >>> Calo deposit inside veto (no ECAL): deltar " << deltar
00156                     << " calodep " << theWeight_H*ethcal
00157                     << " eta " << cal->eta()
00158                     << " phi " << cal->phi();
00159                   continue;
00160             }
00161       }
00162 
00163       if (std::find(theVetoCollection.begin(), theVetoCollection.end()
00164                   , calId)!=theVetoCollection.end()) {
00165             LogDebug("Muon|RecoMuon|L2MuonIsolationProducer")
00166             << " >>> Deposits belongs to other track: deltar, etecal, ethcal= " 
00167             << deltar << ", " << etecal << ", " << ethcal;
00168             continue;
00169       }
00170 
00171       if (doEcal) {
00172             if (deltar>theDR_Veto_E) { 
00173                   double calodep = theWeight_E*etecal;
00174                   if (doHcal) calodep += theWeight_H*ethcal;
00175                   dep.addDeposit(reco::isodeposit::Direction(endpos.eta(), endpos.phi()),calodep);
00176                     LogDebug("Muon|RecoMuon|L2MuonIsolationProducer")
00177                     << " >>> Calo deposit (with ECAL): deltar " << deltar
00178                     << " calodep " << calodep
00179                     << " ecaldep " << etecal
00180                     << " hcaldep " << ethcal
00181                     << " eta " << cal->eta()
00182                     << " phi " << cal->phi();
00183             }
00184       } else {
00185             if (deltar>theDR_Veto_H) { 
00186                     dep.addDeposit(reco::isodeposit::Direction(endpos.eta(), endpos.phi()),theWeight_H*ethcal);
00187                     LogDebug("Muon|RecoMuon|L2MuonIsolationProducer")
00188                     << " >>> Calo deposit (no ECAL): deltar " << deltar
00189                     << " calodep " << theWeight_H*ethcal
00190                     << " eta " << cal->eta()
00191                     << " phi " << cal->phi();
00192             }
00193       }
00194   }
00195 
00196   return dep;
00197 
00198 }
00199 
00200 GlobalPoint CaloExtractor::MuonAtCaloPosition(const Track& muon, const double bz, const GlobalPoint& endpos, bool fixVxy, bool fixVz) {
00201       double qoverp= muon.qoverp();
00202       double cur = bz*muon.charge()/muon.pt();
00203       double phi0 = muon.phi();
00204       double dca = muon.dxy();
00205       double theta = muon.theta();
00206       double dz = muon.dz();
00207 
00208       //LogDebug("Muon|RecoMuon|L2MuonIsolationProducer")
00209           //<< " Pt(GeV): " <<  muon.pt()
00210           //<< ", phi0 " <<  muon.phi0()
00211              //<< ", eta " <<  muon.eta();
00212       //LogDebug("Muon|RecoMuon|L2MuonIsolationProducer")
00213           //<< " d0 " <<  muon.d0()
00214           //<< ", dz " <<  muon.dz();
00215       //LogDebug("Muon|RecoMuon|L2MuonIsolationProducer")
00216           //<< " rhocal " <<  endpos.perp()
00217           //<< ", zcal " <<  endpos.z();
00218 
00219       if (fixVxy && fixVz) {
00220             // Note that here we assume no correlation between XY and Z projections
00221             // This should be a reasonable approximation for our purposes
00222             double errd02 = muon.covariance(muon.i_dxy,muon.i_dxy);
00223             if (pow(muon.dxy(),2)<4*errd02) {
00224                   phi0 -= muon.dxy()*muon.covariance(muon.i_dxy,muon.i_phi)
00225                                      /errd02;
00226                   cur -= muon.dxy()*muon.covariance(muon.i_dxy,muon.i_qoverp)
00227                                      /errd02 * (cur/qoverp);
00228                   dca = 0;
00229             } 
00230             double errdsz2 = muon.covariance(muon.i_dsz,muon.i_dsz);
00231             if (pow(muon.dsz(),2)<4*errdsz2) {
00232                   theta += muon.dsz()*muon.covariance(muon.i_dsz,muon.i_lambda)
00233                                      /errdsz2;
00234                   dz = 0;
00235             } 
00236       } else if (fixVxy) {
00237             double errd02 = muon.covariance(muon.i_dxy,muon.i_dxy);
00238             if (pow(muon.dxy(),2)<4*errd02) {
00239                   phi0  -= muon.dxy()*muon.covariance(muon.i_dxy,muon.i_phi)
00240                                      /errd02;
00241                   cur -= muon.dxy()*muon.covariance(muon.i_dxy,muon.i_qoverp)
00242                                      /errd02 * (cur/qoverp);
00243                   theta += muon.dxy()*muon.covariance(muon.i_dxy,muon.i_lambda)
00244                                      /errd02;
00245                   dz    -= muon.dxy()*muon.covariance(muon.i_dxy,muon.i_dsz)
00246                                      /errd02 * muon.p()/muon.pt();
00247                   dca = 0;
00248             } 
00249       } else if (fixVz) {
00250             double errdsz2 = muon.covariance(muon.i_dsz,muon.i_dsz);
00251             if (pow(muon.dsz(),2)<4*errdsz2) {
00252                   theta += muon.dsz()*muon.covariance(muon.i_dsz,muon.i_lambda)
00253                                      /errdsz2;
00254                   phi0  -= muon.dsz()*muon.covariance(muon.i_dsz,muon.i_phi)
00255                                      /errdsz2;
00256                   cur -= muon.dsz()*muon.covariance(muon.i_dsz,muon.i_qoverp)
00257                                      /errdsz2 * (cur/qoverp);
00258                   dca   -= muon.dsz()*muon.covariance(muon.i_dsz,muon.i_dxy)
00259                                      /errdsz2;
00260                   dz = 0;
00261             } 
00262       }
00263 
00264       double sphi0 = sin(phi0);
00265       double cphi0 = cos(phi0);
00266 
00267       double xsin =  endpos.x()*sphi0 - endpos.y()*cphi0;
00268       double xcos =  endpos.x()*cphi0 + endpos.y()*sphi0;
00269       double fcdca = fabs(1-cur*dca);
00270       double phif = atan2( fcdca*sphi0-cur*endpos.x()
00271                          , fcdca*cphi0+cur*endpos.y());
00272       double tphif2 = tan(0.5*(phif-phi0));
00273       double dcaf = dca + xsin + xcos*tphif2;
00274 
00275       double x = endpos.x() - dcaf*sin(phif);
00276       double y = endpos.y() + dcaf*cos(phif);
00277 
00278       double deltas =  (x-muon.vx())*cphi0 + (y-muon.vy())*sphi0;
00279       double deltaphi = normalizedPhi(phif-phi0);
00280       if (deltaphi!=0) deltas = deltas*deltaphi/sin(deltaphi);
00281 
00282       double z =dz;
00283       double tantheta = tan(theta);
00284       if (tantheta!=0) {
00285             z += deltas/tan(theta);
00286       } else {
00287             z = endpos.z();
00288       }
00289 
00290       return GlobalPoint(x,y,z);
00291 }
00292 
00293 double CaloExtractor::noiseEcal(const CaloTower& tower) const {
00294       double noise = 0.04;
00295       double eta = tower.eta();
00296       if (fabs(eta)>1.479) noise = 0.15;
00297       return noise;
00298 }
00299 
00300 double CaloExtractor::noiseHcal(const CaloTower& tower) const {
00301       double noise = 0.2;
00302       return noise;
00303 }

Generated on Tue Jun 9 17:44:21 2009 for CMSSW by  doxygen 1.5.4