Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-08-26 00:19:29

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 <memory>
0021 #include <numeric>
0022 // user include files
0023 #include "DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h"
0024 #include "DataFormats/L1TrackTrigger/interface/TTTypes.h"
0025 #include "DataFormats/L1Trigger/interface/EtSum.h"
0026 #include "DataFormats/L1Trigger/interface/VertexWord.h"
0027 #include "DataFormats/Math/interface/LorentzVector.h"
0028 #include "FWCore/Framework/interface/Event.h"
0029 #include "FWCore/Framework/interface/EventSetup.h"
0030 #include "FWCore/Framework/interface/Frameworkfwd.h"
0031 #include "FWCore/Framework/interface/MakerMacros.h"
0032 #include "FWCore/Framework/interface/stream/EDProducer.h"
0033 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0034 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0035 #include "L1Trigger/L1TTrackMatch/interface/Cordic.h"
0036 #include "L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuAlgo.h"
0037 #include "L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuTrackTransform.h"
0038 
0039 using namespace l1t;
0040 
0041 class L1TrackerEtMissEmulatorProducer : public edm::stream::EDProducer<> {
0042 public:
0043   typedef TTTrack<Ref_Phase2TrackerDigi_> L1TTTrackType;
0044   typedef std::vector<L1TTTrackType> L1TTTrackCollectionType;
0045   typedef edm::RefVector<L1TTTrackCollectionType> L1TTTrackRefCollectionType;
0046   typedef l1t::VertexWordCollection L1VertexCollectionType;
0047   typedef l1t::VertexWord L1VertexType;
0048 
0049   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0050 
0051   explicit L1TrackerEtMissEmulatorProducer(const edm::ParameterSet&);
0052   ~L1TrackerEtMissEmulatorProducer() override;
0053 
0054 private:
0055   virtual void beginJob();
0056   void produce(edm::Event&, const edm::EventSetup&) override;
0057   virtual void endJob();
0058 
0059   // ----------member data ---------------------------
0060 
0061   std::vector<l1tmetemu::global_phi_t> cosLUT_;  // Cos LUT array
0062   std::vector<l1tmetemu::global_phi_t> phiQuadrants_;
0063   std::vector<l1tmetemu::global_phi_t> phiShifts_;
0064 
0065   l1tmetemu::z_t deltaZ0_ = 0;
0066 
0067   int cordicSteps_;
0068   int debug_;
0069   bool cordicDebug_ = false;
0070 
0071   bool GTTinput_ = false;
0072 
0073   L1TkEtMissEmuTrackTransform TrackTransform;
0074 
0075   std::string L1MetCollectionName_;
0076 
0077   const edm::EDGetTokenT<L1VertexCollectionType> pvToken_;
0078   const edm::EDGetTokenT<L1TTTrackRefCollectionType> trackToken_;
0079   const edm::EDGetTokenT<L1TTTrackRefCollectionType> vtxAssocTrackToken_;
0080 };
0081 
0082 // constructor//
0083 L1TrackerEtMissEmulatorProducer::L1TrackerEtMissEmulatorProducer(const edm::ParameterSet& iConfig)
0084     : pvToken_(consumes<L1VertexCollectionType>(iConfig.getParameter<edm::InputTag>("L1VertexInputTag"))),
0085       trackToken_(consumes<L1TTTrackRefCollectionType>(iConfig.getParameter<edm::InputTag>("L1TrackInputTag"))),
0086       vtxAssocTrackToken_(
0087           consumes<L1TTTrackRefCollectionType>(iConfig.getParameter<edm::InputTag>("L1TrackAssociatedInputTag"))) {
0088   // Setup LUTs
0089   TrackTransform.generateLUTs();
0090   phiQuadrants_ = TrackTransform.getPhiQuad();
0091   phiShifts_ = TrackTransform.getPhiShift();
0092 
0093   // Get Emulator config parameters
0094   cordicSteps_ = (int)iConfig.getParameter<int>("nCordicSteps");
0095   debug_ = (int)iConfig.getParameter<int>("debug");
0096 
0097   GTTinput_ = (bool)iConfig.getParameter<bool>("useGTTinput");
0098 
0099   TrackTransform.setGTTinput(GTTinput_);
0100 
0101   // Name of output ED Product
0102   L1MetCollectionName_ = (std::string)iConfig.getParameter<std::string>("L1MetCollectionName");
0103 
0104   if (debug_ == 5) {
0105     cordicDebug_ = true;
0106   }
0107 
0108   // To have same bin spacing between 0 and pi/2 as between original phi
0109   // granularity
0110   int cosLUTbins = floor(l1tmetemu::kMaxCosLUTPhi / l1tmetemu::kStepPhi);
0111 
0112   // Compute LUTs
0113   cosLUT_ = l1tmetemu::generateCosLUT(cosLUTbins);
0114 
0115   produces<std::vector<EtSum>>(L1MetCollectionName_);
0116 }
0117 
0118 L1TrackerEtMissEmulatorProducer::~L1TrackerEtMissEmulatorProducer() {}
0119 
0120 void L1TrackerEtMissEmulatorProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0121   using namespace edm;
0122 
0123   std::unique_ptr<std::vector<l1t::EtSum>> METCollection(new std::vector<l1t::EtSum>(0));
0124 
0125   edm::Handle<L1VertexCollectionType> L1VertexHandle;
0126   iEvent.getByToken(pvToken_, L1VertexHandle);
0127 
0128   edm::Handle<L1TTTrackRefCollectionType> L1TTTrackHandle;
0129   iEvent.getByToken(trackToken_, L1TTTrackHandle);
0130 
0131   edm::Handle<L1TTTrackRefCollectionType> L1TTTrackAssociatedHandle;
0132   iEvent.getByToken(vtxAssocTrackToken_, L1TTTrackAssociatedHandle);
0133 
0134   // Initialize cordic class
0135   Cordic cordicSqrt(l1tmetemu::kMETPhiBins, l1tmetemu::kMETSize, cordicSteps_, cordicDebug_);
0136 
0137   if (!L1VertexHandle.isValid()) {
0138     LogError("L1TrackerEtMissEmulatorProducer") << "\nWarning: VertexCollection not found in the event. Exit\n";
0139     return;
0140   }
0141 
0142   if (!L1TTTrackHandle.isValid()) {
0143     LogError("L1TrackerEtMissEmulatorProducer") << "\nWarning: L1TTTrackCollection not found in the event. Exit\n";
0144     return;
0145   }
0146 
0147   if (!L1TTTrackAssociatedHandle.isValid()) {
0148     LogError("L1TrackerEtMissEmulatorProducer")
0149         << "\nWarning: L1TTTrackAssociatedCollection not found in the event. Exit\n";
0150     return;
0151   }
0152 
0153   // Initialize sector sums, need 0 initialization in case a sector has no
0154   // tracks
0155   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};
0156   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};
0157   int sector_totals[l1tmetemu::kNSector] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
0158 
0159   // Track counters
0160   int num_quality_tracks{0};
0161   int num_assoc_tracks{0};
0162 
0163   // Get reference to first vertex in event vertex collection
0164   L1VertexType& vtx = const_cast<L1VertexType&>(L1VertexHandle->at(0));
0165 
0166   for (const auto& track : *L1TTTrackHandle) {
0167     num_quality_tracks++;
0168     L1TTTrackType& track_ref = const_cast<L1TTTrackType&>(*track);  // Get Reference to track to pass to TrackTransform
0169 
0170     // Convert to internal track representation
0171     InternalEtWord EtTrack = TrackTransform.transformTrack<L1TTTrackType, L1VertexType>(track_ref, vtx);
0172 
0173     if (std::find(L1TTTrackAssociatedHandle->begin(), L1TTTrackAssociatedHandle->end(), track) !=
0174         L1TTTrackAssociatedHandle->end()) {
0175       num_assoc_tracks++;
0176       if (debug_ == 7) {
0177         edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
0178             << "Track to Vertex ID: " << num_quality_tracks << "\n"
0179             << "Phi Sector: " << EtTrack.Sector << " pT: " << EtTrack.pt << " Phi: " << EtTrack.globalPhi
0180             << " TanL: " << EtTrack.eta << " Z0: " << EtTrack.z0 << " Nstub: " << EtTrack.nstubs
0181             << " Chi2rphi: " << EtTrack.chi2rphidof << " Chi2rz: " << EtTrack.chi2rzdof
0182             << " bendChi2: " << EtTrack.bendChi2 << " PV: " << EtTrack.pV << "\n"
0183             << "--------------------------------------------------------------\n";
0184       }
0185 
0186       if (debug_ == 2) {
0187         edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
0188             << "========================Phi debug=================================\n"
0189             << "Int pT: " << EtTrack.pt << "\n"
0190             << "Int Phi: " << EtTrack.globalPhi << " Float Phi: " << EtTrack.phi
0191             << " Actual Float Cos(Phi): " << cos(EtTrack.phi) << " Actual Float Sin(Phi): " << sin(EtTrack.phi) << "\n";
0192       }
0193       l1tmetemu::Et_t temppx = 0;
0194       l1tmetemu::Et_t temppy = 0;
0195 
0196       // Split tracks in phi quadrants and access cosLUT_, backwards iteration
0197       // through cosLUT_ gives sin Sum sector Et -ve when cos or sin phi are -ve
0198       sector_totals[EtTrack.Sector] += 1;
0199       if (EtTrack.globalPhi >= phiQuadrants_[0] && EtTrack.globalPhi < phiQuadrants_[1]) {
0200         temppx = (EtTrack.pt * cosLUT_[EtTrack.globalPhi]);
0201         temppy = (EtTrack.pt * cosLUT_[phiQuadrants_[1] - 1 - EtTrack.globalPhi]);
0202 
0203         if (debug_ == 2) {
0204           edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
0205               << "Sector: " << EtTrack.Sector << " Quadrant: " << 1 << "\n"
0206               << "Int Phi: " << EtTrack.globalPhi << " Int Cos(Phi): " << cosLUT_[EtTrack.globalPhi]
0207               << " Int Sin(Phi): " << cosLUT_[phiQuadrants_[1] - 1 - EtTrack.globalPhi] << "\n"
0208 
0209               << "Float Phi: " << (float)EtTrack.globalPhi / l1tmetemu::kGlobalPhiBins
0210               << " Float Cos(Phi): " << (float)cosLUT_[EtTrack.globalPhi] / l1tmetemu::kGlobalPhiBins
0211               << " Float Sin(Phi): "
0212               << (float)cosLUT_[phiQuadrants_[1] - 1 - EtTrack.globalPhi] / l1tmetemu::kGlobalPhiBins << "\n";
0213         }
0214       } else if (EtTrack.globalPhi >= phiQuadrants_[1] && EtTrack.globalPhi < phiQuadrants_[2]) {
0215         temppx = -(EtTrack.pt * cosLUT_[phiQuadrants_[2] - 1 - EtTrack.globalPhi]);
0216         temppy = (EtTrack.pt * cosLUT_[EtTrack.globalPhi - phiQuadrants_[1]]);
0217 
0218         if (debug_ == 2) {
0219           edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
0220               << "Sector: " << EtTrack.Sector << " Quadrant: " << 2 << "\n"
0221               << "Int Phi: " << EtTrack.globalPhi << " Int Cos(Phi): -"
0222               << cosLUT_[phiQuadrants_[2] - 1 - EtTrack.globalPhi]
0223               << " Int Sin(Phi): " << cosLUT_[EtTrack.globalPhi - phiQuadrants_[1]] << "\n"
0224 
0225               << "Float Phi: " << (float)EtTrack.globalPhi / l1tmetemu::kGlobalPhiBins << " Float Cos(Phi): -"
0226               << (float)cosLUT_[phiQuadrants_[2] - 1 - EtTrack.globalPhi] / l1tmetemu::kGlobalPhiBins
0227               << " Float Sin(Phi): " << (float)cosLUT_[EtTrack.globalPhi - phiQuadrants_[1]] / l1tmetemu::kGlobalPhiBins
0228               << "\n";
0229         }
0230       } else if (EtTrack.globalPhi >= phiQuadrants_[2] && EtTrack.globalPhi < phiQuadrants_[3]) {
0231         temppx = -(EtTrack.pt * cosLUT_[EtTrack.globalPhi - phiQuadrants_[2]]);
0232         temppy = -(EtTrack.pt * cosLUT_[phiQuadrants_[3] - 1 - EtTrack.globalPhi]);
0233 
0234         if (debug_ == 2) {
0235           edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
0236               << "Sector: " << EtTrack.Sector << " Quadrant: " << 3 << "\n"
0237               << "Int Phi: " << EtTrack.globalPhi << " Int Cos(Phi): -" << cosLUT_[EtTrack.globalPhi - phiQuadrants_[2]]
0238               << " Int Sin(Phi): -" << cosLUT_[phiQuadrants_[3] - 1 - EtTrack.globalPhi] << "\n"
0239 
0240               << "Float Phi: " << (float)EtTrack.globalPhi / l1tmetemu::kGlobalPhiBins << " Float Cos(Phi): -"
0241               << (float)cosLUT_[EtTrack.globalPhi - phiQuadrants_[2]] / l1tmetemu::kGlobalPhiBins
0242               << " Float Sin(Phi): -"
0243               << (float)cosLUT_[phiQuadrants_[3] - 1 - EtTrack.globalPhi] / l1tmetemu::kGlobalPhiBins << "\n";
0244         }
0245 
0246       } else if (EtTrack.globalPhi >= phiQuadrants_[3] && EtTrack.globalPhi < phiQuadrants_[4]) {
0247         temppx = (EtTrack.pt * cosLUT_[phiQuadrants_[4] - 1 - EtTrack.globalPhi]);
0248         temppy = -(EtTrack.pt * cosLUT_[EtTrack.globalPhi - phiQuadrants_[3]]);
0249 
0250         if (debug_ == 2) {
0251           edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
0252               << "Sector: " << EtTrack.Sector << " Quadrant: " << 4 << "\n"
0253               << "Int Phi: " << EtTrack.globalPhi
0254               << " Int Cos(Phi): " << cosLUT_[phiQuadrants_[4] - 1 - EtTrack.globalPhi] << " Int Sin(Phi): -"
0255               << cosLUT_[EtTrack.globalPhi - phiQuadrants_[3]] << "\n"
0256 
0257               << "Float Phi: " << (float)EtTrack.globalPhi / l1tmetemu::kGlobalPhiBins << " Float Cos(Phi): "
0258               << (float)cosLUT_[phiQuadrants_[4] - 1 - EtTrack.globalPhi] / l1tmetemu::kGlobalPhiBins
0259               << " Float Sin(Phi): -"
0260               << (float)cosLUT_[EtTrack.globalPhi - phiQuadrants_[3]] / l1tmetemu::kGlobalPhiBins << "\n";
0261         }
0262       } else {
0263         temppx = 0;
0264         temppy = 0;
0265       }
0266       if (EtTrack.EtaSector) {
0267         sumPx[EtTrack.Sector] = sumPx[EtTrack.Sector] + temppx;
0268         sumPy[EtTrack.Sector] = sumPy[EtTrack.Sector] + temppy;
0269       } else {
0270         sumPx[l1tmetemu::kNSector + EtTrack.Sector] = sumPx[l1tmetemu::kNSector + EtTrack.Sector] + temppx;
0271         sumPy[l1tmetemu::kNSector + EtTrack.Sector] = sumPy[l1tmetemu::kNSector + EtTrack.Sector] + temppy;
0272       }
0273     }
0274 
0275   }  // end loop over tracks
0276 
0277   l1tmetemu::Et_t GlobalPx = 0;
0278   l1tmetemu::Et_t GlobalPy = 0;
0279 
0280   float tempsumPx = 0;
0281   float tempsumPy = 0;
0282 
0283   // Global Et sum as floats to emulate rounding in HW
0284   for (unsigned int i = 0; i < l1tmetemu::kNSector * 2; i++) {
0285     tempsumPx += floor((float)sumPx[i] / (float)l1tmetemu::kGlobalPhiBins);
0286     tempsumPy += floor((float)sumPy[i] / (float)l1tmetemu::kGlobalPhiBins);
0287   }
0288 
0289   // Recast rounded temporary sums into Et_t datatype
0290   GlobalPx = tempsumPx;
0291   GlobalPy = tempsumPy;
0292 
0293   // Perform cordic sqrt, take x,y and converts to polar coordinate r,phi where
0294   // r=sqrt(x**2+y**2) and phi = atan(y/x)
0295   l1tmetemu::EtMiss EtMiss = cordicSqrt.toPolar(GlobalPx, GlobalPy);
0296 
0297   // Recentre phi
0298   l1tmetemu::METphi_t tempPhi = 0;
0299 
0300   if ((GlobalPx < 0) && (GlobalPy < 0))
0301     tempPhi = EtMiss.Phi - l1tmetemu::kMETPhiBins / 2;
0302   else if ((GlobalPx >= 0) && (GlobalPy >= 0))
0303     tempPhi = (EtMiss.Phi) + l1tmetemu::kMETPhiBins / 2;
0304   else if ((GlobalPx >= 0) && (GlobalPy < 0))
0305     tempPhi = EtMiss.Phi - l1tmetemu::kMETPhiBins / 2;
0306   else if ((GlobalPx < 0) && (GlobalPy >= 0))
0307     tempPhi = EtMiss.Phi - 3 * l1tmetemu::kMETPhiBins / 2;
0308 
0309   if (debug_ == 6) {
0310     std::string flpxarray[l1tmetemu::kNSector * 2];
0311     std::string flpyarray[l1tmetemu::kNSector * 2];
0312 
0313     std::string intpxarray[l1tmetemu::kNSector * 2];
0314     std::string intpyarray[l1tmetemu::kNSector * 2];
0315 
0316     std::string totalsarray[l1tmetemu::kNSector * 2];
0317 
0318     for (unsigned int i = 0; i < l1tmetemu::kNSector * 2; i++) {
0319       flpxarray[i] = to_string(sumPx[i] * l1tmetemu::kStepPt) + "|";
0320       flpyarray[i] = to_string(sumPy[i] * l1tmetemu::kStepPt) + "|";
0321       intpxarray[i] = to_string(floor((float)sumPx[i] / (float)l1tmetemu::kGlobalPhiBins)) + "|";
0322       intpyarray[i] = to_string(floor((float)sumPy[i] / (float)l1tmetemu::kGlobalPhiBins)) + "|";
0323       totalsarray[i] = to_string(sector_totals[i]) + "|";
0324     }
0325 
0326     edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
0327         << "====Sector Pt====\n"
0328         << "Float Px: " << flpxarray << "Float Py: " << flpyarray << "Integer Px: " << intpyarray
0329         << "Integer Px: " << intpyarray << "Sector Totals: " << totalsarray
0330 
0331         << "====Global Pt====\n"
0332         << "Integer Global Px: " << GlobalPx << "| Integer Global Py: " << GlobalPy << "\n"
0333         << "Float Global Px: " << GlobalPx * l1tmetemu::kStepPt
0334         << "| Float Global Py: " << GlobalPy * l1tmetemu::kStepPt << "\n";
0335   }
0336 
0337   if (debug_ == 6) {
0338     edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
0339         << "====MET===\n"
0340         << "Integer MET: " << EtMiss.Et << "| Integer MET phi: " << EtMiss.Phi << "\n"
0341         << "Float MET: " << (EtMiss.Et) * l1tmetemu::kStepMET
0342         << "| Float MET phi: " << (float)tempPhi * l1tmetemu::kStepMETPhi - M_PI << "\n"
0343         << "# Tracks after Quality Cuts: " << num_quality_tracks << "\n"
0344         << "# Tracks Associated to Vertex: " << num_assoc_tracks << "\n"
0345         << "========================================================\n";
0346   }
0347 
0348   math::XYZTLorentzVector missingEt(-GlobalPx, -GlobalPy, 0, EtMiss.Et);
0349   EtSum L1EtSum(missingEt, EtSum::EtSumType::kMissingEt, (int)EtMiss.Et, 0, (int)tempPhi, (int)num_assoc_tracks);
0350 
0351   METCollection->push_back(L1EtSum);
0352 
0353   iEvent.put(std::move(METCollection), L1MetCollectionName_);
0354 }  // end producer
0355 
0356 void L1TrackerEtMissEmulatorProducer::beginJob() {}
0357 
0358 void L1TrackerEtMissEmulatorProducer::endJob() {}
0359 
0360 // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
0361 void L1TrackerEtMissEmulatorProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0362   //The following says we do not know what parameters are allowed so do no validation
0363   // Please change this to state exactly what you do use, even if it is no parameters
0364   edm::ParameterSetDescription desc;
0365   desc.setUnknown();
0366   descriptions.addDefault(desc);
0367 }
0368 
0369 // define this as a plug-in
0370 DEFINE_FWK_MODULE(L1TrackerEtMissEmulatorProducer);