Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:21:16

0001 // -*- C++ -*-
0002 //
0003 // Package:    L1Trigger/L1TTrackMatch
0004 // Class:      L1TrackerEtMissEmulatorProducer
0005 //
0006 /**\class L1TrackerEtMissEmulatorProducer L1TrackerEtMissEmulatorProducer.cc
0007  L1Trigger/L1TTrackMatch/plugins/L1TrackerEtMissEmulatorProducer.cc
0008 
0009  Description: Takes L1TTTracks and performs a integer emulation of Track-based
0010  missing Et, outputting a collection of EtSum 
0011 */
0012 //
0013 // Original Author:  Christopher Brown
0014 //         Created:  Fri, 19 Feb 2021
0015 //         Updated:  Wed, 16 Jun 2021
0016 //
0017 //
0018 
0019 // system include files
0020 #include <iomanip>
0021 #include <memory>
0022 #include <numeric>
0023 #include <sstream>
0024 // user include files
0025 #include "DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h"
0026 #include "DataFormats/L1TrackTrigger/interface/TTTypes.h"
0027 #include "DataFormats/L1Trigger/interface/EtSum.h"
0028 #include "DataFormats/L1Trigger/interface/VertexWord.h"
0029 #include "DataFormats/Math/interface/LorentzVector.h"
0030 #include "FWCore/Framework/interface/Event.h"
0031 #include "FWCore/Framework/interface/EventSetup.h"
0032 #include "FWCore/Framework/interface/Frameworkfwd.h"
0033 #include "FWCore/Framework/interface/MakerMacros.h"
0034 #include "FWCore/Framework/interface/stream/EDProducer.h"
0035 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0036 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0037 #include "L1Trigger/L1TTrackMatch/interface/Cordic.h"
0038 #include "L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuAlgo.h"
0039 
0040 using namespace l1t;
0041 
0042 class L1TrackerEtMissEmulatorProducer : public edm::stream::EDProducer<> {
0043 public:
0044   typedef TTTrack<Ref_Phase2TrackerDigi_> L1TTTrackType;
0045   typedef std::vector<L1TTTrackType> L1TTTrackCollectionType;
0046   typedef edm::RefVector<L1TTTrackCollectionType> L1TTTrackRefCollectionType;
0047 
0048   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0049 
0050   explicit L1TrackerEtMissEmulatorProducer(const edm::ParameterSet&);
0051   ~L1TrackerEtMissEmulatorProducer() override;
0052 
0053 private:
0054   virtual void beginJob();
0055   void produce(edm::Event&, const edm::EventSetup&) override;
0056   virtual void endJob();
0057 
0058   // ----------member data ---------------------------
0059 
0060   std::vector<l1tmetemu::cos_lut_fixed_t> cosLUT_;  // Cos LUT array
0061   std::vector<l1tmetemu::global_phi_t> phiQuadrants_;
0062   std::vector<l1tmetemu::global_phi_t> phiShifts_;
0063 
0064   int cordicSteps_;
0065   int debug_;
0066   bool cordicDebug_ = false;
0067 
0068   std::string L1MetCollectionName_;
0069 
0070   const edm::EDGetTokenT<L1TTTrackRefCollectionType> trackToken_;
0071   const edm::EDGetTokenT<L1TTTrackRefCollectionType> vtxAssocTrackToken_;
0072 };
0073 
0074 // constructor//
0075 L1TrackerEtMissEmulatorProducer::L1TrackerEtMissEmulatorProducer(const edm::ParameterSet& iConfig)
0076     : trackToken_(consumes<L1TTTrackRefCollectionType>(iConfig.getParameter<edm::InputTag>("L1TrackInputTag"))),
0077       vtxAssocTrackToken_(
0078           consumes<L1TTTrackRefCollectionType>(iConfig.getParameter<edm::InputTag>("L1TrackAssociatedInputTag"))) {
0079   phiQuadrants_ = l1tmetemu::generatePhiSliceLUT(l1tmetemu::kNQuadrants);
0080   phiShifts_ = l1tmetemu::generatePhiSliceLUT(l1tmetemu::kNSector);
0081 
0082   // Get Emulator config parameters
0083   cordicSteps_ = (int)iConfig.getParameter<int>("nCordicSteps");
0084   debug_ = (int)iConfig.getParameter<int>("debug");
0085   // Name of output ED Product
0086   L1MetCollectionName_ = (std::string)iConfig.getParameter<std::string>("L1MetCollectionName");
0087 
0088   if (debug_ == 5) {
0089     cordicDebug_ = true;
0090   }
0091 
0092   // Compute LUTs
0093   cosLUT_ = l1tmetemu::generateCosLUT();
0094 
0095   // Print LUTs
0096   if (debug_ == 1) {
0097     l1tmetemu::printLUT(phiQuadrants_, "L1TrackerEtMissEmulatorProducer", "phiQuadrants_");
0098     l1tmetemu::printLUT(phiShifts_, "L1TrackerEtMissEmulatorProducer", "phiShifts_");
0099     l1tmetemu::printLUT(cosLUT_, "L1TrackerEtMissEmulatorProducer", "cosLUT_");
0100   }
0101 
0102   produces<std::vector<EtSum>>(L1MetCollectionName_);
0103 }
0104 
0105 L1TrackerEtMissEmulatorProducer::~L1TrackerEtMissEmulatorProducer() {}
0106 
0107 void L1TrackerEtMissEmulatorProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0108   using namespace edm;
0109 
0110   std::unique_ptr<std::vector<l1t::EtSum>> METCollection(new std::vector<l1t::EtSum>(0));
0111 
0112   edm::Handle<L1TTTrackRefCollectionType> L1TTTrackHandle;
0113   iEvent.getByToken(trackToken_, L1TTTrackHandle);
0114 
0115   edm::Handle<L1TTTrackRefCollectionType> L1TTTrackAssociatedHandle;
0116   iEvent.getByToken(vtxAssocTrackToken_, L1TTTrackAssociatedHandle);
0117 
0118   // Initialize cordic class
0119   Cordic cordicSqrt(cordicSteps_, cordicDebug_);
0120 
0121   if (!L1TTTrackHandle.isValid()) {
0122     LogError("L1TrackerEtMissEmulatorProducer") << "\nWarning: L1TTTrackCollection not found in the event. Exit\n";
0123     return;
0124   }
0125 
0126   if (!L1TTTrackAssociatedHandle.isValid()) {
0127     LogError("L1TrackerEtMissEmulatorProducer")
0128         << "\nWarning: L1TTTrackAssociatedCollection not found in the event. Exit\n";
0129     return;
0130   }
0131 
0132   // Initialize sector sums, need 0 initialization in case a sector has no
0133   // tracks
0134   l1tmetemu::Et_t sumPx[l1tmetemu::kNSector * 2] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
0135   l1tmetemu::Et_t sumPy[l1tmetemu::kNSector * 2] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
0136   int link_totals[l1tmetemu::kNSector * 2] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
0137   int sector_totals[l1tmetemu::kNSector] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
0138 
0139   // Track counters
0140   int num_assoc_tracks{0};
0141 
0142   for (const auto& track : *L1TTTrackHandle) {
0143     if (std::find(L1TTTrackAssociatedHandle->begin(), L1TTTrackAssociatedHandle->end(), track) !=
0144         L1TTTrackAssociatedHandle->end()) {
0145       bool EtaSector = (track->getTanlWord() & (1 << (TTTrack_TrackWord::TrackBitWidths::kTanlSize - 1)));
0146 
0147       ap_uint<TTTrack_TrackWord::TrackBitWidths::kRinvSize - 1> ptEmulationBits = track->getTrackWord()(
0148           TTTrack_TrackWord::TrackBitLocations::kRinvMSB - 1, TTTrack_TrackWord::TrackBitLocations::kRinvLSB);
0149       ap_ufixed<TTTrack_TrackWord::TrackBitWidths::kRinvSize - 1, l1tmetemu::kPtMagSize> ptEmulation;
0150       ptEmulation.V = ptEmulationBits.range();
0151 
0152       l1tmetemu::global_phi_t globalPhi =
0153           l1tmetemu::localToGlobalPhi(track->getPhiWord(), phiShifts_[track->phiSector()]);
0154 
0155       num_assoc_tracks++;
0156       if (debug_ == 7) {
0157         edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
0158             << "Track to Vertex ID: " << num_assoc_tracks << "\n"
0159             << "Phi Sector: " << track->phiSector() << " pT: " << track->getRinvWord()
0160             << " Phi: " << track->getPhiWord() << " TanL: " << track->getTanlWord() << " Z0: " << track->getZ0Word()
0161             << " Chi2rphi: " << track->getChi2RPhiWord() << " Chi2rz: " << track->getChi2RZWord()
0162             << " bendChi2: " << track->getBendChi2Word() << " Emu pT " << ptEmulation.to_double() << "\n"
0163             << "--------------------------------------------------------------\n";
0164       }
0165 
0166       if (debug_ == 2) {
0167         edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
0168             << "========================Phi debug=================================\n"
0169             << "Emu pT: " << ptEmulation.to_double() << " float pT: " << track->momentum().perp() << "\n"
0170             << "Int Phi: " << globalPhi << " Float Phi: " << track->phi() << " Float Cos(Phi): " << cos(track->phi())
0171             << "  Float Sin(Phi): " << sin(track->phi())
0172             << " Float Px: " << track->momentum().perp() * cos(track->phi())
0173             << " Float Py: " << track->momentum().perp() * sin(track->phi()) << "\n";
0174       }
0175 
0176       l1tmetemu::Et_t temppx = 0;
0177       l1tmetemu::Et_t temppy = 0;
0178 
0179       // Split tracks in phi quadrants and access cosLUT_, backwards iteration
0180       // through cosLUT_ gives sin Sum sector Et -ve when cos or sin phi are -ve
0181       sector_totals[track->phiSector()] += 1;
0182       if (globalPhi >= phiQuadrants_[0] && globalPhi < phiQuadrants_[1]) {
0183         temppx = ((l1tmetemu::Et_t)ptEmulation * cosLUT_[(globalPhi) >> l1tmetemu::kCosLUTShift]);
0184         temppy =
0185             ((l1tmetemu::Et_t)ptEmulation * cosLUT_[(phiQuadrants_[1] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift]);
0186 
0187         if (debug_ == 2) {
0188           edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
0189               << "Sector: " << track->phiSector() << " Quadrant: " << 1 << "\n"
0190               << "Emu Phi: " << globalPhi << " Emu Cos(Phi): " << cosLUT_[(globalPhi) >> l1tmetemu::kCosLUTShift]
0191               << " Emu Sin(Phi): " << cosLUT_[(phiQuadrants_[1] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift] << "\n";
0192         }
0193       } else if (globalPhi >= phiQuadrants_[1] && globalPhi < phiQuadrants_[2]) {
0194         temppx =
0195             -((l1tmetemu::Et_t)ptEmulation * cosLUT_[(phiQuadrants_[2] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift]);
0196         temppy = ((l1tmetemu::Et_t)ptEmulation * cosLUT_[(globalPhi - phiQuadrants_[1]) >> l1tmetemu::kCosLUTShift]);
0197 
0198         if (debug_ == 2) {
0199           edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
0200               << "Sector: " << track->phiSector() << " Quadrant: " << 2 << "\n"
0201               << "Emu Phi: " << globalPhi << " Emu Cos(Phi): -"
0202               << cosLUT_[(phiQuadrants_[2] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift]
0203               << " Emu Sin(Phi): " << cosLUT_[(globalPhi - phiQuadrants_[1]) >> l1tmetemu::kCosLUTShift] << "\n";
0204         }
0205       } else if (globalPhi >= phiQuadrants_[2] && globalPhi < phiQuadrants_[3]) {
0206         temppx = -((l1tmetemu::Et_t)ptEmulation * cosLUT_[(globalPhi - phiQuadrants_[2]) >> l1tmetemu::kCosLUTShift]);
0207         temppy =
0208             -((l1tmetemu::Et_t)ptEmulation * cosLUT_[(phiQuadrants_[3] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift]);
0209 
0210         if (debug_ == 2) {
0211           edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
0212               << "Sector: " << track->phiSector() << " Quadrant: " << 3 << "\n"
0213               << "Emu Phi: " << globalPhi << " Emu Cos(Phi): -"
0214               << cosLUT_[(globalPhi - phiQuadrants_[2]) >> l1tmetemu::kCosLUTShift] << " Emu Sin(Phi): -"
0215               << cosLUT_[(phiQuadrants_[3] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift] << "\n";
0216         }
0217 
0218       } else if (globalPhi >= phiQuadrants_[3] && globalPhi < phiQuadrants_[4]) {
0219         temppx =
0220             ((l1tmetemu::Et_t)ptEmulation * cosLUT_[(phiQuadrants_[4] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift]);
0221         temppy = -((l1tmetemu::Et_t)ptEmulation * cosLUT_[(globalPhi - phiQuadrants_[3]) >> l1tmetemu::kCosLUTShift]);
0222 
0223         if (debug_ == 2) {
0224           edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
0225               << "Sector: " << track->phiSector() << " Quadrant: " << 4 << "\n"
0226               << " Emu Phi: " << globalPhi
0227               << " Emu Cos(Phi): " << cosLUT_[(phiQuadrants_[4] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift]
0228               << " Emu Sin(Phi): -" << cosLUT_[(globalPhi - phiQuadrants_[3]) >> l1tmetemu::kCosLUTShift] << "\n";
0229         }
0230       }
0231 
0232       int link_number = (track->phiSector() * 2) + ((EtaSector) ? 0 : 1);
0233       link_totals[link_number] += 1;
0234       sumPx[link_number] += temppx;
0235       sumPy[link_number] += temppy;
0236 
0237       if (debug_ == 4) {
0238         edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
0239             << std::setprecision(8) << "Sector: " << track->phiSector() << " Eta sector: " << EtaSector << "\n"
0240             << "Track Ref Pt: " << track->momentum().perp() << " Track Ref Px: " << track->momentum().x()
0241             << " Track Ref Py: " << track->momentum().y() << "\n"
0242             << "Track Pt: " << ptEmulation << " Track phi: " << globalPhi << " Track Px: " << temppx
0243             << " Track Py: " << temppy << "\n"
0244             << "Sector Sum Px: " << sumPx[link_number] << " Sector Sum Py: " << sumPy[link_number] << "\n";
0245       }
0246     }
0247   }  // end loop over tracks
0248 
0249   l1tmetemu::Et_t GlobalPx = 0;
0250   l1tmetemu::Et_t GlobalPy = 0;
0251 
0252   // Global Et sum as floats to emulate rounding in HW
0253   for (unsigned int i = 0; i < l1tmetemu::kNSector * 2; i++) {
0254     GlobalPx += sumPx[i];
0255     GlobalPy += sumPy[i];
0256   }
0257 
0258   // Perform cordic sqrt, take x,y and converts to polar coordinate r,phi where
0259   // r=sqrt(x**2+y**2) and phi = atan(y/x)
0260   l1tmetemu::EtMiss EtMiss = cordicSqrt.toPolar(-GlobalPx, -GlobalPy);
0261 
0262   if (debug_ == 4 || debug_ == 6) {
0263     edm::LogVerbatim("L1TrackerEtMissEmulatorProducer") << "====Sector Pt====\n";
0264 
0265     for (unsigned int i = 0; i < l1tmetemu::kNSector * 2; i++) {
0266       edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
0267           << "Sector " << i << "\n"
0268           << "Px: " << sumPx[i] << " | Py: " << sumPy[i] << " | Link Totals: " << link_totals[i]
0269           << " | Sector Totals: " << sector_totals[(int)(i / 2)] << "\n";
0270     }
0271 
0272     edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
0273         << "====Global Pt====\n"
0274         << "Global Px: " << GlobalPx << "| Global Py: " << GlobalPy << "\n";
0275 
0276     edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
0277         << "====MET===\n"
0278         << "MET word Et: " << EtMiss.Et.range() * l1tmetemu::kStepMETwordEt << "| MET word phi: " << EtMiss.Phi << "\n"
0279         << "MET: " << EtMiss.Et.to_double() << "| MET phi: " << EtMiss.Phi.to_double() * l1tmetemu::kStepMETwordPhi
0280         << "\n"
0281         << "Word MET: " << EtMiss.Et.to_string(2) << " | Word MET phi: " << EtMiss.Phi.to_string(2) << "\n"
0282         << "# Tracks Associated to Vertex: " << num_assoc_tracks << "\n"
0283         << "========================================================\n";
0284   }
0285 
0286   math::XYZTLorentzVector missingEt(-GlobalPx, -GlobalPy, 0, EtMiss.Et);
0287   EtSum L1EtSum(missingEt, EtSum::EtSumType::kMissingEt, EtMiss.Et.range(), 0, EtMiss.Phi, num_assoc_tracks);
0288 
0289   METCollection->push_back(L1EtSum);
0290 
0291   iEvent.put(std::move(METCollection), L1MetCollectionName_);
0292 }  // end producer
0293 
0294 void L1TrackerEtMissEmulatorProducer::beginJob() {}
0295 
0296 void L1TrackerEtMissEmulatorProducer::endJob() {}
0297 
0298 // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
0299 void L1TrackerEtMissEmulatorProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0300   //The following says we do not know what parameters are allowed so do no validation
0301   // Please change this to state exactly what you do use, even if it is no parameters
0302   edm::ParameterSetDescription desc;
0303   desc.setUnknown();
0304   descriptions.addDefault(desc);
0305 }
0306 
0307 // define this as a plug-in
0308 DEFINE_FWK_MODULE(L1TrackerEtMissEmulatorProducer);