Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #include "RecoMuon/L3MuonProducer/src/QuarkoniaTrackSelector.h"
0002 
0003 #include "FWCore/Framework/interface/Frameworkfwd.h"
0004 
0005 #include "FWCore/Framework/interface/Event.h"
0006 #include "FWCore/Framework/interface/MakerMacros.h"
0007 #include "DataFormats/Common/interface/Handle.h"
0008 
0009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0010 #include "FWCore/MessageLogger/interface/MessageDrop.h"
0011 
0012 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0013 
0014 #include <memory>
0015 #include <iostream>
0016 #include <sstream>
0017 
0018 QuarkoniaTrackSelector::QuarkoniaTrackSelector(const edm::ParameterSet& iConfig)
0019     : muonTag_(iConfig.getParameter<edm::InputTag>("muonCandidates")),
0020       trackTag_(iConfig.getParameter<edm::InputTag>("tracks")),
0021       minMasses_(iConfig.getParameter<std::vector<double> >("MinMasses")),
0022       maxMasses_(iConfig.getParameter<std::vector<double> >("MaxMasses")),
0023       checkCharge_(iConfig.getParameter<bool>("checkCharge")),
0024       minTrackPt_(iConfig.getParameter<double>("MinTrackPt")),
0025       minTrackP_(iConfig.getParameter<double>("MinTrackP")),
0026       maxTrackEta_(iConfig.getParameter<double>("MaxTrackEta")) {
0027   muonToken_ = consumes<reco::RecoChargedCandidateCollection>(muonTag_);
0028   trackToken_ = consumes<reco::TrackCollection>(trackTag_);
0029 
0030   //register your products
0031   produces<reco::TrackCollection>();
0032   //
0033   // verify mass windows
0034   //
0035   bool massesValid = minMasses_.size() == maxMasses_.size();
0036   if (massesValid) {
0037     for (size_t i = 0; i < minMasses_.size(); ++i) {
0038       if (minMasses_[i] < 0 || maxMasses_[i] < 0 || minMasses_[i] > maxMasses_[i])
0039         massesValid = false;
0040     }
0041   }
0042   if (!massesValid) {
0043     edm::LogError("QuarkoniaTrackSelector") << "Inconsistency in definition of mass windows, "
0044                                             << "no track will be selected";
0045     minMasses_.clear();
0046     maxMasses_.clear();
0047   }
0048 
0049   std::ostringstream stream;
0050   stream << "instantiated with parameters\n"
0051          << "  muonTag  = " << muonTag_ << "\n"
0052          << "  trackTag = " << trackTag_ << "\n";
0053   stream << "  mass windows =";
0054   for (size_t i = 0; i < minMasses_.size(); ++i)
0055     stream << " (" << minMasses_[i] << "," << maxMasses_[i] << ")";
0056   stream << "\n";
0057   stream << "  checkCharge  = " << checkCharge_ << "\n";
0058   stream << "  MinTrackPt = " << minTrackPt_ << "\n";
0059   stream << "  MinTrackP = " << minTrackP_ << "\n";
0060   stream << "  MaxTrackEta = " << maxTrackEta_;
0061   LogDebug("QuarkoniaTrackSelector") << stream.str();
0062 }
0063 
0064 void QuarkoniaTrackSelector::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const {
0065   //
0066   // the product
0067   //
0068   auto product = std::make_unique<reco::TrackCollection>();
0069   //
0070   // Muons
0071   //
0072   edm::Handle<reco::RecoChargedCandidateCollection> muonHandle;
0073   iEvent.getByToken(muonToken_, muonHandle);
0074   //
0075   // Tracks
0076   //
0077   edm::Handle<reco::TrackCollection> trackHandle;
0078   iEvent.getByToken(trackToken_, trackHandle);
0079   //
0080   // Verification
0081   //
0082   if (!muonHandle.isValid() || !trackHandle.isValid() || minMasses_.empty()) {
0083     iEvent.put(std::move(product));
0084     return;
0085   }
0086   //
0087   // Debug output
0088   //
0089   if (edm::isDebugEnabled()) {
0090     std::ostringstream stream;
0091     stream << "\nInput muons: # / q / pt / p / eta\n";
0092     for (size_t im = 0; im < muonHandle->size(); ++im) {
0093       const reco::RecoChargedCandidate& muon = (*muonHandle)[im];
0094       stream << "   " << im << " " << muon.charge() << " " << muon.pt() << " " << muon.p() << " " << muon.eta() << "\n";
0095     }
0096     stream << "Input tracks: # / q / pt / p / eta\n";
0097     for (size_t it = 0; it < trackHandle->size(); ++it) {
0098       const reco::Track& track = (*trackHandle)[it];
0099       stream << "   " << it << " " << track.charge() << " " << track.pt() << " " << track.p() << " " << track.eta()
0100              << "\n";
0101     }
0102     LogDebug("QuarkoniaTrackSelector") << stream.str();
0103   }
0104   //
0105   // combinations
0106   //
0107   //   std::ostringstream stream;
0108   unsigned int nQ(0);
0109   unsigned int nComb(0);
0110   std::vector<size_t> selectedTrackIndices;
0111   selectedTrackIndices.reserve(muonHandle->size());
0112   reco::Particle::LorentzVector p4Muon;
0113   reco::Particle::LorentzVector p4JPsi;
0114   // muons
0115   for (size_t im = 0; im < muonHandle->size(); ++im) {
0116     const reco::RecoChargedCandidate& muon = (*muonHandle)[im];
0117     int qMuon = muon.charge();
0118     p4Muon = muon.p4();
0119     // tracks
0120     for (size_t it = 0; it < trackHandle->size(); ++it) {
0121       const reco::Track& track = (*trackHandle)[it];
0122       if (track.pt() < minTrackPt_ || track.p() < minTrackP_ || fabs(track.eta()) > maxTrackEta_)
0123         continue;
0124       if (checkCharge_ && track.charge() != -qMuon)
0125         continue;
0126       ++nQ;
0127       reco::Particle::LorentzVector p4Track(
0128           track.px(), track.py(), track.pz(), sqrt(track.p() * track.p() + 0.0111636));
0129       // mass windows
0130       double mass = (p4Muon + p4Track).mass();
0131       //       stream << "Combined mass = " << im << " " << it
0132       //         << " " << mass
0133       //         << " phi " << track.phi() << "\n";
0134       for (size_t j = 0; j < minMasses_.size(); ++j) {
0135         if (mass > minMasses_[j] && mass < maxMasses_[j]) {
0136           ++nComb;
0137           if (find(selectedTrackIndices.begin(), selectedTrackIndices.end(), it) == selectedTrackIndices.end())
0138             selectedTrackIndices.push_back(it);
0139           //      stream << "... adding " << "\n";
0140           break;
0141         }
0142       }
0143     }
0144   }
0145   //   LogDebug("QuarkoniaTrackSelector") << stream.str();
0146   //
0147   // filling of output collection
0148   //
0149   for (size_t i = 0; i < selectedTrackIndices.size(); ++i)
0150     product->push_back((*trackHandle)[selectedTrackIndices[i]]);
0151   //
0152   // debug output
0153   //
0154   if (edm::isDebugEnabled()) {
0155     std::ostringstream stream;
0156     stream << "Total number of combinations = " << muonHandle->size() * trackHandle->size() << " , after charge " << nQ
0157            << " , after mass " << nComb << std::endl;
0158     stream << "Selected " << product->size() << " tracks with # / q / pt / eta\n";
0159     for (size_t i = 0; i < product->size(); ++i) {
0160       const reco::Track& track = (*product)[i];
0161       stream << "  " << i << " " << track.charge() << " " << track.pt() << " " << track.eta() << "\n";
0162     }
0163     LogDebug("QuarkoniaTrackSelector") << stream.str();
0164   }
0165   //
0166   iEvent.put(std::move(product));
0167 }
0168 
0169 //define this as a plug-in
0170 DEFINE_FWK_MODULE(QuarkoniaTrackSelector);