Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-01-09 23:33:53

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/plugins/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   theL3LinksLabel = parameterSet.getParameter<InputTag>("InputLinksObjects");
0052   theUseLinks = !theL3LinksLabel.label().empty() && theL3LinksLabel.label() != "unused";
0053   if (theUseLinks) {
0054     linkToken_ = consumes<reco::MuonTrackLinksCollection>(theL3LinksLabel);
0055   }
0056 
0057   // Use global, standalone or tracker pT/4-vector assignment
0058   const std::string& muon_track_for_momentum = parameterSet.getParameter<std::string>("MuonPtOption");
0059   if (muon_track_for_momentum == "Tracker")
0060     theType = InnerTrack;
0061   else if (muon_track_for_momentum == "Standalone")
0062     theType = OuterTrack;
0063   else if (muon_track_for_momentum == "Global")
0064     theType = CombinedTrack;
0065   else {
0066     LogError(category) << "Invalid value for MuonPtOption, please choose among 'Tracker', 'Standalone', 'Global'";
0067     theType = CombinedTrack;
0068   }
0069 
0070   produces<RecoChargedCandidateCollection>();
0071 }
0072 
0073 /// fillDescriptions
0074 void L3MuonCandidateProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0075   edm::ParameterSetDescription desc;
0076   desc.add<InputTag>("InputObjects", edm::InputTag("L3Muons"))->setComment("Input tag for L3 muon tracks");
0077   desc.add<InputTag>("InputLinksObjects", edm::InputTag("unused"))->setComment("Input tag for track links");
0078   desc.add<std::string>("MuonPtOption", "Global")
0079       ->setComment("Option to determine muon momentum: 'Tracker', 'Standalone', or 'Global'");
0080   descriptions.addWithDefaultLabel(desc);
0081 }
0082 
0083 /// destructor
0084 L3MuonCandidateProducer::~L3MuonCandidateProducer() {
0085   LogTrace(category) << " L3MuonCandidateProducer destructor called";
0086 }
0087 
0088 /// reconstruct muons
0089 void L3MuonCandidateProducer::produce(StreamID, Event& event, const EventSetup& eventSetup) const {
0090   // Take the L3 container
0091   LogTrace(category) << " Taking the L3/GLB muons: " << theL3CollectionLabel.label();
0092   Handle<TrackCollection> tracks;
0093   event.getByToken(trackToken_, tracks);
0094 
0095   edm::Handle<reco::MuonTrackLinksCollection> links;
0096   if (theUseLinks)
0097     event.getByToken(linkToken_, links);
0098 
0099   // Create a RecoChargedCandidate collection
0100   LogTrace(category) << " Creating the RecoChargedCandidate collection";
0101   auto candidates = std::make_unique<RecoChargedCandidateCollection>();
0102   LogDebug(category) << " size = " << tracks->size();
0103   for (unsigned int i = 0; i < tracks->size(); i++) {
0104     TrackRef inRef(tracks, i);
0105     TrackRef tkRef = TrackRef();
0106 
0107     if (theUseLinks) {
0108       for (reco::MuonTrackLinksCollection::const_iterator link = links->begin(); link != links->end(); ++link) {
0109         LogDebug(category) << " i = " << i;
0110 
0111         if (not link->trackerTrack().isNull())
0112           LogTrace(category) << " link tk pt " << link->trackerTrack()->pt();
0113         if (not link->standAloneTrack().isNull())
0114           LogTrace(category) << " sta pt " << link->standAloneTrack()->pt();
0115         if (not link->globalTrack().isNull())
0116           LogTrace(category) << " global pt " << link->globalTrack()->pt();
0117         if (not inRef.isNull())
0118           LogTrace(category) << " inRef pt " << inRef->pt();
0119 
0120         if (link->globalTrack().isNull()) {
0121           edm::LogError(category) << "null reference to the global track";
0122           // skip this candidate
0123           continue;
0124         }
0125 
0126         float dR = deltaR(inRef->eta(), inRef->phi(), link->globalTrack()->eta(), link->globalTrack()->phi());
0127         float dPt = abs(inRef->pt() - link->globalTrack()->pt()) / inRef->pt();
0128         if (dR < 0.02 and dPt < 0.001) {
0129           LogTrace(category) << " *** pt matches *** ";
0130           switch (theType) {
0131             case InnerTrack:
0132               tkRef = link->trackerTrack();
0133               break;
0134             case OuterTrack:
0135               tkRef = link->standAloneTrack();
0136               break;
0137             case CombinedTrack:
0138               tkRef = link->globalTrack();
0139               break;
0140             default:
0141               tkRef = link->globalTrack();
0142               break;
0143           }
0144         }
0145       }
0146       if (tkRef.isNull()) {
0147         edm::LogWarning(category) << "null reference to the linked track, reverting to old behaviour";
0148         tkRef = inRef;
0149       }
0150     } else {
0151       // theUseLinks is false
0152       tkRef = inRef;
0153     }
0154     LogDebug(category) << "tkRef Used For Momentum pt " << tkRef->pt() << " inRef from the input collection pt "
0155                        << inRef->pt();
0156 
0157     Particle::Charge q = tkRef->charge();
0158     Particle::LorentzVector p4(tkRef->px(), tkRef->py(), tkRef->pz(), tkRef->p());
0159     Particle::Point vtx(tkRef->vx(), tkRef->vy(), tkRef->vz());
0160 
0161     int pid = 13;
0162     if (abs(q) == 1)
0163       pid = q < 0 ? 13 : -13;
0164     else
0165       LogWarning(category) << "L3MuonCandidate has charge = " << q;
0166     RecoChargedCandidate cand(q, p4, vtx, pid);
0167 
0168     //set the inRef as the RecoChargedCandidate ref so that the isolation maps
0169     //work in downstream filters
0170     cand.setTrack(inRef);
0171     candidates->push_back(cand);
0172   }
0173 
0174   event.put(std::move(candidates));
0175 
0176   LogTrace(category) << " Event loaded"
0177                      << "================================";
0178 }
0179 
0180 #include "FWCore/Framework/interface/MakerMacros.h"
0181 DEFINE_FWK_MODULE(L3MuonCandidateProducer);