File indexing completed on 2024-10-08 05:11:50
0001
0002
0003 #ifndef PHASE2GMT_SAFWDMUONTRANSLATOR
0004 #define PHASE2GMT_SAFWDMUONTRANSLATOR
0005
0006
0007 #include <memory>
0008 #include <sstream>
0009
0010
0011 #include "FWCore/Framework/interface/Frameworkfwd.h"
0012 #include "FWCore/Framework/interface/stream/EDProducer.h"
0013 #include "FWCore/Framework/interface/Event.h"
0014 #include "FWCore/Framework/interface/MakerMacros.h"
0015 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0016 #include "FWCore/Utilities/interface/StreamID.h"
0017 #include "DataFormats/L1Trigger/interface/Muon.h"
0018 #include "DataFormats/L1TMuonPhase2/interface/SAMuon.h"
0019 #include "DataFormats/L1TMuonPhase2/interface/EMTFTrack.h"
0020 #include "L1Trigger/L1TMuonEndCapPhase2/interface/Utils/TPUtils.h"
0021
0022
0023
0024
0025 using namespace Phase2L1GMT;
0026 using namespace l1t;
0027
0028 class Phase2L1TGMTFwdMuonTranslator : public edm::stream::EDProducer<> {
0029 public:
0030 explicit Phase2L1TGMTFwdMuonTranslator(const edm::ParameterSet&);
0031 ~Phase2L1TGMTFwdMuonTranslator() override = default;
0032
0033 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0034
0035 private:
0036 void produce(edm::Event&, const edm::EventSetup&) override;
0037
0038 l1t::SAMuon Convertl1tMuon(const l1t::RegionalMuonCand& mu, const int bx_, bool isDisplaced = false);
0039 l1t::MuonStubRefVector selectLayerBX(const l1t::MuonStubRefVector& all, int bx, uint layer);
0040 void associateStubs(l1t::SAMuon&, const l1t::MuonStubRefVector&);
0041
0042 l1t::SAMuon ConvertEMTFTrack(const l1t::phase2::EMTFTrack& track, const int bx_);
0043
0044
0045 edm::EDGetTokenT<l1t::MuonStubCollection> stubToken_;
0046 edm::EDGetTokenT<l1t::RegionalMuonCandBxCollection> omtfTrackToken_;
0047 edm::EDGetTokenT<l1t::phase2::EMTFTrackCollection> emtfTrackToken_;
0048 };
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060 Phase2L1TGMTFwdMuonTranslator::Phase2L1TGMTFwdMuonTranslator(const edm::ParameterSet& iConfig)
0061 : stubToken_(consumes<l1t::MuonStubCollection>(iConfig.getParameter<edm::InputTag>("stubs"))),
0062 omtfTrackToken_(consumes<l1t::RegionalMuonCandBxCollection>(iConfig.getParameter<edm::InputTag>("omtfTracks"))),
0063 emtfTrackToken_(consumes<l1t::phase2::EMTFTrackCollection>(iConfig.getParameter<edm::InputTag>("emtfTracks"))) {
0064 produces<std::vector<l1t::SAMuon> >("prompt").setBranchAlias("prompt");
0065 produces<std::vector<l1t::SAMuon> >("displaced").setBranchAlias("displaced");
0066 }
0067
0068
0069 void Phase2L1TGMTFwdMuonTranslator::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0070 using namespace edm;
0071
0072 edm::Handle<l1t::MuonStubCollection> stubHandle;
0073 iEvent.getByToken(stubToken_, stubHandle);
0074
0075 edm::Handle<l1t::phase2::EMTFTrackCollection> emtf_tracks;
0076 iEvent.getByToken(emtfTrackToken_, emtf_tracks);
0077
0078 edm::Handle<l1t::RegionalMuonCandBxCollection> omtf_tracks;
0079 iEvent.getByToken(omtfTrackToken_, omtf_tracks);
0080
0081
0082 l1t::MuonStubRefVector stubs;
0083
0084 for (uint i = 0; i < stubHandle->size(); ++i) {
0085 l1t::MuonStubRef stub(stubHandle, i);
0086
0087 if (stub->bxNum() == 0)
0088 stubs.push_back(stub);
0089 }
0090
0091
0092 std::vector<SAMuon> prompt;
0093
0094
0095 std::vector<SAMuon> displaced;
0096
0097
0098 for (unsigned int i = 0; i < omtf_tracks->size(0); ++i) {
0099 const l1t::RegionalMuonCand& mu = omtf_tracks->at(0, i);
0100
0101
0102 l1t::SAMuon samuon;
0103 if (mu.hwPt() > 0) {
0104 samuon = Convertl1tMuon(mu, 0);
0105
0106 associateStubs(samuon, stubs);
0107 prompt.push_back(samuon);
0108 }
0109 if (mu.hwPtUnconstrained() > 0) {
0110 samuon = Convertl1tMuon(mu, 0, true);
0111
0112 associateStubs(samuon, stubs);
0113 displaced.push_back(samuon);
0114 }
0115 }
0116
0117
0118 for (unsigned int track_id = 0; track_id < emtf_tracks->size(); ++track_id) {
0119 const auto& track = emtf_tracks->at(track_id);
0120
0121
0122 if ((track.valid() == 0) || (track.bx() != 0)) {
0123 continue;
0124 }
0125
0126
0127 if (track.emtfQuality() <= 3) {
0128 continue;
0129 }
0130
0131
0132 if (track.emtfRels() != 127) {
0133 continue;
0134 }
0135
0136 auto samuon = ConvertEMTFTrack(track, 0);
0137
0138
0139 associateStubs(samuon, stubs);
0140
0141
0142 if (track.unconstrained()) {
0143 displaced.push_back(samuon);
0144 } else {
0145 prompt.push_back(samuon);
0146 }
0147 }
0148
0149
0150 std::unique_ptr<std::vector<l1t::SAMuon> > prompt_ptr = std::make_unique<std::vector<l1t::SAMuon> >(prompt);
0151 std::unique_ptr<std::vector<l1t::SAMuon> > displaced_ptr = std::make_unique<std::vector<l1t::SAMuon> >(displaced);
0152 iEvent.put(std::move(prompt_ptr), "prompt");
0153 iEvent.put(std::move(displaced_ptr), "displaced");
0154 }
0155
0156
0157
0158
0159
0160 SAMuon Phase2L1TGMTFwdMuonTranslator::Convertl1tMuon(const l1t::RegionalMuonCand& mu, const int bx_, bool isDisplaced) {
0161 ap_uint<BITSSAQUAL> qual = mu.hwQual();
0162 int charge = mu.hwSign();
0163
0164 ap_uint<BITSGTPT> pt = 0;
0165 if (!isDisplaced && mu.hwPt() > 0)
0166 pt = round(mu.hwPt() * 0.5 / LSBpt);
0167 if (isDisplaced && mu.hwPtUnconstrained() > 0)
0168 pt = round(mu.hwPtUnconstrained() * 1.0 / LSBpt);
0169
0170
0171 constexpr double p1phiLSB = 2 * M_PI / 576;
0172
0173
0174 int globPhi = mu.processor() * 192 + mu.hwPhi();
0175
0176 globPhi = (globPhi + 600) % 576;
0177 ap_int<BITSGTPHI> phi = round(globPhi * p1phiLSB / LSBphi);
0178 ap_int<BITSGTETA> eta = round(mu.hwEta() * 0.010875 / LSBeta);
0179
0180
0181
0182 ap_int<BITSSAZ0> z0 = 0;
0183
0184 ap_int<BITSSAD0> d0 = mu.hwDXY();
0185
0186
0187 int bstart = 0;
0188 wordtype word(0);
0189 bstart = wordconcat<wordtype>(word, bstart, 1, 1);
0190 bstart = wordconcat<wordtype>(word, bstart, charge, 1);
0191 bstart = wordconcat<wordtype>(word, bstart, pt, BITSPT);
0192 bstart = wordconcat<wordtype>(word, bstart, phi, BITSPHI);
0193 bstart = wordconcat<wordtype>(word, bstart, eta, BITSETA);
0194
0195 bstart = wordconcat<wordtype>(word, bstart, d0, BITSSAD0);
0196 wordconcat<wordtype>(
0197 word, bstart, qual, 8);
0198
0199
0200 math::PtEtaPhiMLorentzVector p4(pt * LSBpt, eta * LSBeta, phi * LSBphi, 0.0);
0201 SAMuon samuon(p4, charge, pt.to_uint(), eta.to_int(), phi.to_int(), z0.to_int(), d0.to_int(), qual.to_uint());
0202 samuon.setTF(mu.trackFinderType());
0203 samuon.setWord(word);
0204
0205 return samuon;
0206 }
0207
0208 l1t::MuonStubRefVector Phase2L1TGMTFwdMuonTranslator::selectLayerBX(const l1t::MuonStubRefVector& all,
0209 int bx,
0210 uint layer) {
0211 l1t::MuonStubRefVector out;
0212 for (const auto& stub : all) {
0213 if (stub->bxNum() == bx && stub->tfLayer() == layer)
0214 out.push_back(stub);
0215 }
0216 return out;
0217 }
0218
0219 void Phase2L1TGMTFwdMuonTranslator::associateStubs(l1t::SAMuon& mu, const l1t::MuonStubRefVector& stubs) {
0220 for (unsigned int layer = 0; layer <= 4; ++layer) {
0221 l1t::MuonStubRefVector selectedStubs = selectLayerBX(stubs, 0, layer);
0222 int bestStubINT = -1;
0223 float dPhi = 1000.0;
0224 for (uint i = 0; i < selectedStubs.size(); ++i) {
0225 const l1t::MuonStubRef& stub = selectedStubs[i];
0226 float deltaPhi =
0227 (stub->quality() & 0x1) ? stub->offline_coord1() - mu.p4().phi() : stub->offline_coord2() - mu.p4().phi();
0228 if (deltaPhi > M_PI)
0229 deltaPhi = deltaPhi - 2 * M_PI;
0230 if (deltaPhi < -M_PI)
0231 deltaPhi = deltaPhi + 2 * M_PI;
0232 deltaPhi = fabs(deltaPhi);
0233 float deltaEta = (stub->etaQuality() == 0 || (stub->etaQuality() & 0x1))
0234 ? fabs(stub->offline_eta1() - mu.p4().eta())
0235 : fabs(stub->offline_eta2() - mu.p4().eta());
0236 if (deltaPhi < 0.3 && deltaEta < 0.3 && deltaPhi < dPhi) {
0237 dPhi = deltaPhi;
0238 bestStubINT = i;
0239 }
0240 }
0241 if (bestStubINT >= 0) {
0242 mu.addStub(selectedStubs[bestStubINT]);
0243 }
0244 }
0245 }
0246
0247 SAMuon Phase2L1TGMTFwdMuonTranslator::ConvertEMTFTrack(const l1t::phase2::EMTFTrack& track, const int bx_) {
0248
0249 float track_phi =
0250 emtf::phase2::tp::calcPhiGlobRadFromLoc(track.sector(), emtf::phase2::tp::calcPhiLocRadFromInt(track.modelPhi()));
0251 float track_theta = emtf::phase2::tp::calcThetaRadFromInt(track.modelEta());
0252 float track_eta = -1 * std::log(std::tan(track_theta / 2));
0253
0254
0255 track_eta *= track.endcap();
0256
0257
0258
0259 math::PtEtaPhiMLorentzVector p4(track.emtfPt() * LSBpt, track_eta, track_phi, 0.0);
0260
0261
0262 ap_uint<BITSSAQUAL> qual = track.emtfQuality();
0263 int charge = track.emtfQ();
0264 ap_uint<BITSGTPT> pt = track.emtfPt();
0265 ap_int<BITSGTPHI> phi = round(track_phi / LSBphi);
0266 ap_int<BITSGTETA> eta = round(track_eta / LSBeta);
0267 ap_int<BITSSAZ0> z0 = track.emtfZ0();
0268 ap_int<BITSSAD0> d0 = track.emtfD0();
0269
0270
0271 int bstart = 0;
0272 wordtype word(0);
0273 bstart = wordconcat<wordtype>(word, bstart, 1, 1);
0274 bstart = wordconcat<wordtype>(word, bstart, charge, 1);
0275 bstart = wordconcat<wordtype>(word, bstart, pt, BITSPT);
0276 bstart = wordconcat<wordtype>(word, bstart, phi, BITSPHI);
0277 bstart = wordconcat<wordtype>(word, bstart, eta, BITSETA);
0278
0279 bstart = wordconcat<wordtype>(word, bstart, d0, BITSSAD0);
0280 wordconcat<wordtype>(
0281 word, bstart, qual, 8);
0282
0283 SAMuon samuon(p4, charge, pt.to_uint(), eta.to_int(), phi.to_int(), z0.to_int(), d0.to_int(), qual.to_uint());
0284
0285
0286 if (track.endcap() == 1)
0287 samuon.setTF(tftype::emtf_pos);
0288 else
0289 samuon.setTF(tftype::emtf_neg);
0290
0291 samuon.setWord(word);
0292
0293 return samuon;
0294 }
0295
0296
0297 void Phase2L1TGMTFwdMuonTranslator::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0298
0299
0300 edm::ParameterSetDescription desc;
0301
0302
0303 desc.add<edm::InputTag>("stubs", edm::InputTag("gmtStubs"));
0304 desc.add<edm::InputTag>("emtfTracks", edm::InputTag("simEmtfDigisPhase2"));
0305 desc.add<edm::InputTag>("omtfTracks", edm::InputTag("simOmtfPhase2Digis"));
0306
0307
0308 descriptions.add("Phase2L1TGMTFwdMuonTranslator", desc);
0309 }
0310
0311
0312 DEFINE_FWK_MODULE(Phase2L1TGMTFwdMuonTranslator);
0313 #endif