Skip to content

Commit

Permalink
Merge pull request cms-sw#2 from aperloff/phase2-l1t-integration-CMSS…
Browse files Browse the repository at this point in the history
…W_12_3_0_pre4-METUpdate

Match emulation and firmware
  • Loading branch information
Chriisbrown committed Sep 13, 2022
2 parents 38ab830 + db7adce commit 799e15b
Show file tree
Hide file tree
Showing 7 changed files with 211 additions and 124 deletions.
6 changes: 4 additions & 2 deletions L1Trigger/L1TTrackMatch/interface/Cordic.h
Expand Up @@ -17,6 +17,8 @@ class Cordic {
Cordic();
Cordic(const int aSteps, bool debug);

template <typename T>
void cordic_subfunc(T &x, T &y, T &z) const;
l1tmetemu::EtMiss toPolar(l1tmetemu::Et_t x, l1tmetemu::Et_t y) const;

private:
Expand All @@ -25,9 +27,9 @@ class Cordic {
const bool debug;

// To calculate atan
std::vector<l1tmetemu::E2t_t> atanLUT;
std::vector<l1tmetemu::atan_lut_fixed_t> atanLUT;
// To normalise final magnitude
std::vector<l1tmetemu::E2t_t> magNormalisationLUT;
std::vector<l1tmetemu::atan_lut_fixed_t> magNormalisationLUT;
};

#endif
40 changes: 22 additions & 18 deletions L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuAlgo.h
Expand Up @@ -8,6 +8,7 @@
#include <filesystem>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <numeric>

#include "DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h"
Expand All @@ -17,32 +18,35 @@
// Namespace that defines constants and types used by the EtMiss Emulation
// Includes functions for writing LUTs and converting to integer representations
namespace l1tmetemu {

const unsigned int kInternalPtWidth{14};
const unsigned int kPtMagSize{9};
const unsigned int kMETSize{16}; // For output Magnitude default 16
const unsigned int kMETMagSize{11};
const unsigned int kMETPhiSize{13}; // For Output Phi default 13
const unsigned int kEtExtra{4};
const unsigned int kGlobalPhiExtra{3};
const unsigned int kGlobalPhiExtra{4};
const unsigned int kCosLUTSize{10};
const unsigned int kCosLUTMagSize{1};
const unsigned int kAtanLUTSize{64};
const unsigned int kAtanLUTMagSize{2};

typedef ap_uint<TTTrack_TrackWord::TrackBitWidths::kPhiSize + kGlobalPhiExtra> global_phi_t;
typedef ap_ufixed<kMETSize, kMETMagSize, AP_RND_CONV, AP_SAT> METWord_t;
typedef ap_int<kMETPhiSize> METWordphi_t;
typedef ap_int<TTTrack_TrackWord::TrackBitWidths::kPhiSize + kGlobalPhiExtra> global_phi_t;
typedef ap_ufixed<kCosLUTSize, kCosLUTMagSize, AP_RND_CONV, AP_SAT> cos_lut_fixed_t;
typedef ap_fixed<kInternalPtWidth + kEtExtra + kEtExtra, kPtMagSize + kEtExtra, AP_RND_CONV, AP_SAT> Et_t;
typedef ap_fixed<kInternalPtWidth + kPtMagSize + kEtExtra,2*kPtMagSize + kEtExtra, AP_RND_CONV, AP_SAT> E2t_t;
typedef ap_ufixed<kAtanLUTSize, kAtanLUTMagSize, AP_RND_CONV, AP_SAT> atan_lut_fixed_t;
typedef ap_fixed<kMETSize + kEtExtra, kMETMagSize + kEtExtra, AP_RND_CONV, AP_SAT> Et_t;
typedef ap_fixed<kMETPhiSize + kEtExtra, 4, AP_RND_CONV, AP_SAT> metphi_fixed_t;
typedef ap_ufixed<kMETPhiSize + kEtExtra + 7, kMETPhiSize - 2, AP_RND_CONV, AP_SAT> pi_bins_fixed_t;

// Output definition as per interface document, only used when creating output format
const double kMaxMET{2048}; // 2 TeV
const double kMaxMET = 1 << kMETMagSize; // 2 TeV
const double kMaxMETPhi{2 * M_PI};

const unsigned int kMETSize{16}; // For output Magnitude default 16
const unsigned int kMETMagSize{11};
const unsigned int kMETPhiSize{13}; // For Output Phi default 13

typedef ap_ufixed<kMETSize,kMETMagSize> METWord_t;
typedef ap_int<kMETPhiSize> METWordphi_t;

const double kStepMETwordEt = kMaxMET / ( 1 << kMETSize);
const double kStepMETwordPhi = kMaxMETPhi / ( 1 << kMETPhiSize);
const double kStepMETwordEt = kMaxMET / (1 << kMETSize);
const double kStepMETwordPhi = kMaxMETPhi / (1 << kMETPhiSize);
const double kBinsInPi = 1.0 / kStepMETwordPhi;

// Enough symmetry in cos and sin between 0 and pi/2 to get all possible values
// of cos and sin phi
Expand All @@ -59,14 +63,14 @@ namespace l1tmetemu {

std::vector<cos_lut_fixed_t> generateCosLUT(unsigned int size);

global_phi_t localToGlobalPhi(TTTrack_TrackWord::phi_t local_phi, global_phi_t sector_shift );
global_phi_t localToGlobalPhi(TTTrack_TrackWord::phi_t local_phi, global_phi_t sector_shift);

std::vector<global_phi_t> generatePhiSliceLUT(unsigned int N);

template <typename T>
void printLUT(std::vector<T> lut, std::string module = "", std::string name = "") {
edm::LogVerbatim log(module);
log << "The " << name << "[" << lut.size() << "] values are ... \n";
log << "The " << name << "[" << lut.size() << "] values are ... \n" << std::setprecision(30);
for (unsigned int i = 0; i < lut.size(); i++) {
log << "\t" << i << "\t" << lut[i] << "\n";
}
Expand Down
Expand Up @@ -27,7 +27,7 @@ namespace l1tmhtemu {
// extra room for sumPx, sumPy
const unsigned int kEtExtra{10};
const unsigned int kValidSize{1};
const unsigned int kMHTSize{16}; // For output Magnitude default 15
const unsigned int kMHTSize{16}; // For output Magnitude default 15
const unsigned int kMHTIntSize{11};
const unsigned int kMHTPhiSize{13}; // For output Phi default 14
const unsigned int kHTSize{kInternalPtWidth + kEtExtra};
Expand Down Expand Up @@ -56,7 +56,7 @@ namespace l1tmhtemu {
typedef ap_int<kInternalPhiWidth> phi_t;

typedef ap_int<kHTSize> Et_t;
typedef ap_ufixed<kMHTSize,kMHTIntSize> MHT_t;
typedef ap_ufixed<kMHTSize, kMHTIntSize> MHT_t;
typedef ap_uint<kMHTPhiSize> MHTphi_t;

const unsigned int kMHTBins = 1 << kMHTSize;
Expand Down
7 changes: 3 additions & 4 deletions L1Trigger/L1TTrackMatch/plugins/L1TkHTMissEmulatorProducer.cc
Expand Up @@ -249,13 +249,12 @@ void L1TkHTMissEmulatorProducer::produce(edm::Event& iEvent, const edm::EventSet
<< "\n"
<< "====MHT AP_INTS TO FLOATS====\n"
<< "sumPx: " << (float)sumPx * l1tmhtemu::kStepPt * l1tmhtemu::kStepPhi
<< "| sumPy: " << (float)sumPy * l1tmhtemu::kStepPt * l1tmhtemu::kStepPhi
<< "| ET: " << EtMiss.Et.to_double() << "| HT: " << (float)HT * l1tmhtemu::kStepPt
<< "| PHI: " << (float)phi * l1tmhtemu::kStepMHTPhi - M_PI << "\n"
<< "| sumPy: " << (float)sumPy * l1tmhtemu::kStepPt * l1tmhtemu::kStepPhi << "| ET: " << EtMiss.Et.to_double()
<< "| HT: " << (float)HT * l1tmhtemu::kStepPt << "| PHI: " << (float)phi * l1tmhtemu::kStepMHTPhi - M_PI << "\n"
<< "-------------------------------------------------------------------------\n";
}
//rescale HT to correct output range
HT = HT / (int)(1/l1tmhtemu::kStepPt);
HT = HT / (int)(1 / l1tmhtemu::kStepPt);

EtSum L1HTSum(missingEt, EtSum::EtSumType::kMissingHt, (int)HT.range(), 0, (int)phi, (int)jetn);

Expand Down
75 changes: 33 additions & 42 deletions L1Trigger/L1TTrackMatch/plugins/L1TrackerEtMissEmulatorProducer.cc
Expand Up @@ -17,6 +17,7 @@
//

// system include files
#include <iomanip>
#include <memory>
#include <numeric>
#include <sstream>
Expand Down Expand Up @@ -75,7 +76,6 @@ L1TrackerEtMissEmulatorProducer::L1TrackerEtMissEmulatorProducer(const edm::Para
: trackToken_(consumes<L1TTTrackRefCollectionType>(iConfig.getParameter<edm::InputTag>("L1TrackInputTag"))),
vtxAssocTrackToken_(
consumes<L1TTTrackRefCollectionType>(iConfig.getParameter<edm::InputTag>("L1TrackAssociatedInputTag"))) {

phiQuadrants_ = l1tmetemu::generatePhiSliceLUT(l1tmetemu::kNQuadrants);
phiShifts_ = l1tmetemu::generatePhiSliceLUT(l1tmetemu::kNSector);

Expand Down Expand Up @@ -136,8 +136,8 @@ void L1TrackerEtMissEmulatorProducer::produce(edm::Event& iEvent, const edm::Eve

// Initialize sector sums, need 0 initialization in case a sector has no
// tracks
l1tmetemu::E2t_t sumPx[l1tmetemu::kNSector * 2] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
l1tmetemu::E2t_t sumPy[l1tmetemu::kNSector * 2] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
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};
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};
int link_totals[l1tmetemu::kNSector * 2] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int sector_totals[l1tmetemu::kNSector] = {0, 0, 0, 0, 0, 0, 0, 0, 0};

Expand All @@ -147,38 +147,39 @@ void L1TrackerEtMissEmulatorProducer::produce(edm::Event& iEvent, const edm::Eve
for (const auto& track : *L1TTTrackHandle) {
if (std::find(L1TTTrackAssociatedHandle->begin(), L1TTTrackAssociatedHandle->end(), track) !=
L1TTTrackAssociatedHandle->end()) {

bool EtaSector = (track->getTanlWord() & (1 << (TTTrack_TrackWord::TrackBitWidths::kTanlSize - 1)));

ap_uint<TTTrack_TrackWord::TrackBitWidths::kRinvSize - 1> ptEmulationBits = track->getTrackWord()(
TTTrack_TrackWord::TrackBitLocations::kRinvMSB - 1, TTTrack_TrackWord::TrackBitLocations::kRinvLSB);
ap_ufixed<TTTrack_TrackWord::TrackBitWidths::kRinvSize - 1, l1tmetemu::kPtMagSize> ptEmulation;
ptEmulation.V = ptEmulationBits.range();

l1tmetemu::global_phi_t globalPhi = l1tmetemu::localToGlobalPhi(track->getPhiWord(),phiShifts_[track->phiSector()]);
l1tmetemu::global_phi_t globalPhi =
l1tmetemu::localToGlobalPhi(track->getPhiWord(), phiShifts_[track->phiSector()]);

num_assoc_tracks++;
if (debug_ == 7) {
edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
<< "Track to Vertex ID: " << num_assoc_tracks << "\n"
<< "Phi Sector: " << track->phiSector() << " pT: " << track->getRinvWord() << " Phi: " << track->getPhiWord()
<< " TanL: " << track->getTanlWord() << " Z0: " << track->getZ0Word()
<< "Phi Sector: " << track->phiSector() << " pT: " << track->getRinvWord()
<< " Phi: " << track->getPhiWord() << " TanL: " << track->getTanlWord() << " Z0: " << track->getZ0Word()
<< " Chi2rphi: " << track->getChi2RPhiWord() << " Chi2rz: " << track->getChi2RZWord()
<< " bendChi2: " << track->getBendChi2Word() << " Emu pT " << ptEmulation.to_double() << "\n"
<< " bendChi2: " << track->getBendChi2Word() << " Emu pT " << ptEmulation.to_double() << "\n"
<< "--------------------------------------------------------------\n";
}

if (debug_ == 2) {
edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
<< "========================Phi debug=================================\n"
<< "Emu pT: " << ptEmulation.to_double() << " float pT: " << track->momentum().perp() << "\n"
<< "Int Phi: " << globalPhi << " Float Phi: " << track->phi()
<< " Float Cos(Phi): " << cos(track->phi()) << " Float Sin(Phi): " << sin(track->phi())
<< " Float Px: " << track->momentum().perp()*cos(track->phi()) << " Float Py: " << track->momentum().perp()*sin(track->phi()) << "\n";
<< "Int Phi: " << globalPhi << " Float Phi: " << track->phi() << " Float Cos(Phi): " << cos(track->phi())
<< " Float Sin(Phi): " << sin(track->phi())
<< " Float Px: " << track->momentum().perp() * cos(track->phi())
<< " Float Py: " << track->momentum().perp() * sin(track->phi()) << "\n";
}
l1tmetemu::E2t_t temppx = 0;
l1tmetemu::E2t_t temppy = 0;

l1tmetemu::Et_t temppx = 0;
l1tmetemu::Et_t temppy = 0;

// Split tracks in phi quadrants and access cosLUT_, backwards iteration
// through cosLUT_ gives sin Sum sector Et -ve when cos or sin phi are -ve
Expand All @@ -192,7 +193,6 @@ void L1TrackerEtMissEmulatorProducer::produce(edm::Event& iEvent, const edm::Eve
<< "Sector: " << track->phiSector() << " Quadrant: " << 1 << "\n"
<< "Emu Phi: " << globalPhi << " Emu Cos(Phi): " << cosLUT_[globalPhi]
<< " Emu Sin(Phi): " << cosLUT_[phiQuadrants_[1] - 1 - globalPhi] << "\n";

}
} else if (globalPhi >= phiQuadrants_[1] && globalPhi < phiQuadrants_[2]) {
temppx = -((l1tmetemu::Et_t)ptEmulation * cosLUT_[phiQuadrants_[2] - 1 - globalPhi]);
Expand All @@ -201,8 +201,7 @@ void L1TrackerEtMissEmulatorProducer::produce(edm::Event& iEvent, const edm::Eve
if (debug_ == 2) {
edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
<< "Sector: " << track->phiSector() << " Quadrant: " << 2 << "\n"
<< "Emu Phi: " << globalPhi << " Emu Cos(Phi): -"
<< cosLUT_[phiQuadrants_[2] - 1 - globalPhi]
<< "Emu Phi: " << globalPhi << " Emu Cos(Phi): -" << cosLUT_[phiQuadrants_[2] - 1 - globalPhi]
<< " Emu Sin(Phi): " << cosLUT_[globalPhi - phiQuadrants_[1]] << "\n";
}
} else if (globalPhi >= phiQuadrants_[2] && globalPhi < phiQuadrants_[3]) {
Expand All @@ -223,9 +222,8 @@ void L1TrackerEtMissEmulatorProducer::produce(edm::Event& iEvent, const edm::Eve
if (debug_ == 2) {
edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
<< "Sector: " << track->phiSector() << " Quadrant: " << 4 << "\n"
<< " Emu Phi: " << globalPhi
<< " Emu Cos(Phi): " << cosLUT_[phiQuadrants_[4] - 1 - globalPhi] << " Emu Sin(Phi): -"
<< cosLUT_[globalPhi - phiQuadrants_[3]] << "\n";
<< " Emu Phi: " << globalPhi << " Emu Cos(Phi): " << cosLUT_[phiQuadrants_[4] - 1 - globalPhi]
<< " Emu Sin(Phi): -" << cosLUT_[globalPhi - phiQuadrants_[3]] << "\n";
}
} else {
temppx = 0;
Expand All @@ -239,17 +237,18 @@ void L1TrackerEtMissEmulatorProducer::produce(edm::Event& iEvent, const edm::Eve

if (debug_ == 4) {
edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
<< "Sector: " << track->phiSector() << " Eta sector: " << EtaSector << "\n"
<< "Track Ref Pt: " << track->momentum().perp()
<< " Track Ref Px: " << track->momentum().x() << " Track Ref Py: " << track->momentum().y() << "\n"
<< "Track Pt: " << ptEmulation << " Track Px: " << temppx << " Track Py: " << temppy << "\n"
<< std::setprecision(8) << "Sector: " << track->phiSector() << " Eta sector: " << EtaSector << "\n"
<< "Track Ref Pt: " << track->momentum().perp() << " Track Ref Px: " << track->momentum().x()
<< " Track Ref Py: " << track->momentum().y() << "\n"
<< "Track Pt: " << ptEmulation << " Track phi: " << globalPhi << " Track Px: " << temppx
<< " Track Py: " << temppy << "\n"
<< "Sector Sum Px: " << sumPx[link_number] << " Sector Sum Py: " << sumPy[link_number] << "\n";
}
}
} // end loop over tracks

l1tmetemu::E2t_t GlobalPx = 0;
l1tmetemu::E2t_t GlobalPy = 0;
l1tmetemu::Et_t GlobalPx = 0;
l1tmetemu::Et_t GlobalPy = 0;

// Global Et sum as floats to emulate rounding in HW
for (unsigned int i = 0; i < l1tmetemu::kNSector * 2; i++) {
Expand All @@ -259,24 +258,16 @@ void L1TrackerEtMissEmulatorProducer::produce(edm::Event& iEvent, const edm::Eve

// Perform cordic sqrt, take x,y and converts to polar coordinate r,phi where
// r=sqrt(x**2+y**2) and phi = atan(y/x)
l1tmetemu::EtMiss EtMiss = cordicSqrt.toPolar(GlobalPx, GlobalPy);

if ((GlobalPx < 0) && (GlobalPy < 0))
EtMiss.Phi -= l1tmetemu::METWordphi_t(M_PI/l1tmetemu::kStepMETwordPhi);
else if ((GlobalPx < 0) && (GlobalPy >= 0))
EtMiss.Phi += l1tmetemu::METWordphi_t(M_PI/l1tmetemu::kStepMETwordPhi);
l1tmetemu::EtMiss EtMiss = cordicSqrt.toPolar(-GlobalPx, -GlobalPy);

if (debug_ == 4 || debug_ == 6) {

edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
<< "====Sector Pt====\n";
edm::LogVerbatim("L1TrackerEtMissEmulatorProducer") << "====Sector Pt====\n";

for (unsigned int i = 0; i < l1tmetemu::kNSector * 2; i++) {
edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
<< "Sector " << i << "\n"
<< "Px: " << sumPx[i] << " | Py: " << sumPy[i]
<< " | Link Totals: " << link_totals[i]
<< " | Sector Totals: " << sector_totals[(int)(i/2)] << "\n";
<< "Sector " << i << "\n"
<< "Px: " << sumPx[i] << " | Py: " << sumPy[i] << " | Link Totals: " << link_totals[i]
<< " | Sector Totals: " << sector_totals[(int)(i / 2)] << "\n";
}

edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
Expand All @@ -285,9 +276,9 @@ void L1TrackerEtMissEmulatorProducer::produce(edm::Event& iEvent, const edm::Eve

edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
<< "====MET===\n"
<< "MET word Et: " << EtMiss.Et.range()*l1tmetemu::kStepMETwordEt << "| MET word phi: " << EtMiss.Phi << "\n"
<< "MET: " << EtMiss.Et.to_double()
<< "| MET phi: " << (float)EtMiss.Phi * l1tmetemu::kStepMETwordPhi << "\n"
<< "MET word Et: " << EtMiss.Et.range() * l1tmetemu::kStepMETwordEt << "| MET word phi: " << EtMiss.Phi << "\n"
<< "MET: " << EtMiss.Et.to_double() << "| MET phi: " << EtMiss.Phi.to_double() * l1tmetemu::kStepMETwordPhi
<< "\n"
<< "Word MET: " << EtMiss.Et.to_string(2) << " | Word MET phi: " << EtMiss.Phi.to_string(2) << "\n"
<< "# Tracks Associated to Vertex: " << num_assoc_tracks << "\n"
<< "========================================================\n";
Expand Down

0 comments on commit 799e15b

Please sign in to comment.