Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:26:59

0001 /**
0002  *  Class: L3MuonTrajectoryBuilder
0003  *
0004  *  Description:
0005  *   Reconstruct muons starting
0006  *   from a muon track reconstructed
0007  *   in the standalone muon system (with DT, CSC and RPC
0008  *   information).
0009  *   It tries to reconstruct the corresponding
0010  *   track in the tracker and performs
0011  *   matching between the reconstructed tracks
0012  *   in the muon system and the tracker.
0013  *
0014  *
0015  *  Authors :
0016  *  N. Neumeister            Purdue University
0017  *  C. Liu                   Purdue University
0018  *  A. Everett               Purdue University
0019  *  with contributions from: S. Lacaprara, J. Mumford, P. Traczyk
0020  *
0021  **/
0022 
0023 #include "RecoMuon/L3TrackFinder/interface/L3MuonTrajectoryBuilder.h"
0024 
0025 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0026 #include "FWCore/Framework/interface/Event.h"
0027 
0028 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0029 
0030 #include "DataFormats/MuonSeed/interface/L3MuonTrajectorySeed.h"
0031 #include "DataFormats/MuonSeed/interface/L3MuonTrajectorySeedCollection.h"
0032 
0033 #include "RecoMuon/TrackingTools/interface/MuonCandidate.h"
0034 #include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h"
0035 #include "RecoMuon/GlobalTrackingTools/interface/GlobalMuonTrackMatcher.h"
0036 
0037 #include "FWCore/ServiceRegistry/interface/Service.h"
0038 
0039 #include "RecoTracker/Record/interface/CkfComponentsRecord.h"
0040 #include "RecoTracker/Record/interface/NavigationSchoolRecord.h"
0041 
0042 #include "RecoTracker/TkTrackingRegions/interface/RectangularEtaPhiTrackingRegion.h"
0043 #include "TrackingTools/TrajectoryCleaning/interface/TrajectoryCleanerBySharedHits.h"
0044 
0045 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
0046 #include "DataFormats/VertexReco/interface/Vertex.h"
0047 #include "DataFormats/VertexReco/interface/VertexFwd.h"
0048 #include "RecoMuon/GlobalTrackingTools/interface/MuonTrackingRegionBuilder.h"
0049 
0050 //----------------
0051 // Constructors --
0052 //----------------
0053 L3MuonTrajectoryBuilder::L3MuonTrajectoryBuilder(const edm::ParameterSet& par,
0054                                                  const MuonServiceProxy* service,
0055                                                  edm::ConsumesCollector& iC)
0056     : GlobalTrajectoryBuilderBase(par, service, iC) {
0057   theTrajectoryCleaner = std::make_unique<TrajectoryCleanerBySharedHits>();
0058   theTkCollName = par.getParameter<edm::InputTag>("tkTrajLabel");
0059   theBeamSpotInputTag = par.getParameter<edm::InputTag>("tkTrajBeamSpot");
0060   theMaxChi2 = par.getParameter<double>("tkTrajMaxChi2");
0061   theDXYBeamSpot = par.getParameter<double>("tkTrajMaxDXYBeamSpot");
0062   theUseVertex = par.getParameter<bool>("tkTrajUseVertex");
0063   theVertexCollInputTag = par.getParameter<edm::InputTag>("tkTrajVertex");
0064   theTrackToken = iC.consumes<reco::TrackCollection>(theTkCollName);
0065 }
0066 
0067 //--------------
0068 // Destructor --
0069 //--------------
0070 L3MuonTrajectoryBuilder::~L3MuonTrajectoryBuilder() {}
0071 
0072 void L3MuonTrajectoryBuilder::fillDescriptions(edm::ParameterSetDescription& desc) {
0073   edm::ParameterSetDescription descTRB;
0074   MuonTrackingRegionBuilder::fillDescriptionsHLT(descTRB);
0075   desc.add("MuonTrackingRegionBuilder", descTRB);
0076 }
0077 
0078 //
0079 // Get information from event
0080 //
0081 void L3MuonTrajectoryBuilder::setEvent(const edm::Event& event) {
0082   const std::string category = "Muon|RecoMuon|L3MuonTrajectoryBuilder|setEvent";
0083 
0084   GlobalTrajectoryBuilderBase::setEvent(event);
0085 
0086   // get tracker TrackCollection from Event
0087   event.getByToken(theTrackToken, allTrackerTracks);
0088   LogDebug(category) << "Found " << allTrackerTracks->size() << " tracker Tracks with label " << theTkCollName;
0089 
0090   if (theUseVertex) {
0091     // PV
0092     edm::Handle<reco::VertexCollection> pvHandle;
0093     if (pvHandle.isValid()) {
0094       vtx = pvHandle->front();
0095     } else {
0096       edm::LogInfo(category) << "No Primary Vertex available from EventSetup \n";
0097     }
0098   } else {
0099     // BS
0100     event.getByLabel(theBeamSpotInputTag, beamSpotHandle);
0101     if (beamSpotHandle.isValid()) {
0102       beamSpot = *beamSpotHandle;
0103     } else {
0104       edm::LogInfo(category) << "No beam spot available from EventSetup \n";
0105     }
0106   }
0107 }
0108 
0109 //
0110 // reconstruct trajectories
0111 //
0112 MuonCandidate::CandidateContainer L3MuonTrajectoryBuilder::trajectories(const TrackCand& staCandIn) {
0113   const std::string category = "Muon|RecoMuon|L3MuonTrajectoryBuilder|trajectories";
0114 
0115   // cut on muons with low momenta
0116   if ((staCandIn).second->pt() < thePtCut || (staCandIn).second->innerMomentum().Rho() < thePtCut ||
0117       (staCandIn).second->innerMomentum().R() < 2.5)
0118     return CandidateContainer();
0119 
0120   // convert the STA track into a Trajectory if Trajectory not already present
0121   TrackCand staCand(staCandIn);
0122 
0123   std::vector<TrackCand> regionalTkTracks = makeTkCandCollection(staCand);
0124   LogDebug(category) << "Found " << regionalTkTracks.size() << " tracks within region of interest";
0125 
0126   // match tracker tracks to muon track
0127   std::vector<TrackCand> trackerTracks = trackMatcher()->match(staCand, regionalTkTracks);
0128 
0129   LogDebug(category) << "Found " << trackerTracks.size() << " matching tracker tracks within region of interest";
0130   if (trackerTracks.empty())
0131     return CandidateContainer();
0132 
0133   // build a combined tracker-muon MuonCandidate
0134   // turn tkMatchedTracks into MuonCandidates
0135   LogDebug(category) << "turn tkMatchedTracks into MuonCandidates";
0136   CandidateContainer tkTrajs;
0137   tkTrajs.reserve(trackerTracks.size());
0138   for (std::vector<TrackCand>::const_iterator tkt = trackerTracks.begin(); tkt != trackerTracks.end(); tkt++) {
0139     if ((*tkt).first != nullptr && (*tkt).first->isValid()) {
0140       tkTrajs.emplace_back(std::make_unique<MuonCandidate>(
0141           nullptr, staCand.second, (*tkt).second, std::make_unique<Trajectory>(*(*tkt).first)));
0142     } else {
0143       tkTrajs.emplace_back(std::make_unique<MuonCandidate>(nullptr, staCand.second, (*tkt).second, nullptr));
0144     }
0145   }
0146 
0147   if (tkTrajs.empty()) {
0148     LogDebug(category) << "tkTrajs empty";
0149     return CandidateContainer();
0150   }
0151 
0152   CandidateContainer result = build(staCand, tkTrajs);
0153   LogDebug(category) << "Found " << result.size() << " L3Muons from one L2Cand";
0154 
0155   // free memory
0156   if (staCandIn.first == nullptr)
0157     delete staCand.first;
0158 
0159   for (std::vector<TrackCand>::const_iterator is = regionalTkTracks.begin(); is != regionalTkTracks.end(); ++is) {
0160     delete (*is).first;
0161   }
0162 
0163   return result;
0164 }
0165 
0166 //
0167 // make a TrackCand collection using tracker Track, Trajectory information
0168 //
0169 std::vector<L3MuonTrajectoryBuilder::TrackCand> L3MuonTrajectoryBuilder::makeTkCandCollection(const TrackCand& staCand) {
0170   const std::string category = "Muon|RecoMuon|L3MuonTrajectoryBuilder|makeTkCandCollection";
0171   std::vector<TrackCand> tkCandColl;
0172   std::vector<TrackCand> tkTrackCands;
0173 
0174   //  for (auto&& tkTrack: allTrackerTracks){
0175   //    auto tkCand = TrackCand((Trajectory*)(0),tkTrack);
0176   for (unsigned int position = 0; position != allTrackerTracks->size(); ++position) {
0177     reco::TrackRef tkTrackRef(allTrackerTracks, position);
0178     TrackCand tkCand = TrackCand((Trajectory*)nullptr, tkTrackRef);
0179     tkCandColl.push_back(tkCand);
0180   }
0181 
0182   //Loop over TrackCand collection made from allTrackerTracks in previous step
0183   for (auto&& tkCand : tkCandColl) {
0184     auto& tk = tkCand.second;
0185     bool canUseL3MTS = false;
0186     // check the seedRef is non-null first; and then
0187     if (tk->seedRef().isNonnull()) {
0188       auto a = dynamic_cast<const L3MuonTrajectorySeed*>(tk->seedRef().get());
0189       canUseL3MTS = a != nullptr;
0190     }
0191     if (canUseL3MTS) {
0192       edm::Ref<L3MuonTrajectorySeedCollection> l3seedRef =
0193           tk->seedRef().castTo<edm::Ref<L3MuonTrajectorySeedCollection> >();
0194       // May still need provenance here, so using trackref:
0195       reco::TrackRef staTrack = l3seedRef->l2Track();
0196       if (staTrack == (staCand.second)) {
0197         // Apply filters (dxy, chi2 cut)
0198         double tk_vtx;
0199         if (theUseVertex)
0200           tk_vtx = tk->dxy(vtx.position());
0201         else
0202           tk_vtx = tk->dxy(beamSpot.position());
0203         if (fabs(tk_vtx) > theDXYBeamSpot || tk->normalizedChi2() > theMaxChi2)
0204           continue;
0205         tkTrackCands.push_back(tkCand);
0206       }
0207     } else {
0208       // We will try to match all tracker tracks with the muon:
0209       double tk_vtx;
0210       if (theUseVertex)
0211         tk_vtx = tk->dxy(vtx.position());
0212       else
0213         tk_vtx = tk->dxy(beamSpot.position());
0214       if (fabs(tk_vtx) > theDXYBeamSpot || tk->normalizedChi2() > theMaxChi2)
0215         continue;
0216       tkTrackCands.push_back(tkCand);
0217     }
0218   }
0219 
0220   return tkTrackCands;
0221 }