Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:25:51

0001 /**  \class L3MuonCandidateProducer
0002  *
0003  *   Intermediate step in the L3 muons selection.
0004  *   This class takes the L3 muons (which are reco::Tracks)
0005  *   and creates the correspondent reco::RecoChargedCandidate.
0006  *
0007  *   Riccardo's comment:
0008  *   The separation between the L3MuonProducer and this class allows
0009  *   the interchangeability of the L3MuonProducer and the StandAloneMuonProducer
0010  *   This class is supposed to be removed once the
0011  *   L3/STA comparison will be done, then the RecoChargedCandidate
0012  *   production will be put into the L3MuonProducer class.
0013  *
0014  *
0015  *   \author  J.Alcaraz
0016  */
0017 
0018 // Framework
0019 #include "FWCore/Framework/interface/Event.h"
0020 #include "FWCore/Framework/interface/EventSetup.h"
0021 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0022 #include "DataFormats/Common/interface/Handle.h"
0023 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0024 
0025 #include "RecoMuon/L3MuonProducer/src/L3MuonCandidateProducer.h"
0026 
0027 #include "DataFormats/Math/interface/deltaR.h"
0028 
0029 // Input and output collections
0030 #include "DataFormats/RecoCandidate/interface/RecoChargedCandidate.h"
0031 #include "DataFormats/RecoCandidate/interface/RecoChargedCandidateFwd.h"
0032 
0033 #include <string>
0034 #include <algorithm>
0035 
0036 using namespace edm;
0037 using namespace std;
0038 using namespace reco;
0039 
0040 static const char category[] = "Muon|RecoMuon|L3MuonCandidateProducer";
0041 
0042 /// constructor with config
0043 L3MuonCandidateProducer::L3MuonCandidateProducer(const ParameterSet& parameterSet) {
0044   LogTrace(category) << " constructor called";
0045 
0046   // StandAlone Collection Label
0047   theL3CollectionLabel = parameterSet.getParameter<InputTag>("InputObjects");
0048   trackToken_ = consumes<reco::TrackCollection>(theL3CollectionLabel);
0049 
0050   // use links
0051   theUseLinks = parameterSet.existsAs<InputTag>("InputLinksObjects");
0052   if (theUseLinks) {
0053     theL3LinksLabel = parameterSet.getParameter<InputTag>("InputLinksObjects");
0054     linkToken_ = consumes<reco::MuonTrackLinksCollection>(theL3LinksLabel);
0055     if (theL3LinksLabel.label().empty() or theL3LinksLabel.label() == "unused")
0056       theUseLinks = false;
0057   }
0058 
0059   // use global, standalone or tracker pT/4-vector assignment
0060   const std::string& muon_track_for_momentum = parameterSet.existsAs<std::string>("MuonPtOption")
0061                                                    ? parameterSet.getParameter<std::string>("MuonPtOption")
0062                                                    : "Global";
0063   if (muon_track_for_momentum == std::string("Tracker"))
0064     theType = InnerTrack;
0065   else if (muon_track_for_momentum == std::string("Standalone"))
0066     theType = OuterTrack;
0067   else if (muon_track_for_momentum == std::string("Global"))
0068     theType = CombinedTrack;
0069   else {
0070     LogError(category) << "invalid value for MuonPtOption, please choose among 'Tracker', 'Standalone', 'Global'";
0071     theType = CombinedTrack;
0072   }
0073 
0074   produces<RecoChargedCandidateCollection>();
0075 }
0076 
0077 /// destructor
0078 L3MuonCandidateProducer::~L3MuonCandidateProducer() {
0079   LogTrace(category) << " L3MuonCandidateProducer destructor called";
0080 }
0081 
0082 /// reconstruct muons
0083 void L3MuonCandidateProducer::produce(StreamID, Event& event, const EventSetup& eventSetup) const {
0084   // Take the L3 container
0085   LogTrace(category) << " Taking the L3/GLB muons: " << theL3CollectionLabel.label();
0086   Handle<TrackCollection> tracks;
0087   event.getByToken(trackToken_, tracks);
0088 
0089   edm::Handle<reco::MuonTrackLinksCollection> links;
0090   if (theUseLinks)
0091     event.getByToken(linkToken_, links);
0092 
0093   // Create a RecoChargedCandidate collection
0094   LogTrace(category) << " Creating the RecoChargedCandidate collection";
0095   auto candidates = std::make_unique<RecoChargedCandidateCollection>();
0096   LogDebug(category) << " size = " << tracks->size();
0097   for (unsigned int i = 0; i < tracks->size(); i++) {
0098     TrackRef inRef(tracks, i);
0099     TrackRef tkRef = TrackRef();
0100 
0101     if (theUseLinks) {
0102       for (reco::MuonTrackLinksCollection::const_iterator link = links->begin(); link != links->end(); ++link) {
0103         LogDebug(category) << " i = " << i;
0104 
0105         if (not link->trackerTrack().isNull())
0106           LogTrace(category) << " link tk pt " << link->trackerTrack()->pt();
0107         if (not link->standAloneTrack().isNull())
0108           LogTrace(category) << " sta pt " << link->standAloneTrack()->pt();
0109         if (not link->globalTrack().isNull())
0110           LogTrace(category) << " global pt " << link->globalTrack()->pt();
0111         if (not inRef.isNull())
0112           LogTrace(category) << " inRef pt " << inRef->pt();
0113 
0114         if (link->globalTrack().isNull()) {
0115           edm::LogError(category) << "null reference to the global track";
0116           // skip this candidate
0117           continue;
0118         }
0119 
0120         float dR = deltaR(inRef->eta(), inRef->phi(), link->globalTrack()->eta(), link->globalTrack()->phi());
0121         float dPt = abs(inRef->pt() - link->globalTrack()->pt()) / inRef->pt();
0122         if (dR < 0.02 and dPt < 0.001) {
0123           LogTrace(category) << " *** pt matches *** ";
0124           switch (theType) {
0125             case InnerTrack:
0126               tkRef = link->trackerTrack();
0127               break;
0128             case OuterTrack:
0129               tkRef = link->standAloneTrack();
0130               break;
0131             case CombinedTrack:
0132               tkRef = link->globalTrack();
0133               break;
0134             default:
0135               tkRef = link->globalTrack();
0136               break;
0137           }
0138         }
0139       }
0140       if (tkRef.isNull()) {
0141         edm::LogWarning(category) << "null reference to the linked track, reverting to old behaviour";
0142         tkRef = inRef;
0143       }
0144     } else {
0145       // theUseLinks is false
0146       tkRef = inRef;
0147     }
0148     LogDebug(category) << "tkRef Used For Momentum pt " << tkRef->pt() << " inRef from the input collection pt "
0149                        << inRef->pt();
0150 
0151     Particle::Charge q = tkRef->charge();
0152     Particle::LorentzVector p4(tkRef->px(), tkRef->py(), tkRef->pz(), tkRef->p());
0153     Particle::Point vtx(tkRef->vx(), tkRef->vy(), tkRef->vz());
0154 
0155     int pid = 13;
0156     if (abs(q) == 1)
0157       pid = q < 0 ? 13 : -13;
0158     else
0159       LogWarning(category) << "L3MuonCandidate has charge = " << q;
0160     RecoChargedCandidate cand(q, p4, vtx, pid);
0161 
0162     //set the inRef as the RecoChargedCandidate ref so that the isolation maps
0163     //work in downstream filters
0164     cand.setTrack(inRef);
0165     candidates->push_back(cand);
0166   }
0167 
0168   event.put(std::move(candidates));
0169 
0170   LogTrace(category) << " Event loaded"
0171                      << "================================";
0172 }