00001
00009 #include "FWCore/Framework/interface/Frameworkfwd.h"
00010 #include "FWCore/Framework/interface/EDProducer.h"
00011 #include "FWCore/Framework/interface/Event.h"
00012 #include "FWCore/Framework/interface/MakerMacros.h"
00013 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00014
00015 #include "DataFormats/MuonReco/interface/Muon.h"
00016 #include "DataFormats/MuonReco/interface/MuonFwd.h"
00017 #include "DataFormats/MuonReco/interface/MuonCocktails.h"
00018 #include "DataFormats/TrackReco/interface/Track.h"
00019 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00020 #include "DataFormats/TrackReco/interface/TrackToTrackMap.h"
00021
00022 reco::Muon::MuonTrackTypePair tevOptimizedTMR(const reco::Muon& muon, const reco::TrackToTrackMap& fmsMap,
00023 const double cut) {
00024 const reco::TrackRef& combinedTrack = muon.globalTrack();
00025 const reco::TrackRef& trackerTrack = muon.innerTrack();
00026
00027 reco::TrackToTrackMap::const_iterator fmsTrack = fmsMap.find(combinedTrack);
00028
00029 double probTK = 0;
00030 double probFMS = 0;
00031
00032 if (trackerTrack.isAvailable() && trackerTrack->numberOfValidHits())
00033 probTK = muon::trackProbability(trackerTrack);
00034 if (fmsTrack != fmsMap.end() && fmsTrack->val->numberOfValidHits())
00035 probFMS = muon::trackProbability(fmsTrack->val);
00036
00037 bool TKok = probTK > 0;
00038 bool FMSok = probFMS > 0;
00039
00040 if (TKok && FMSok) {
00041 if (probFMS - probTK > cut)
00042 return make_pair(trackerTrack,reco::Muon::InnerTrack);
00043 else
00044 return make_pair(fmsTrack->val,reco::Muon::TPFMS);
00045 }
00046 else if (FMSok)
00047 return make_pair(fmsTrack->val,reco::Muon::TPFMS);
00048 else if (TKok)
00049 return make_pair(trackerTrack,reco::Muon::InnerTrack);
00050
00051 return make_pair(combinedTrack,reco::Muon::CombinedTrack);
00052 }
00053
00054 reco::Muon::MuonTrackTypePair sigmaSwitch(const reco::Muon& muon, const double nSigma, const double ptThreshold) {
00055 const reco::TrackRef& combinedTrack = muon.globalTrack();
00056 const reco::TrackRef& trackerTrack = muon.innerTrack();
00057
00058 if (combinedTrack->pt() < ptThreshold || trackerTrack->pt() < ptThreshold)
00059 return make_pair(trackerTrack,reco::Muon::InnerTrack);
00060
00061 double delta = fabs(trackerTrack->qoverp() - combinedTrack->qoverp());
00062 double threshold = nSigma * trackerTrack->qoverpError();
00063
00064 return delta > threshold ? make_pair(trackerTrack,reco::Muon::InnerTrack) : make_pair(combinedTrack,reco::Muon::CombinedTrack);
00065 }
00066
00067 class MuonsFromRefitTracksProducer : public edm::EDProducer {
00068 public:
00069 explicit MuonsFromRefitTracksProducer(const edm::ParameterSet&);
00070 ~MuonsFromRefitTracksProducer() {}
00071
00072 private:
00073 virtual void beginJob() {}
00074 virtual void produce(edm::Event&, const edm::EventSetup&);
00075 virtual void endJob() {}
00076
00077
00078 bool storeMatchMaps(const edm::Event& event);
00079
00080
00081
00082
00083 reco::Muon* cloneAndSwitchTrack(const reco::Muon& muon,
00084 const reco::Muon::MuonTrackTypePair& newTrack) const;
00085
00086
00087 edm::InputTag src;
00088
00089
00090
00091
00092
00093 bool fromTrackerTrack;
00094
00095
00096
00097
00098
00099 bool fromGlobalTrack;
00100
00101
00102
00103 bool fromTeVRefit;
00104
00105
00106
00107
00108 std::string tevMuonTracks;
00109
00110
00111
00112
00113 bool fromCocktail;
00114
00115
00116
00117 bool fromTMR;
00118
00119
00120 double TMRcut;
00121
00122
00123
00124 bool fromSigmaSwitch;
00125
00126
00127 double nSigmaSwitch;
00128
00129
00130 double ptThreshold;
00131
00132
00133
00134
00135 edm::Handle<reco::TrackToTrackMap> trackMap;
00136
00137
00138 edm::Handle<reco::TrackToTrackMap> trackMapDefault;
00139 edm::Handle<reco::TrackToTrackMap> trackMapFirstHit;
00140 edm::Handle<reco::TrackToTrackMap> trackMapPicky;
00141 };
00142
00143 MuonsFromRefitTracksProducer::MuonsFromRefitTracksProducer(const edm::ParameterSet& cfg)
00144 : src(cfg.getParameter<edm::InputTag>("src")),
00145 fromTrackerTrack(cfg.getParameter<bool>("fromTrackerTrack")),
00146 fromGlobalTrack(cfg.getParameter<bool>("fromGlobalTrack")),
00147 tevMuonTracks(cfg.getParameter<std::string>("tevMuonTracks")),
00148 fromCocktail(cfg.getParameter<bool>("fromCocktail")),
00149 fromTMR(cfg.getParameter<bool>("fromTMR")),
00150 TMRcut(cfg.getParameter<double>("TMRcut")),
00151 fromSigmaSwitch(cfg.getParameter<bool>("fromSigmaSwitch")),
00152 nSigmaSwitch(cfg.getParameter<double>("nSigmaSwitch")),
00153 ptThreshold(cfg.getParameter<double>("ptThreshold"))
00154 {
00155 fromTeVRefit = tevMuonTracks != "none";
00156 produces<reco::MuonCollection>();
00157 }
00158
00159 bool MuonsFromRefitTracksProducer::storeMatchMaps(const edm::Event& event) {
00160 if (fromCocktail || fromTMR) {
00161 event.getByLabel(tevMuonTracks, "default", trackMapDefault);
00162 event.getByLabel(tevMuonTracks, "firstHit", trackMapFirstHit);
00163 event.getByLabel(tevMuonTracks, "picky", trackMapPicky);
00164 return !trackMapDefault.failedToGet() &&
00165 !trackMapFirstHit.failedToGet() && !trackMapPicky.failedToGet();
00166 }
00167 else {
00168 event.getByLabel(edm::InputTag(tevMuonTracks), trackMap);
00169 return !trackMap.failedToGet();
00170 }
00171 }
00172
00173 reco::Muon* MuonsFromRefitTracksProducer::cloneAndSwitchTrack(const reco::Muon& muon,
00174 const reco::Muon::MuonTrackTypePair& newTrack) const {
00175
00176 static const double muMass = 0.10566;
00177
00178 reco::TrackRef tkTrack = muon.innerTrack();
00179 reco::TrackRef muTrack = muon.outerTrack();
00180
00181
00182 reco::Particle::Point vtx(newTrack.first->vx(), newTrack.first->vy(), newTrack.first->vz());
00183 reco::Particle::LorentzVector p4;
00184 double p = newTrack.first->p();
00185 p4.SetXYZT(newTrack.first->px(), newTrack.first->py(), newTrack.first->pz(),
00186 sqrt(p*p + muMass*muMass));
00187
00188 reco::Muon* mu = muon.clone();
00189 mu->setCharge(newTrack.first->charge());
00190 mu->setP4(p4);
00191 mu->setVertex(vtx);
00192 mu->setGlobalTrack(newTrack.first);
00193 mu->setInnerTrack(tkTrack);
00194 mu->setOuterTrack(muTrack);
00195 mu->setBestTrack(newTrack.second);
00196 return mu;
00197 }
00198
00199 void MuonsFromRefitTracksProducer::produce(edm::Event& event, const edm::EventSetup& eSetup) {
00200
00201 edm::Handle<edm::View<reco::Muon> > muons;
00202 event.getByLabel(src, muons);
00203
00204
00205
00206
00207 bool ok = !muons.failedToGet();
00208
00209
00210
00211
00212
00213
00214 if (ok && fromTeVRefit)
00215 ok = storeMatchMaps(event);
00216
00217
00218 std::auto_ptr<reco::MuonCollection> cands(new reco::MuonCollection);
00219
00220 if (ok) {
00221 edm::View<reco::Muon>::const_iterator muon;
00222 for (muon = muons->begin(); muon != muons->end(); muon++) {
00223
00224
00225
00226 if (!muon->isGlobalMuon()) continue;
00227
00228 if (fromTeVRefit || fromSigmaSwitch) {
00229
00230 reco::Muon::MuonTrackTypePair tevTk;
00231
00232
00233
00234
00235 if (fromTMR)
00236 tevTk = tevOptimizedTMR(*muon, *trackMapFirstHit, TMRcut);
00237 else if (fromCocktail)
00238 tevTk = muon::tevOptimized(*muon, *trackMapDefault, *trackMapFirstHit,
00239 *trackMapPicky);
00240 else if (fromSigmaSwitch)
00241 tevTk = sigmaSwitch(*muon, nSigmaSwitch, ptThreshold);
00242 else {
00243 reco::TrackToTrackMap::const_iterator tevTkRef =
00244 trackMap->find(muon->combinedMuon());
00245 if (tevTkRef != trackMap->end())
00246 tevTk = make_pair(tevTkRef->val,reco::Muon::CombinedTrack);
00247 }
00248
00249
00250
00251
00252 if (tevTk.first.isNonnull())
00253 cands->push_back(*cloneAndSwitchTrack(*muon, tevTk));
00254 }
00255 else if (fromTrackerTrack)
00256 cands->push_back(*cloneAndSwitchTrack(*muon, make_pair(muon->innerTrack(),reco::Muon::InnerTrack)));
00257 else if (fromGlobalTrack)
00258 cands->push_back(*cloneAndSwitchTrack(*muon, make_pair(muon->globalTrack(),reco::Muon::CombinedTrack)));
00259 else {
00260 cands->push_back(*muon->clone());
00261
00262
00263
00264
00265 reco::Muon& last = cands->at(cands->size()-1);
00266 if (muon->globalTrack().isTransient())
00267 last.setGlobalTrack(muon->globalTrack());
00268 if (muon->innerTrack().isTransient())
00269 last.setInnerTrack(muon->innerTrack());
00270 if (muon->outerTrack().isTransient())
00271 last.setOuterTrack(muon->outerTrack());
00272 }
00273 }
00274 }
00275 else
00276 edm::LogWarning("MuonsFromRefitTracksProducer")
00277 << "either " << src << " or the track map(s) " << tevMuonTracks
00278 << " not present in the event; producing empty collection";
00279
00280 event.put(cands);
00281 }
00282
00283 DEFINE_FWK_MODULE(MuonsFromRefitTracksProducer);