File indexing completed on 2023-03-17 11:20:33
0001
0002
0003
0004
0005
0006
0007
0008 #include "FWCore/Framework/interface/Frameworkfwd.h"
0009 #include "FWCore/Framework/interface/stream/EDProducer.h"
0010 #include "FWCore/Framework/interface/Event.h"
0011 #include "FWCore/Framework/interface/MakerMacros.h"
0012 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0013
0014 #include "DataFormats/MuonReco/interface/Muon.h"
0015 #include "DataFormats/MuonReco/interface/MuonFwd.h"
0016 #include "DataFormats/MuonReco/interface/MuonCocktails.h"
0017 #include "DataFormats/TrackReco/interface/Track.h"
0018 #include "DataFormats/TrackReco/interface/TrackFwd.h"
0019 #include "DataFormats/TrackReco/interface/TrackToTrackMap.h"
0020
0021 reco::Muon::MuonTrackTypePair tevOptimizedTMR(const reco::Muon& muon,
0022 const reco::TrackToTrackMap& fmsMap,
0023 const double cut) {
0024 const reco::TrackRef& combinedTrack = muon.globalTrack();
0025 const reco::TrackRef& trackerTrack = muon.innerTrack();
0026
0027 reco::TrackToTrackMap::const_iterator fmsTrack = fmsMap.find(combinedTrack);
0028
0029 double probTK = 0;
0030 double probFMS = 0;
0031
0032 if (trackerTrack.isAvailable() && trackerTrack->numberOfValidHits())
0033 probTK = muon::trackProbability(trackerTrack);
0034 if (fmsTrack != fmsMap.end() && fmsTrack->val->numberOfValidHits())
0035 probFMS = muon::trackProbability(fmsTrack->val);
0036
0037 bool TKok = probTK > 0;
0038 bool FMSok = probFMS > 0;
0039
0040 if (TKok && FMSok) {
0041 if (probFMS - probTK > cut)
0042 return make_pair(trackerTrack, reco::Muon::InnerTrack);
0043 else
0044 return make_pair(fmsTrack->val, reco::Muon::TPFMS);
0045 } else if (FMSok)
0046 return make_pair(fmsTrack->val, reco::Muon::TPFMS);
0047 else if (TKok)
0048 return make_pair(trackerTrack, reco::Muon::InnerTrack);
0049
0050 return make_pair(combinedTrack, reco::Muon::CombinedTrack);
0051 }
0052
0053 reco::Muon::MuonTrackTypePair sigmaSwitch(const reco::Muon& muon, const double nSigma, const double ptThreshold) {
0054 const reco::TrackRef& combinedTrack = muon.globalTrack();
0055 const reco::TrackRef& trackerTrack = muon.innerTrack();
0056
0057 if (combinedTrack->pt() < ptThreshold || trackerTrack->pt() < ptThreshold)
0058 return make_pair(trackerTrack, reco::Muon::InnerTrack);
0059
0060 double delta = fabs(trackerTrack->qoverp() - combinedTrack->qoverp());
0061 double threshold = nSigma * trackerTrack->qoverpError();
0062
0063 return delta > threshold ? make_pair(trackerTrack, reco::Muon::InnerTrack)
0064 : make_pair(combinedTrack, reco::Muon::CombinedTrack);
0065 }
0066
0067 class MuonsFromRefitTracksProducer : public edm::stream::EDProducer<> {
0068 public:
0069 explicit MuonsFromRefitTracksProducer(const edm::ParameterSet&);
0070 ~MuonsFromRefitTracksProducer() override {}
0071
0072 private:
0073 void produce(edm::Event&, const edm::EventSetup&) override;
0074
0075
0076 bool storeMatchMaps(const edm::Event& event);
0077
0078
0079
0080
0081 reco::Muon* cloneAndSwitchTrack(const reco::Muon& muon, const reco::Muon::MuonTrackTypePair& newTrack) const;
0082
0083
0084 edm::InputTag src;
0085
0086
0087
0088
0089
0090 bool fromTrackerTrack;
0091
0092
0093
0094
0095
0096 bool fromGlobalTrack;
0097
0098
0099
0100 bool fromTeVRefit;
0101
0102
0103
0104
0105 std::string tevMuonTracks;
0106
0107
0108
0109
0110 bool fromCocktail;
0111
0112
0113
0114 bool fromTMR;
0115
0116
0117 double TMRcut;
0118
0119
0120
0121 bool fromSigmaSwitch;
0122
0123
0124 double nSigmaSwitch;
0125
0126
0127 double ptThreshold;
0128
0129
0130
0131
0132 edm::Handle<reco::TrackToTrackMap> trackMap;
0133
0134
0135 edm::Handle<reco::TrackToTrackMap> trackMapDefault;
0136 edm::Handle<reco::TrackToTrackMap> trackMapFirstHit;
0137 edm::Handle<reco::TrackToTrackMap> trackMapPicky;
0138
0139
0140 edm::EDGetTokenT<edm::View<reco::Muon> > srcToken_;
0141 edm::EDGetTokenT<reco::TrackToTrackMap> trackMapToken_;
0142 edm::EDGetTokenT<reco::TrackToTrackMap> trackMapDefaultToken_;
0143 edm::EDGetTokenT<reco::TrackToTrackMap> trackMapFirstHitToken_;
0144 edm::EDGetTokenT<reco::TrackToTrackMap> trackMapPickyToken_;
0145 };
0146
0147 MuonsFromRefitTracksProducer::MuonsFromRefitTracksProducer(const edm::ParameterSet& cfg)
0148 : src(cfg.getParameter<edm::InputTag>("src")),
0149 fromTrackerTrack(cfg.getParameter<bool>("fromTrackerTrack")),
0150 fromGlobalTrack(cfg.getParameter<bool>("fromGlobalTrack")),
0151 tevMuonTracks(cfg.getParameter<std::string>("tevMuonTracks")),
0152 fromCocktail(cfg.getParameter<bool>("fromCocktail")),
0153 fromTMR(cfg.getParameter<bool>("fromTMR")),
0154 TMRcut(cfg.getParameter<double>("TMRcut")),
0155 fromSigmaSwitch(cfg.getParameter<bool>("fromSigmaSwitch")),
0156 nSigmaSwitch(cfg.getParameter<double>("nSigmaSwitch")),
0157 ptThreshold(cfg.getParameter<double>("ptThreshold")) {
0158 fromTeVRefit = tevMuonTracks != "none";
0159
0160 srcToken_ = consumes<edm::View<reco::Muon> >(src);
0161 trackMapToken_ = consumes<reco::TrackToTrackMap>(edm::InputTag(tevMuonTracks, "default"));
0162 trackMapDefaultToken_ = consumes<reco::TrackToTrackMap>(edm::InputTag(tevMuonTracks));
0163 trackMapFirstHitToken_ = consumes<reco::TrackToTrackMap>(edm::InputTag(tevMuonTracks, "firstHit"));
0164 trackMapPickyToken_ = consumes<reco::TrackToTrackMap>(edm::InputTag(tevMuonTracks, "picky"));
0165
0166 produces<reco::MuonCollection>();
0167 }
0168
0169 bool MuonsFromRefitTracksProducer::storeMatchMaps(const edm::Event& event) {
0170 if (fromCocktail || fromTMR) {
0171 event.getByToken(trackMapDefaultToken_, trackMapDefault);
0172 event.getByToken(trackMapFirstHitToken_, trackMapFirstHit);
0173 event.getByToken(trackMapPickyToken_, trackMapPicky);
0174 return !trackMapDefault.failedToGet() && !trackMapFirstHit.failedToGet() && !trackMapPicky.failedToGet();
0175 } else {
0176 event.getByToken(trackMapToken_, trackMap);
0177 return !trackMap.failedToGet();
0178 }
0179 }
0180
0181 reco::Muon* MuonsFromRefitTracksProducer::cloneAndSwitchTrack(const reco::Muon& muon,
0182 const reco::Muon::MuonTrackTypePair& newTrack) const {
0183
0184 static const double muMass = 0.10566;
0185
0186 reco::TrackRef tkTrack = muon.innerTrack();
0187 reco::TrackRef muTrack = muon.outerTrack();
0188
0189
0190 reco::Particle::Point vtx(newTrack.first->vx(), newTrack.first->vy(), newTrack.first->vz());
0191 reco::Particle::LorentzVector p4;
0192 double p = newTrack.first->p();
0193 p4.SetXYZT(newTrack.first->px(), newTrack.first->py(), newTrack.first->pz(), sqrt(p * p + muMass * muMass));
0194
0195 reco::Muon* mu = muon.clone();
0196 mu->setCharge(newTrack.first->charge());
0197 mu->setP4(p4);
0198 mu->setVertex(vtx);
0199 mu->setGlobalTrack(newTrack.first);
0200 mu->setInnerTrack(tkTrack);
0201 mu->setOuterTrack(muTrack);
0202 mu->setBestTrack(newTrack.second);
0203 return mu;
0204 }
0205
0206 void MuonsFromRefitTracksProducer::produce(edm::Event& event, const edm::EventSetup& eSetup) {
0207
0208 edm::Handle<edm::View<reco::Muon> > muons;
0209 event.getByToken(srcToken_, muons);
0210
0211
0212
0213
0214 bool ok = !muons.failedToGet();
0215
0216
0217
0218
0219
0220
0221 if (ok && fromTeVRefit)
0222 ok = storeMatchMaps(event);
0223
0224
0225 auto cands = std::make_unique<reco::MuonCollection>();
0226
0227 if (ok) {
0228 edm::View<reco::Muon>::const_iterator muon;
0229 for (muon = muons->begin(); muon != muons->end(); muon++) {
0230
0231
0232
0233 if (!muon->isGlobalMuon())
0234 continue;
0235
0236 if (fromTeVRefit || fromSigmaSwitch) {
0237
0238 reco::Muon::MuonTrackTypePair tevTk;
0239
0240
0241
0242
0243 if (fromTMR)
0244 tevTk = tevOptimizedTMR(*muon, *trackMapFirstHit, TMRcut);
0245 else if (fromCocktail)
0246 tevTk = muon::tevOptimized(*muon);
0247 else if (fromSigmaSwitch)
0248 tevTk = sigmaSwitch(*muon, nSigmaSwitch, ptThreshold);
0249 else {
0250 reco::TrackToTrackMap::const_iterator tevTkRef = trackMap->find(muon->combinedMuon());
0251 if (tevTkRef != trackMap->end())
0252 tevTk = make_pair(tevTkRef->val, reco::Muon::CombinedTrack);
0253 }
0254
0255
0256
0257
0258 if (tevTk.first.isNonnull())
0259 cands->push_back(*cloneAndSwitchTrack(*muon, tevTk));
0260 } else if (fromTrackerTrack)
0261 cands->push_back(*cloneAndSwitchTrack(*muon, make_pair(muon->innerTrack(), reco::Muon::InnerTrack)));
0262 else if (fromGlobalTrack)
0263 cands->push_back(*cloneAndSwitchTrack(*muon, make_pair(muon->globalTrack(), reco::Muon::CombinedTrack)));
0264 else {
0265 cands->push_back(*muon->clone());
0266
0267
0268
0269
0270 reco::Muon& last = cands->at(cands->size() - 1);
0271 if (muon->globalTrack().isTransient())
0272 last.setGlobalTrack(muon->globalTrack());
0273 if (muon->innerTrack().isTransient())
0274 last.setInnerTrack(muon->innerTrack());
0275 if (muon->outerTrack().isTransient())
0276 last.setOuterTrack(muon->outerTrack());
0277 }
0278 }
0279 } else
0280 edm::LogWarning("MuonsFromRefitTracksProducer") << "either " << src << " or the track map(s) " << tevMuonTracks
0281 << " not present in the event; producing empty collection";
0282
0283 event.put(std::move(cands));
0284 }
0285
0286 DEFINE_FWK_MODULE(MuonsFromRefitTracksProducer);