00001 #include "HLTrigger/Muon/interface/HLTMuonTrackMassFilter.h"
00002
00003 #include "FWCore/Framework/interface/Frameworkfwd.h"
00004
00005 #include "FWCore/Framework/interface/Event.h"
00006 #include "FWCore/Framework/interface/MakerMacros.h"
00007 #include "DataFormats/Common/interface/Handle.h"
00008
00009 #include "DataFormats/HLTReco/interface/TriggerFilterObjectWithRefs.h"
00010 #include "DataFormats/HLTReco/interface/TriggerRefsCollections.h"
00011
00012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00013 #include "FWCore/MessageLogger/interface/MessageDrop.h"
00014
00015 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
00016 #include "DataFormats/RecoCandidate/interface/RecoChargedCandidate.h"
00017 #include "DataFormats/RecoCandidate/interface/RecoChargedCandidateFwd.h"
00018 #include "DataFormats/TrackReco/interface/Track.h"
00019
00020 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00021
00022 #include "DataFormats/Math/interface/deltaR.h"
00023
00024 #include <memory>
00025 #include <iostream>
00026 #include <sstream>
00027
00028
00029 HLTMuonTrackMassFilter::HLTMuonTrackMassFilter(const edm::ParameterSet& iConfig) :
00030 beamspotTag_(iConfig.getParameter<edm::InputTag>("BeamSpotTag")),
00031 muonTag_(iConfig.getParameter<edm::InputTag>("CandTag")),
00032 trackTag_(iConfig.getParameter<edm::InputTag>("TrackTag")),
00033 prevCandTag_(iConfig.getParameter<edm::InputTag>("PreviousCandTag")),
00034 saveTag_(iConfig.getUntrackedParameter<bool>("SaveTag",false)),
00035 minMasses_(iConfig.getParameter< std::vector<double> >("MinMasses")),
00036 maxMasses_(iConfig.getParameter< std::vector<double> >("MaxMasses")),
00037 checkCharge_(iConfig.getParameter<bool>("checkCharge")),
00038 minTrackPt_(iConfig.getParameter<double>("MinTrackPt")),
00039 minTrackP_(iConfig.getParameter<double>("MinTrackP")),
00040 maxTrackEta_(iConfig.getParameter<double>("MaxTrackEta")),
00041 maxTrackDxy_(iConfig.getParameter<double>("MaxTrackDxy")),
00042 maxTrackDz_(iConfig.getParameter<double>("MaxTrackDz")),
00043 minTrackHits_(iConfig.getParameter<int>("MinTrackHits")),
00044 maxTrackNormChi2_(iConfig.getParameter<double>("MaxTrackNormChi2")),
00045 maxDzMuonTrack_(iConfig.getParameter<double>("MaxDzMuonTrack")),
00046 cutCowboys_(iConfig.getParameter<bool>("CutCowboys"))
00047 {
00048
00049 produces<trigger::TriggerFilterObjectWithRefs>();
00050
00051
00052
00053 bool massesValid = minMasses_.size()==maxMasses_.size();
00054 if ( massesValid ) {
00055 for ( unsigned int i=0; i<minMasses_.size(); ++i ) {
00056 if ( minMasses_[i]<0 || maxMasses_[i]<0 ||
00057 minMasses_[i]>maxMasses_[i] ) massesValid = false;
00058 }
00059 }
00060 if ( !massesValid ) {
00061 edm::LogError("HLTMuonTrackMassFilter") << "Inconsistency in definition of mass windows, "
00062 << "no event will pass the filter";
00063 minMasses_.clear();
00064 maxMasses_.clear();
00065 }
00066
00067 std::ostringstream stream;
00068 stream << "instantiated with parameters\n";
00069 stream << " beamspot = " << beamspotTag_ << "\n";
00070 stream << " muonCandidates = " << muonTag_ << "\n";
00071 stream << " trackCandidates = " << trackTag_ << "\n";
00072 stream << " previousCandidates = " << prevCandTag_ << "\n";
00073 stream << " saveTag = " << saveTag_ << "\n";
00074 stream << " mass windows =";
00075 for ( size_t i=0; i<minMasses_.size(); ++i )
00076 stream << " (" << minMasses_[i] << "," << maxMasses_[i] << ")";
00077 stream << "\n";
00078 stream << " checkCharge = " << checkCharge_ << "\n";
00079 stream << " MinTrackPt = " << minTrackPt_ << "\n";
00080 stream << " MinTrackP = " << minTrackP_ << "\n";
00081 stream << " MaxTrackEta = " << maxTrackEta_ << "\n";
00082 stream << " MaxTrackDxy = " << maxTrackDxy_ << "\n";
00083 stream << " MaxTrackDz = " << maxTrackDz_ << "\n";
00084 stream << " MinTrackHits = " << minTrackHits_ << "\n";
00085 stream << " MaxTrackNormChi2 = " << maxTrackNormChi2_ << "\n";
00086 stream << " MaxDzMuonTrack = " << maxDzMuonTrack_ << "\n";
00087 LogDebug("HLTMuonTrackMassFilter") << stream.str();
00088
00089 }
00090
00091 bool
00092 HLTMuonTrackMassFilter::filter(edm::Event& iEvent, const edm::EventSetup& iSetup)
00093 {
00094
00095 std::auto_ptr<trigger::TriggerFilterObjectWithRefs>
00096 filterproduct (new trigger::TriggerFilterObjectWithRefs(path(),module()));
00097 if ( saveTag_ ) {
00098 filterproduct->addCollectionTag(muonTag_);
00099 filterproduct->addCollectionTag(trackTag_);
00100 }
00101
00102
00103
00104 edm::Handle<reco::BeamSpot> beamspotHandle;
00105 iEvent.getByLabel(beamspotTag_,beamspotHandle);
00106 reco::BeamSpot::Point beamspot(beamspotHandle->position());
00107
00108
00109
00110 edm::Handle<reco::RecoChargedCandidateCollection> muonHandle;
00111 iEvent.getByLabel(muonTag_,muonHandle);
00112
00113
00114
00115 edm::Handle<reco::RecoChargedCandidateCollection> trackHandle;
00116 iEvent.getByLabel(trackTag_,trackHandle);
00117
00118
00119
00120 edm::Handle<trigger::TriggerFilterObjectWithRefs> prevCandHandle;
00121 iEvent.getByLabel(prevCandTag_,prevCandHandle);
00122 std::vector<reco::RecoChargedCandidateRef> prevMuonRefs;
00123 prevCandHandle->getObjects(trigger::TriggerMuon,prevMuonRefs);
00124 std::vector<reco::RecoChargedCandidateRef> prevTrackRefs;
00125 prevCandHandle->getObjects(trigger::TriggerTrack,prevTrackRefs);
00126 bool checkPrevTracks = prevTrackRefs.size()==prevMuonRefs.size();
00127
00128
00129
00130
00131
00132
00133
00134 std::vector<reco::RecoChargedCandidateRef> selectedMuonRefs;
00135 selectedMuonRefs.reserve(muonHandle->size());
00136
00137
00138 for ( unsigned int i=0; i<muonHandle->size(); ++i ) {
00139
00140 reco::RecoChargedCandidateRef muonRef(muonHandle,i);
00141
00142
00143
00144
00145 if ( find(prevMuonRefs.begin(),prevMuonRefs.end(),muonRef)==
00146 prevMuonRefs.end() ) continue;
00147
00148
00149
00150
00151 selectedMuonRefs.push_back(muonRef);
00152 }
00153
00154
00155
00156
00157 std::vector<reco::RecoChargedCandidateRef> selectedTrackRefs;
00158 selectedTrackRefs.reserve(trackHandle->size());
00159
00160 for ( unsigned int i=0; i<trackHandle->size(); ++i ) {
00161
00162 reco::RecoChargedCandidateRef trackRef(trackHandle,i);
00163 const reco::RecoChargedCandidate& trackCand = *trackRef;
00164
00165
00166
00167
00168 if ( trackCand.pt()<minTrackPt_ || trackCand.p()<minTrackP_ ||
00169 fabs(trackCand.eta())>maxTrackEta_ ) continue;
00170 if ( trackCand.track().isNull() ) continue;
00171
00172 const reco::Track& track = *trackCand.track();
00173
00174
00175
00176
00177
00178 if ( fabs(track.dxy(beamspot))>maxTrackDxy_ ||
00179 fabs(track.dz(beamspot))>maxTrackDz_ ||
00180 track.numberOfValidHits()<minTrackHits_ ||
00181 track.normalizedChi2()>maxTrackNormChi2_ ) continue;
00182
00183
00184 selectedTrackRefs.push_back(trackRef);
00185 }
00186
00187
00188
00189
00190 unsigned int nDz(0);
00191 unsigned int nQ(0);
00192 unsigned int nCowboy(0);
00193 unsigned int nComb(0);
00194 reco::Particle::LorentzVector p4Muon;
00195 reco::Particle::LorentzVector p4JPsi;
00196
00197 for ( unsigned int im=0; im<selectedMuonRefs.size(); ++im ) {
00198 const reco::RecoChargedCandidate& muon = *selectedMuonRefs[im];
00199 int qMuon = muon.charge();
00200 p4Muon = muon.p4();
00201 for ( unsigned int it=0; it<selectedTrackRefs.size(); ++it ) {
00202 const reco::RecoChargedCandidate& track = *selectedTrackRefs[it];
00203
00204
00205
00206
00207 if ( fabs(muon.track()->dz(beamspot)-track.track()->dz(beamspot))>
00208 maxDzMuonTrack_ ) continue;
00209 ++nDz;
00210 if ( checkCharge_ && track.charge()!=-qMuon ) continue;
00211 ++nQ;
00212
00213
00214 if(cutCowboys_ && (qMuon*deltaPhi(p4Muon.phi(), track.phi()) > 0.)) continue;
00215 ++nCowboy;
00216
00217 if ( checkPrevTracks ) {
00218 if ( !pairMatched(prevMuonRefs,prevTrackRefs,
00219 selectedMuonRefs[im],
00220 selectedTrackRefs[it]) ) continue;
00221 }
00222 double mass = (p4Muon+track.p4()).mass();
00223 for ( unsigned int j=0; j<minMasses_.size(); ++j ) {
00224 if ( mass>minMasses_[j] && mass<maxMasses_[j] ) {
00225 ++nComb;
00226 filterproduct->addObject(trigger::TriggerMuon,selectedMuonRefs[im]);
00227 filterproduct->addObject(trigger::TriggerTrack,selectedTrackRefs[it]);
00228
00229 break;
00230 }
00231 }
00232 }
00233 }
00234
00235
00236
00237 if ( edm::isDebugEnabled() ) {
00238 std::ostringstream stream;
00239 stream << "Total number of combinations = "
00240 << selectedMuonRefs.size()*selectedTrackRefs.size() << " , after dz " << nDz
00241 << " , after charge " << nQ << " , after cutCowboy " << nCowboy << " , after mass " << nComb << std::endl;
00242 stream << "Found " << nComb << " jpsi candidates with # / mass / q / pt / eta" << std::endl;
00243 std::vector<reco::RecoChargedCandidateRef> muRefs;
00244 std::vector<reco::RecoChargedCandidateRef> tkRefs;
00245 filterproduct->getObjects(trigger::TriggerMuon,muRefs);
00246 filterproduct->getObjects(trigger::TriggerTrack,tkRefs);
00247 reco::Particle::LorentzVector p4Mu;
00248 reco::Particle::LorentzVector p4Tk;
00249 reco::Particle::LorentzVector p4JPsi;
00250 if ( muRefs.size()==tkRefs.size() ) {
00251 for ( unsigned int i=0; i<muRefs.size(); ++i ) {
00252 p4Mu = muRefs[i]->p4();
00253 p4Tk = tkRefs[i]->p4();
00254 p4JPsi = p4Mu + p4Tk;
00255 stream << " " << i << " "
00256 << p4JPsi.M() << " "
00257 << muRefs[i]->charge()+tkRefs[i]->charge() << " "
00258 << p4JPsi.P() << " "
00259 << p4JPsi.Eta() << "\n";
00260 }
00261 LogDebug("HLTMuonTrackMassFilter") << stream.str();
00262 }
00263 else {
00264 LogDebug("HLTMuonTrackMassFilter") << "different sizes for muon and track containers!!!";
00265 }
00266 }
00267
00268 iEvent.put(filterproduct);
00269
00270 return nComb>0;
00271 }
00272
00273 bool
00274 HLTMuonTrackMassFilter::pairMatched (std::vector<reco::RecoChargedCandidateRef>& prevMuonRefs,
00275 std::vector<reco::RecoChargedCandidateRef>& prevTrackRefs,
00276 const reco::RecoChargedCandidateRef& muonRef,
00277 const reco::RecoChargedCandidateRef& trackRef) const
00278 {
00279
00280
00281
00282 if ( prevTrackRefs.empty() ) return true;
00283
00284
00285
00286 if ( prevMuonRefs.size()!=prevTrackRefs.size() ) return false;
00287 edm::RefToBase<TrajectorySeed> seedRef = trackRef->track()->seedRef();
00288 if ( seedRef.isNull() ) return false;
00289
00290
00291
00292
00293 TrajectorySeed::range seedHits = seedRef->recHits();
00294 trackingRecHit_iterator prevTrackHitEnd;
00295 trackingRecHit_iterator iprev;
00296 TrajectorySeed::const_iterator iseed;
00297 for ( size_t i=0; i<prevMuonRefs.size(); ++i ) {
00298
00299 if ( prevMuonRefs[i]!=muonRef ) continue;
00300
00301 reco::TrackRef prevTrackRef = prevTrackRefs[i]->track();
00302 if ( prevTrackRef.isNull() ) continue;
00303
00304 if (prevTrackRef==trackRef->track()) return true;
00305
00306 if ( seedRef->nHits()!=prevTrackRef->recHitsSize() ) continue;
00307
00308 iseed = seedHits.first;
00309 iprev = prevTrackRef->recHitsBegin();
00310 prevTrackHitEnd = prevTrackRef->recHitsEnd();
00311 bool identical(true);
00312 for ( ; iseed!=seedHits.second&&iprev!=prevTrackHitEnd; ++iseed,++iprev ) {
00313 if ( (*iseed).isValid()!=(**iprev).isValid() ||
00314 !(*iseed).sharesInput(&**iprev,TrackingRecHit::all) ) {
00315
00316 identical = false;
00317 break;
00318 }
00319 }
00320
00321 if ( identical ) return true;
00322 }
00323
00324 return false;
00325 }
00326
00327
00328
00329
00330
00331
00332 DEFINE_FWK_MODULE(HLTMuonTrackMassFilter);