00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "DQMOffline/L1Trigger/interface/L1TEfficiencyMuons_Offline.h"
00011
00012 #include "DQMServices/Core/interface/DQMStore.h"
00013
00014 #include "DataFormats/Histograms/interface/MEtoEDMFormat.h"
00015
00016 #include "DataFormats/MuonReco/interface/MuonSelectors.h"
00017
00018 #include "DataFormats/GeometrySurface/interface/Cylinder.h"
00019 #include "DataFormats/GeometrySurface/interface/Plane.h"
00020
00021 #include "TMath.h"
00022
00023 using namespace reco;
00024 using namespace trigger;
00025 using namespace edm;
00026 using namespace std;
00027
00028
00029
00030
00031 MuonGmtPair::MuonGmtPair(const MuonGmtPair& muonGmtPair) {
00032
00033 m_muon = muonGmtPair.m_muon;
00034 m_gmt = muonGmtPair.m_gmt;
00035 m_eta = muonGmtPair.m_eta;
00036 m_phi_bar = muonGmtPair.m_phi_bar;
00037 m_phi_end = muonGmtPair.m_phi_end;
00038
00039 }
00040
00041
00042 double MuonGmtPair::dR() {
00043
00044 float dEta = m_gmt ? (m_gmt->etaValue() - eta()) : 999.;
00045 float dPhi = m_gmt ? (m_gmt->phiValue() - phi()) : 999.;
00046
00047 float dr = sqrt(dEta*dEta + dPhi*dPhi);
00048
00049 return dr;
00050
00051 }
00052
00053
00054 void MuonGmtPair::propagate(ESHandle<MagneticField> bField,
00055 ESHandle<Propagator> propagatorAlong,
00056 ESHandle<Propagator> propagatorOpposite) {
00057
00058 m_BField = bField;
00059 m_propagatorAlong = propagatorAlong;
00060 m_propagatorOpposite = propagatorOpposite;
00061
00062 TrackRef standaloneMuon = m_muon->outerTrack();
00063
00064 TrajectoryStateOnSurface trajectory;
00065 trajectory = cylExtrapTrkSam(standaloneMuon, 500);
00066 if (trajectory.isValid()) {
00067 m_eta = trajectory.globalPosition().eta();
00068 m_phi_bar = trajectory.globalPosition().phi();
00069 }
00070
00071 trajectory = surfExtrapTrkSam(standaloneMuon, 790);
00072 if (trajectory.isValid()) {
00073 m_eta = trajectory.globalPosition().eta();
00074 m_phi_end = trajectory.globalPosition().phi();
00075 }
00076
00077 trajectory = surfExtrapTrkSam(standaloneMuon, -790);
00078 if (trajectory.isValid()) {
00079 m_eta = trajectory.globalPosition().eta();
00080 m_phi_end = trajectory.globalPosition().phi();
00081 }
00082
00083 }
00084
00085
00086 TrajectoryStateOnSurface MuonGmtPair::cylExtrapTrkSam(TrackRef track, double rho)
00087 {
00088
00089 Cylinder::PositionType pos(0, 0, 0);
00090 Cylinder::RotationType rot;
00091 Cylinder::CylinderPointer myCylinder = Cylinder::build(pos, rot, rho);
00092
00093 FreeTrajectoryState recoStart = freeTrajStateMuon(track);
00094 TrajectoryStateOnSurface recoProp;
00095 recoProp = m_propagatorAlong->propagate(recoStart, *myCylinder);
00096 if (!recoProp.isValid()) {
00097 recoProp = m_propagatorOpposite->propagate(recoStart, *myCylinder);
00098 }
00099 return recoProp;
00100
00101 }
00102
00103
00104 TrajectoryStateOnSurface MuonGmtPair::surfExtrapTrkSam(TrackRef track, double z)
00105 {
00106
00107 Plane::PositionType pos(0, 0, z);
00108 Plane::RotationType rot;
00109 Plane::PlanePointer myPlane = Plane::build(pos, rot);
00110
00111 FreeTrajectoryState recoStart = freeTrajStateMuon(track);
00112 TrajectoryStateOnSurface recoProp;
00113 recoProp = m_propagatorAlong->propagate(recoStart, *myPlane);
00114 if (!recoProp.isValid()) {
00115 recoProp = m_propagatorOpposite->propagate(recoStart, *myPlane);
00116 }
00117 return recoProp;
00118 }
00119
00120
00121 FreeTrajectoryState MuonGmtPair::freeTrajStateMuon(TrackRef track)
00122 {
00123
00124 GlobalPoint innerPoint(track->innerPosition().x(), track->innerPosition().y(), track->innerPosition().z());
00125 GlobalVector innerVec (track->innerMomentum().x(), track->innerMomentum().y(), track->innerMomentum().z());
00126
00127 FreeTrajectoryState recoStart(innerPoint, innerVec, track->charge(), &*m_BField);
00128
00129 return recoStart;
00130
00131 }
00132
00133
00134
00135 L1TEfficiencyMuons_Offline::L1TEfficiencyMuons_Offline(const ParameterSet & ps){
00136
00137 if (m_verbose) {
00138 cout << "[L1TEfficiencyMuons_Offline:] ____________ Storage initialization ____________ " << endl;
00139 }
00140
00141
00142 dbe = Service<DQMStore>().operator->();
00143 dbe->setVerbose(0);
00144 if (m_verbose) {cout << "[L1TEfficiencyMuons_Offline:] Pointer for DQM Store: " << dbe << endl;}
00145
00146
00147 m_GmtPtCuts = ps.getUntrackedParameter< vector<int> >("gmtPtCuts");
00148
00149 m_MuonInputTag = ps.getUntrackedParameter<InputTag>("muonInputTag");
00150 m_GmtInputTag = ps.getUntrackedParameter<InputTag>("gmtInputTag");
00151
00152 m_VtxInputTag = ps.getUntrackedParameter<InputTag>("vtxInputTag");
00153 m_BsInputTag = ps.getUntrackedParameter<InputTag>("bsInputTag");
00154
00155 m_trigInputTag = ps.getUntrackedParameter<InputTag>("trigInputTag");
00156 m_trigProcess = ps.getUntrackedParameter<string>("trigProcess");
00157 m_trigNames = ps.getUntrackedParameter<vector<string> >("triggerNames");
00158
00159
00160 m_MaxMuonEta = 2.4;
00161 m_MaxGmtMuonDR = 0.7;
00162 m_MaxHltMuonDR = 0.1;
00163
00164
00165
00166 }
00167
00168
00169
00170 L1TEfficiencyMuons_Offline::~L1TEfficiencyMuons_Offline(){ }
00171
00172
00173
00174 void L1TEfficiencyMuons_Offline::beginJob(void){
00175
00176 if (m_verbose) {cout << "[L1TEfficiencyMuons_Offline:] Called beginJob." << endl;}
00177
00178 bookControlHistos();
00179
00180 vector<int>::const_iterator gmtPtCutsIt = m_GmtPtCuts.begin();
00181 vector<int>::const_iterator gmtPtCutsEnd = m_GmtPtCuts.end();
00182
00183 for (; gmtPtCutsIt!=gmtPtCutsEnd; ++ gmtPtCutsIt) {
00184 bookEfficiencyHistos((*gmtPtCutsIt));
00185 }
00186
00187 }
00188
00189
00190
00191 void L1TEfficiencyMuons_Offline::endJob(void){
00192
00193 if (m_verbose) {cout << "[L1TEfficiencyMuons_Offline:] Called endJob." << endl;}
00194
00195 }
00196
00197
00198
00199 void L1TEfficiencyMuons_Offline::beginRun(const edm::Run& run, const edm::EventSetup& iSetup){
00200
00201 if (m_verbose) {cout << "[L1TEfficiencyMuons_Offline:] Called beginRun." << endl;}
00202
00203 bool changed = true;
00204
00205 m_hltConfig.init(run,iSetup,m_trigProcess,changed);
00206
00207 vector<string>::const_iterator trigNamesIt = m_trigNames.begin();
00208 vector<string>::const_iterator trigNamesEnd = m_trigNames.end();
00209
00210 for (; trigNamesIt!=trigNamesEnd; ++trigNamesIt) {
00211
00212 TString tNameTmp = TString(*trigNamesIt);
00213 TRegexp tNamePattern = TRegexp(tNameTmp,true);
00214 int tIndex = -1;
00215
00216 for (unsigned ipath = 0; ipath < m_hltConfig.size(); ++ipath) {
00217
00218 TString tmpName = TString(m_hltConfig.triggerName(ipath));
00219 if (tmpName.Contains(tNamePattern)) {
00220 tIndex = int(ipath);
00221 m_trigIndices.push_back(tIndex);
00222 }
00223
00224 }
00225
00226 if (tIndex < 0 && m_verbose) {
00227 cout << "[L1TEfficiencyMuons_Offline:] Warning: Could not find trigger "
00228 << (*trigNamesIt) << endl;
00229 }
00230
00231 }
00232
00233 }
00234
00235
00236
00237 void L1TEfficiencyMuons_Offline::endRun(const edm::Run& run, const edm::EventSetup& iSetup){
00238
00239 if (m_verbose) {cout << "[L1TEfficiencyMuons_Offline:] Called endRun." << endl;}
00240
00241 }
00242
00243
00244
00245 void L1TEfficiencyMuons_Offline::beginLuminosityBlock(LuminosityBlock const& lumiBlock, EventSetup const& c) {
00246
00247 if(m_verbose){
00248 cout << "[L1TEfficiencyMuons_Offline:] Called beginLuminosityBlock at LS="
00249 << lumiBlock.id().luminosityBlock() << endl;
00250 }
00251
00252 }
00253
00254
00255
00256 void L1TEfficiencyMuons_Offline::endLuminosityBlock(LuminosityBlock const& lumiBlock, EventSetup const& c) {
00257
00258 if(m_verbose){
00259 cout << "[L1TEfficiencyMuons_Offline:] Called endLuminosityBlock at LS="
00260 << lumiBlock.id().luminosityBlock() << endl;
00261 }
00262
00263 }
00264
00265
00266
00267 void L1TEfficiencyMuons_Offline::analyze(const Event & iEvent, const EventSetup & eventSetup){
00268
00269 Handle<reco::MuonCollection> muons;
00270 iEvent.getByLabel(m_MuonInputTag, muons);
00271
00272 Handle<BeamSpot> beamSpot;
00273 iEvent.getByLabel(m_BsInputTag, beamSpot);
00274
00275 Handle<VertexCollection> vertex;
00276 iEvent.getByLabel(m_VtxInputTag, vertex);
00277
00278 Handle<L1MuGMTReadoutCollection> gmtCands;
00279 iEvent.getByLabel(m_GmtInputTag,gmtCands);
00280
00281 Handle<edm::TriggerResults> trigResults;
00282 iEvent.getByLabel(InputTag("TriggerResults","",m_trigProcess),trigResults);
00283
00284 edm::Handle<trigger::TriggerEvent> trigEvent;
00285 iEvent.getByLabel(m_trigInputTag,trigEvent);
00286
00287 eventSetup.get<IdealMagneticFieldRecord>().get(m_BField);
00288
00289 eventSetup.get<TrackingComponentsRecord>().get("SmartPropagatorAny",m_propagatorAlong);
00290 eventSetup.get<TrackingComponentsRecord>().get("SmartPropagatorAnyOpposite",m_propagatorOpposite);
00291
00292 const Vertex primaryVertex = getPrimaryVertex(vertex,beamSpot);
00293
00294 getTightMuons(muons,primaryVertex);
00295 getProbeMuons(trigResults,trigEvent);
00296 getMuonGmtPairs(gmtCands);
00297
00298 cout << "[L1TEfficiencyMuons_Offline:] Computing efficiencies" << endl;
00299
00300 vector<MuonGmtPair>::const_iterator muonGmtPairsIt = m_MuonGmtPairs.begin();
00301 vector<MuonGmtPair>::const_iterator muonGmtPairsEnd = m_MuonGmtPairs.end();
00302
00303 for(; muonGmtPairsIt!=muonGmtPairsEnd; ++muonGmtPairsIt) {
00304
00305 float eta = muonGmtPairsIt->eta();
00306 float phi = muonGmtPairsIt->phi();
00307 float pt = muonGmtPairsIt->pt();
00308
00309
00310 float gmtPt = muonGmtPairsIt->gmtPt();
00311
00312 vector<int>::const_iterator gmtPtCutsIt = m_GmtPtCuts.begin();
00313 vector<int>::const_iterator gmtPtCutsEnd = m_GmtPtCuts.end();
00314
00315 for (; gmtPtCutsIt!=gmtPtCutsEnd; ++ gmtPtCutsIt) {
00316
00317 int gmtPtCut = (*gmtPtCutsIt);
00318 bool gmtAboveCut = (gmtPt > gmtPtCut);
00319
00320 stringstream ptCutToTag; ptCutToTag << gmtPtCut;
00321 string ptTag = ptCutToTag.str();
00322
00323 if (fabs(eta) < m_MaxMuonEta) {
00324
00325 m_EfficiencyHistos[gmtPtCut]["EffvsPt" + ptTag + "Den"]->Fill(pt);
00326 if (gmtAboveCut) m_EfficiencyHistos[gmtPtCut]["EffvsPt" + ptTag + "Num"]->Fill(pt);
00327
00328 if (pt > gmtPtCut + 8.) {
00329
00330 m_EfficiencyHistos[gmtPtCut]["EffvsPhi" + ptTag + "Den"]->Fill(phi);
00331 m_EfficiencyHistos[gmtPtCut]["EffvsEta" + ptTag + "Den"]->Fill(eta);
00332
00333 if (gmtAboveCut) {
00334 m_EfficiencyHistos[gmtPtCut]["EffvsPhi" + ptTag + "Num"]->Fill(phi);
00335 m_EfficiencyHistos[gmtPtCut]["EffvsEta" + ptTag + "Num"]->Fill(eta);
00336 }
00337 }
00338 }
00339 }
00340 }
00341
00342 cout << "[L1TEfficiencyMuons_Offline:] Computation finished" << endl;
00343
00344
00345 }
00346
00347
00348
00349 void L1TEfficiencyMuons_Offline::bookControlHistos() {
00350
00351 if(m_verbose){cout << "[L1TEfficiencyMuons_Offline:] Booking Control Plot Histos" << endl;}
00352
00353 dbe->setCurrentFolder("L1T/Efficiency/Muons/Control");
00354
00355 string name = "MuonGmtDeltaR";
00356 m_ControlHistos[name] = dbe->book1D(name.c_str(),name.c_str(),25.,0.,2.5);
00357
00358 name = "NTightVsAll";
00359 m_ControlHistos[name] = dbe->book2D(name.c_str(),name.c_str(),5,-0.5,4.5,5,-0.5,4.5);
00360
00361 name = "NProbesVsTight";
00362 m_ControlHistos[name] = dbe->book2D(name.c_str(),name.c_str(),5,-0.5,4.5,5,-0.5,4.5);
00363
00364 }
00365
00366
00367
00368 void L1TEfficiencyMuons_Offline::bookEfficiencyHistos(int ptCut) {
00369
00370 if(m_verbose){
00371 cout << "[L1TEfficiencyMuons_Offline:] Booking Efficiency Plot Histos for pt cut = "
00372 << ptCut << endl;
00373 }
00374
00375 stringstream ptCutToTag; ptCutToTag << ptCut;
00376 string ptTag = ptCutToTag.str();
00377
00378 dbe->setCurrentFolder("L1T/Efficiency/Muons/");
00379
00380 string effTag[2] = {"Den", "Num"};
00381
00382 for(int iEffTag=0; iEffTag<2; ++ iEffTag) {
00383 string name = "EffvsPt" + ptTag + effTag[iEffTag];
00384 m_EfficiencyHistos[ptCut][name] = dbe->book1D(name.c_str(),name.c_str(),16,0.,40.);
00385
00386 name = "EffvsPhi" + ptTag + effTag[iEffTag];
00387 m_EfficiencyHistos[ptCut][name] = dbe->book1D(name.c_str(),name.c_str(),12,0.,2*TMath::Pi());
00388
00389 name = "EffvsEta" + ptTag + effTag[iEffTag];
00390 m_EfficiencyHistos[ptCut][name] = dbe->book1D(name.c_str(),name.c_str(),12,-2.4,2.4);
00391 }
00392
00393 }
00394
00395
00396
00397 const reco::Vertex L1TEfficiencyMuons_Offline::getPrimaryVertex( Handle<VertexCollection> & vertex,
00398 Handle<BeamSpot> & beamSpot ) {
00399
00400 Vertex::Point posVtx;
00401 Vertex::Error errVtx;
00402
00403 bool hasPrimaryVertex = false;
00404
00405 if (vertex.isValid())
00406 {
00407
00408 vector<Vertex>::const_iterator vertexIt = vertex->begin();
00409 vector<Vertex>::const_iterator vertexEnd = vertex->end();
00410
00411 for (;vertexIt!=vertexEnd;++vertexIt)
00412 {
00413 if (vertexIt->isValid() &&
00414 !vertexIt->isFake())
00415 {
00416 posVtx = vertexIt->position();
00417 errVtx = vertexIt->error();
00418 hasPrimaryVertex = true;
00419 break;
00420 }
00421 }
00422 }
00423
00424 if ( !hasPrimaryVertex ) {
00425
00426 if(m_verbose){
00427 cout << "[L1TEfficiencyMuons_Offline:] PrimaryVertex not found, use BeamSpot position instead" << endl;
00428 }
00429
00430 posVtx = beamSpot->position();
00431 errVtx(0,0) = beamSpot->BeamWidthX();
00432 errVtx(1,1) = beamSpot->BeamWidthY();
00433 errVtx(2,2) = beamSpot->sigmaZ();
00434
00435 }
00436
00437 const Vertex primaryVertex(posVtx,errVtx);
00438
00439 return primaryVertex;
00440
00441 }
00442
00443
00444
00445 void L1TEfficiencyMuons_Offline::getTightMuons(edm::Handle<reco::MuonCollection> & muons,
00446 const Vertex & vertex) {
00447
00448 cout << "[L1TEfficiencyMuons_Offline:] Getting tight muons" << endl;
00449
00450 m_TightMuons.clear();
00451
00452 MuonCollection::const_iterator muonIt = muons->begin();
00453 MuonCollection::const_iterator muonEnd = muons->end();
00454
00455 for(; muonIt!=muonEnd; ++muonIt) {
00456 if (muon::isTightMuon((*muonIt), vertex)) {
00457 m_TightMuons.push_back(&(*muonIt));
00458 }
00459 }
00460
00461 m_ControlHistos["NTightVsAll"]->Fill(muons->size(),m_TightMuons.size());
00462
00463 }
00464
00465
00466
00467 void L1TEfficiencyMuons_Offline::getProbeMuons(Handle<edm::TriggerResults> & trigResults,
00468 edm::Handle<trigger::TriggerEvent> & trigEvent) {
00469
00470 cout << "[L1TEfficiencyMuons_Offline:] getting probe muons" << endl;
00471
00472 m_ProbeMuons.clear();
00473
00474 vector<const Muon*>::const_iterator probeCandIt = m_TightMuons.begin();
00475 vector<const Muon*>::const_iterator tightMuonsEnd = m_TightMuons.end();
00476
00477 for (; probeCandIt!=tightMuonsEnd; ++probeCandIt) {
00478
00479 bool tagHasTrig = false;
00480 vector<const Muon*>::const_iterator tagCandIt = m_TightMuons.begin();
00481
00482 for (; tagCandIt!=tightMuonsEnd; ++tagCandIt) {
00483 if ((*tagCandIt) == (*probeCandIt)) continue;
00484 tagHasTrig |= matchHlt(trigEvent,(*tagCandIt));
00485 }
00486
00487 if (tagHasTrig) m_ProbeMuons.push_back((*probeCandIt));
00488
00489 }
00490
00491 m_ControlHistos["NProbesVsTight"]->Fill(m_TightMuons.size(),m_ProbeMuons.size());
00492
00493 }
00494
00495
00496 void L1TEfficiencyMuons_Offline::getMuonGmtPairs(edm::Handle<L1MuGMTReadoutCollection> & gmtCands) {
00497
00498 m_MuonGmtPairs.clear();
00499
00500 cout << "[L1TEfficiencyMuons_Offline:] Getting muon GMT pairs" << endl;
00501
00502 vector<const Muon*>::const_iterator probeMuIt = m_ProbeMuons.begin();
00503 vector<const Muon*>::const_iterator probeMuEnd = m_ProbeMuons.end();
00504
00505 vector<L1MuGMTExtendedCand> gmtContainer = gmtCands->getRecord(0).getGMTCands();
00506
00507 vector<L1MuGMTExtendedCand>::const_iterator gmtIt;
00508 vector<L1MuGMTExtendedCand>::const_iterator gmtEnd = gmtContainer.end();
00509
00510 for (; probeMuIt!=probeMuEnd; ++probeMuIt) {
00511
00512 MuonGmtPair pairBestCand((*probeMuIt),0);
00513 pairBestCand.propagate(m_BField,m_propagatorAlong,m_propagatorOpposite);
00514
00515 gmtIt = gmtContainer.begin();
00516
00517 for(; gmtIt!=gmtEnd; ++gmtIt) {
00518
00519 MuonGmtPair pairTmpCand((*probeMuIt),&(*gmtIt));
00520 pairTmpCand.propagate(m_BField,m_propagatorAlong,m_propagatorOpposite);
00521
00522 if (pairTmpCand.dR() < m_MaxGmtMuonDR && pairTmpCand.gmtPt() > pairBestCand.gmtPt())
00523 pairBestCand = pairTmpCand;
00524
00525 }
00526
00527 m_MuonGmtPairs.push_back(pairBestCand);
00528
00529 m_ControlHistos["MuonGmtDeltaR"]->Fill(pairBestCand.dR());
00530
00531 }
00532
00533 }
00534
00535
00536 bool L1TEfficiencyMuons_Offline::matchHlt(edm::Handle<TriggerEvent> & triggerEvent, const Muon * mu) {
00537
00538
00539 double matchDeltaR = 9999;
00540
00541 TriggerObjectCollection trigObjs = triggerEvent->getObjects();
00542
00543 vector<int>::const_iterator trigIndexIt = m_trigIndices.begin();
00544 vector<int>::const_iterator trigIndexEnd = m_trigIndices.end();
00545
00546 for(; trigIndexIt!=trigIndexEnd; ++trigIndexIt) {
00547
00548 const vector<string> moduleLabels(m_hltConfig.moduleLabels(*trigIndexIt));
00549 const unsigned moduleIndex = m_hltConfig.size((*trigIndexIt))-2;
00550 const unsigned hltFilterIndex = triggerEvent->filterIndex(InputTag(moduleLabels[moduleIndex],
00551 "",m_trigProcess));
00552
00553 if (hltFilterIndex < triggerEvent->sizeFilters()) {
00554 const Keys triggerKeys(triggerEvent->filterKeys(hltFilterIndex));
00555 const Vids triggerVids(triggerEvent->filterIds(hltFilterIndex));
00556
00557 const unsigned nTriggers = triggerVids.size();
00558 for (size_t iTrig = 0; iTrig < nTriggers; ++iTrig) {
00559 const TriggerObject trigObject = trigObjs[triggerKeys[iTrig]];
00560
00561 double dRtmp = deltaR((*mu),trigObject);
00562 if (dRtmp < matchDeltaR) matchDeltaR = dRtmp;
00563
00564 }
00565 }
00566 }
00567
00568 return (matchDeltaR < m_MaxHltMuonDR);
00569
00570 }
00571
00572
00573
00574 DEFINE_FWK_MODULE(L1TEfficiencyMuons_Offline);