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
0031 produces<reco::TrackCollection>();
0032
0033
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
0067
0068 auto product = std::make_unique<reco::TrackCollection>();
0069
0070
0071
0072 edm::Handle<reco::RecoChargedCandidateCollection> muonHandle;
0073 iEvent.getByToken(muonToken_, muonHandle);
0074
0075
0076
0077 edm::Handle<reco::TrackCollection> trackHandle;
0078 iEvent.getByToken(trackToken_, trackHandle);
0079
0080
0081
0082 if (!muonHandle.isValid() || !trackHandle.isValid() || minMasses_.empty()) {
0083 iEvent.put(std::move(product));
0084 return;
0085 }
0086
0087
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
0106
0107
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
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
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
0130 double mass = (p4Muon + p4Track).mass();
0131
0132
0133
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
0140 break;
0141 }
0142 }
0143 }
0144 }
0145
0146
0147
0148
0149 for (size_t i = 0; i < selectedTrackIndices.size(); ++i)
0150 product->push_back((*trackHandle)[selectedTrackIndices[i]]);
0151
0152
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
0170 DEFINE_FWK_MODULE(QuarkoniaTrackSelector);