Go to the documentation of this file.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::TrackRef 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 trackerTrack;
00043 else
00044 return fmsTrack->val;
00045 }
00046 else if (FMSok)
00047 return fmsTrack->val;
00048 else if (TKok)
00049 return trackerTrack;
00050
00051 return combinedTrack;
00052 }
00053
00054 reco::TrackRef 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 trackerTrack;
00060
00061 double delta = fabs(trackerTrack->qoverp() - combinedTrack->qoverp());
00062 double threshold = nSigma * trackerTrack->qoverpError();
00063
00064 return delta > threshold ? trackerTrack : 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::TrackRef& 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::TrackRef& 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->vx(), newTrack->vy(), newTrack->vz());
00183 reco::Particle::LorentzVector p4;
00184 double p = newTrack->p();
00185 p4.SetXYZT(newTrack->px(), newTrack->py(), newTrack->pz(),
00186 sqrt(p*p + muMass*muMass));
00187
00188 reco::Muon* mu = muon.clone();
00189 mu->setCharge(newTrack->charge());
00190 mu->setP4(p4);
00191 mu->setVertex(vtx);
00192 mu->setGlobalTrack(newTrack);
00193 mu->setInnerTrack(tkTrack);
00194 mu->setOuterTrack(muTrack);
00195 return mu;
00196 }
00197
00198 void MuonsFromRefitTracksProducer::produce(edm::Event& event, const edm::EventSetup& eSetup) {
00199
00200 edm::Handle<edm::View<reco::Muon> > muons;
00201 event.getByLabel(src, muons);
00202
00203
00204
00205
00206 bool ok = !muons.failedToGet();
00207
00208
00209
00210
00211
00212
00213 if (ok && fromTeVRefit)
00214 ok = storeMatchMaps(event);
00215
00216
00217 std::auto_ptr<reco::MuonCollection> cands(new reco::MuonCollection);
00218
00219 if (ok) {
00220 edm::View<reco::Muon>::const_iterator muon;
00221 for (muon = muons->begin(); muon != muons->end(); muon++) {
00222
00223
00224
00225 if (!muon->isGlobalMuon()) continue;
00226
00227 if (fromTeVRefit || fromSigmaSwitch) {
00228
00229 reco::TrackRef tevTk;
00230
00231
00232
00233
00234 if (fromTMR)
00235 tevTk = tevOptimizedTMR(*muon, *trackMapFirstHit, TMRcut);
00236 else if (fromCocktail)
00237 tevTk = muon::tevOptimized(*muon, *trackMapDefault, *trackMapFirstHit,
00238 *trackMapPicky);
00239 else if (fromSigmaSwitch)
00240 tevTk = sigmaSwitch(*muon, nSigmaSwitch, ptThreshold);
00241 else {
00242 reco::TrackToTrackMap::const_iterator tevTkRef =
00243 trackMap->find(muon->combinedMuon());
00244 if (tevTkRef != trackMap->end())
00245 tevTk = tevTkRef->val;
00246 }
00247
00248
00249
00250
00251 if (tevTk.isNonnull())
00252 cands->push_back(*cloneAndSwitchTrack(*muon, tevTk));
00253 }
00254 else if (fromTrackerTrack)
00255 cands->push_back(*cloneAndSwitchTrack(*muon, muon->innerTrack()));
00256 else if (fromGlobalTrack)
00257 cands->push_back(*cloneAndSwitchTrack(*muon, muon->globalTrack()));
00258 else {
00259 cands->push_back(*muon->clone());
00260
00261
00262
00263
00264 reco::Muon& last = cands->at(cands->size()-1);
00265 if (muon->globalTrack().isTransient())
00266 last.setGlobalTrack(muon->globalTrack());
00267 if (muon->innerTrack().isTransient())
00268 last.setInnerTrack(muon->innerTrack());
00269 if (muon->outerTrack().isTransient())
00270 last.setOuterTrack(muon->outerTrack());
00271 }
00272 }
00273 }
00274 else
00275 edm::LogWarning("MuonsFromRefitTracksProducer")
00276 << "either " << src << " or the track map(s) " << tevMuonTracks
00277 << " not present in the event; producing empty collection";
00278
00279 event.put(cands);
00280 }
00281
00282 DEFINE_FWK_MODULE(MuonsFromRefitTracksProducer);