CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/HLTrigger/Muon/src/HLTMuonL1Filter.cc

Go to the documentation of this file.
00001 
00009 #include "HLTrigger/Muon/interface/HLTMuonL1Filter.h"
00010 
00011 #include "DataFormats/Common/interface/Handle.h"
00012 #include "DataFormats/HLTReco/interface/TriggerFilterObjectWithRefs.h"
00013 #include "DataFormats/HLTReco/interface/TriggerRefsCollections.h"
00014 
00015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00016 
00017 #include "DataFormats/L1GlobalMuonTrigger/interface/L1MuGMTCand.h"
00018 #include "FWCore/Utilities/interface/EDMException.h"
00019 
00020 #include "FWCore/Framework/interface/ESHandle.h"
00021 #include "TMath.h"
00022 
00023 //
00024 // constructors and destructor
00025 //
00026 HLTMuonL1Filter::HLTMuonL1Filter(const edm::ParameterSet& iConfig) :
00027   candTag_( iConfig.getParameter<edm::InputTag>("CandTag") ),
00028   previousCandTag_( iConfig.getParameter<edm::InputTag>("PreviousCandTag") ),
00029   maxEta_( iConfig.getParameter<double>("MaxEta") ),
00030   minPt_( iConfig.getParameter<double>("MinPt") ),
00031   minN_( iConfig.getParameter<int>("MinN") ),
00032   excludeSingleSegmentCSC_( iConfig.getParameter<bool>("ExcludeSingleSegmentCSC") ),
00033   csctfTag_( iConfig.getParameter<edm::InputTag>("CSCTFtag") ),
00034   l1MuTriggerScales_(0),
00035   m_scalesCacheID_(0),
00036   saveTag_( iConfig.getUntrackedParameter<bool>("SaveTag",false) ) 
00037 {
00038   using namespace std;
00039 
00040   //set the quality bit mask
00041   qualityBitMask_ = 0;
00042   vector<int> selectQualities = iConfig.getParameter<vector<int> >("SelectQualities");
00043   for(size_t i=0; i<selectQualities.size(); i++){
00044     if(selectQualities[i] > 7){
00045       throw edm::Exception(edm::errors::Configuration) << "QualityBits must be smaller than 8!";
00046     }
00047     qualityBitMask_ |= 1<<selectQualities[i];
00048   }
00049  
00050   // dump parameters for debugging
00051   if(edm::isDebugEnabled()){
00052     ostringstream ss;
00053     ss<<"Constructed with parameters:"<<endl;
00054     ss<<"    CandTag = "<<candTag_.encode()<<endl;
00055     ss<<"    PreviousCandTag = "<<previousCandTag_.encode()<<endl;
00056     ss<<"    MaxEta = "<<maxEta_<<endl;
00057     ss<<"    MinPt = "<<minPt_<<endl;
00058     ss<<"    SelectQualities =";
00059     for(size_t i=0; i<8; i++){
00060       if((qualityBitMask_>>i) % 2) ss<<" "<<i;
00061     }
00062     ss<<endl;
00063     ss<<"    MinN = "<<minN_<<endl;
00064     ss<<"    ExcludeSingleSegmentCSC = "<<excludeSingleSegmentCSC_<<endl;
00065     ss<<"    CSCTFtag = "<<csctfTag_.encode()<<endl;
00066     ss<<"    SaveTag = "<<saveTag_;
00067     LogDebug("HLTMuonL1Filter")<<ss.str();
00068   }
00069 
00070   //register your products
00071   produces<trigger::TriggerFilterObjectWithRefs>();
00072 }
00073 
00074 HLTMuonL1Filter::~HLTMuonL1Filter()
00075 {
00076 }
00077 
00078 //
00079 // member functions
00080 //
00081 
00082 // ------------ method called to produce the data  ------------
00083 bool HLTMuonL1Filter::filter(edm::Event& iEvent, const edm::EventSetup& iSetup){
00084   using namespace std;
00085   using namespace edm;
00086   using namespace trigger;
00087   using namespace l1extra;
00088 
00089   // All HLT filters must create and fill an HLT filter object,
00090   // recording any reconstructed physics objects satisfying (or not)
00091   // this HLT filter, and place it in the Event.
00092 
00093   // The filter object
00094   auto_ptr<TriggerFilterObjectWithRefs> filterproduct(new TriggerFilterObjectWithRefs(path(), module()));
00095 
00096   // get hold of all muons
00097   Handle<L1MuonParticleCollection> allMuons;
00098   iEvent.getByLabel(candTag_, allMuons);
00099 
00100   // get hold of CSCTF raw tracks
00101   if( excludeSingleSegmentCSC_ ) {
00102     iEvent.getByLabel(csctfTag_, csctfTracks_);
00103     // update scales if necessary
00104     if( iSetup.get<L1MuTriggerScalesRcd>().cacheIdentifier() != m_scalesCacheID_ ){
00105       LogDebug("HLTMuonL1Filter")<<"Changing trigger scales";
00106       ESHandle<L1MuTriggerScales> scales;
00107       iSetup.get<L1MuTriggerScalesRcd>().get(scales);
00108       l1MuTriggerScales_ = scales.product();
00109       m_scalesCacheID_  = iSetup.get<L1MuTriggerScalesRcd>().cacheIdentifier();
00110     }
00111   }  
00112 
00113   // get hold of muons that fired the previous level
00114   Handle<TriggerFilterObjectWithRefs> previousLevelCands;
00115   iEvent.getByLabel(previousCandTag_, previousLevelCands);
00116   vector<L1MuonParticleRef> prevMuons;
00117   previousLevelCands->getObjects(TriggerL1Mu, prevMuons);
00118    
00119   // look at all muon candidates, check cuts and add to filter object
00120   int n = 0;
00121   for(size_t i = 0; i < allMuons->size(); i++){
00122     L1MuonParticleRef muon(allMuons, i);
00123 
00124     //check if triggered by the previous level
00125     if(find(prevMuons.begin(), prevMuons.end(), muon) == prevMuons.end()) continue;
00126 
00127     //check maxEta cut
00128     if(fabs(muon->eta()) > maxEta_) continue;
00129 
00130     //check pT cut
00131     if(muon->pt() < minPt_) continue;
00132 
00133     //check quality cut
00134     if(qualityBitMask_){
00135       int quality = muon->gmtMuonCand().empty() ? 0 : (1 << muon->gmtMuonCand().quality());
00136       if((quality & qualityBitMask_) == 0) continue;
00137     }
00138 
00139     // reject single-segment CSC objects if necessary
00140     if (excludeSingleSegmentCSC_ && isSingleSegmentCSC(muon)) continue;
00141 
00142     //we have a good candidate
00143     n++;
00144     filterproduct->addObject(TriggerL1Mu,muon);
00145   }
00146 
00147   if(saveTag_) filterproduct->addCollectionTag(candTag_);
00148 
00149   // filter decision
00150   const bool accept(n >= minN_);
00151 
00152   // dump event for debugging
00153   if(edm::isDebugEnabled()){
00154     ostringstream ss;
00155     ss.precision(2);
00156     ss<<"L1mu#"<<'\t'<<"q*pt"<<'\t'<<'\t'<<"eta"<<'\t'<<"phi"<<'\t'<<"quality"<<'\t'<<"isPrev"<<'\t'<<"isFired"<<'\t'<<"isSingleCSC"<<endl;
00157     ss<<"--------------------------------------------------------------------------"<<endl;
00158 
00159     vector<L1MuonParticleRef> firedMuons;
00160     filterproduct->getObjects(TriggerL1Mu, firedMuons);
00161     for(size_t i=0; i<allMuons->size(); i++){
00162       L1MuonParticleRef mu(allMuons, i);
00163       int quality = mu->gmtMuonCand().empty() ? 0 : mu->gmtMuonCand().quality();
00164       bool isPrev = find(prevMuons.begin(), prevMuons.end(), mu) != prevMuons.end();
00165       bool isFired = find(firedMuons.begin(), firedMuons.end(), mu) != firedMuons.end();
00166       bool isSingleCSC = excludeSingleSegmentCSC_ && isSingleSegmentCSC(mu);
00167       ss<<i<<'\t'<<scientific<<mu->charge()*mu->pt()<<'\t'<<fixed<<mu->eta()<<'\t'<<mu->phi()<<'\t'<<quality<<'\t'<<isPrev<<'\t'<<isFired<<'\t'<<isSingleCSC<<endl;
00168     }
00169     ss<<"--------------------------------------------------------------------------"<<endl;
00170     LogDebug("HLTMuonL1Filter")<<ss.str()<<"Decision of filter is "<<accept<<", number of muons passing = "<<filterproduct->l1muonSize();
00171   }
00172 
00173   // put filter object into the Event
00174   iEvent.put(filterproduct);
00175 
00176   return accept;
00177 }
00178 
00179 bool HLTMuonL1Filter::isSingleSegmentCSC(const l1extra::L1MuonParticleRef & muon){
00180   // is the muon matching a csctf track?
00181   bool matched   = false;
00182   // which csctf track mode?
00183   // -999: no matching
00184   //  1: bad phi road. Not good extrapolation, but still triggering
00185   // 11: singles
00186   // 15: halo
00187   // 2->10 and 12->14: coincidence trigger with good extrapolation
00188   int csctfMode = -999;
00189 
00190   // loop over the CSCTF tracks
00191   for(L1CSCTrackCollection::const_iterator trk=csctfTracks_->begin(); trk<csctfTracks_->end(); trk++){
00192     
00193     int trEndcap = (trk->first.endcap()==2 ? trk->first.endcap()-3 : trk->first.endcap());
00194     int trSector = 6*(trk->first.endcap()-1)+trk->first.sector();
00195 
00196     //... in radians
00197     // Type 2 is CSC
00198     float trEtaScale = l1MuTriggerScales_->getRegionalEtaScale(2)->getCenter(trk->first.eta_packed());
00199     float trPhiScale = l1MuTriggerScales_->getPhiScale()->getLowEdge(trk->first.localPhi());
00200 
00201     double trEta = trEtaScale * trEndcap;
00202     // there is no L1ExtraParticle below -2.375
00203     if(trEta<-2.4) trEta=-2.375;
00204 
00205     // CSCTF has 6 sectors 
00206     // sector 1 starts at 15 degrees
00207     // trPhiScale is defined inside a sector 
00208     float trPhi02PI = fmod(trPhiScale + 
00209                            ((trSector-1)*TMath::Pi()/3) + 
00210                            (TMath::Pi()/12) , 2*TMath::Pi());
00211 
00212     // L1 information are given from [-Pi,Pi] 
00213     double trPhi = ( trPhi02PI<TMath::Pi()? trPhi02PI : trPhi02PI - 2*TMath::Pi() );
00214     /*    
00215     std::cout << "\ntrEndcap="               << trEndcap                << std::endl;
00216     std::cout << "trSector="                 << trSector                << std::endl;
00217     std::cout << "trk->first.eta_packed()="  << trk->first.eta_packed() << std::endl;
00218     std::cout << "trk->first.localPhi()="    << trk->first.localPhi()   << std::endl;
00219     std::cout << "trEtaScale=" << trEtaScale << std::endl;
00220     std::cout << "trPhiScale=" << trPhiScale << std::endl;
00221     std::cout << "trEta="      << trEta      << std::endl;
00222     std::cout << "trPhi="      << trPhi      << std::endl;
00223     */
00224     if ( fabs (trEta-muon->eta()) < 0.03 && 
00225          fabs (trPhi-muon->phi()) < 0.001  ) {
00226       
00227       matched = true;
00228       ptadd thePtAddress(trk->first.ptLUTAddress());    
00229       csctfMode = thePtAddress.track_mode;
00230 
00231       //std::cout << "is matched -> trMode=" << csctfMode << std::endl;
00232     }
00233   }
00234 
00235   /*
00236   std::cout << " ===================================== " << std::endl;
00237   std::cout << " is matched? " << matched                << std::endl;
00238   std::cout << " is singles? " << (csctfMode==11 ? 1 :0) << std::endl;
00239   std::cout << " ===================================== " << std::endl;
00240   */
00241 
00242   // singles are mode 11 "CSCTF tracks"
00243   return csctfMode==11;  
00244 }