Skip to content

Commit

Permalink
Implement firmware style clustering, fix etaMax in config file
Browse files Browse the repository at this point in the history
  • Loading branch information
SClarkPhysics committed Oct 26, 2023
1 parent 9a7cd3a commit 0ae1601
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
process.l1tTrackJetsEmulation.trk_zMax = cms.double(10000.0) # maximum track z
process.l1tTrackJetsEmulation.trk_ptMax = cms.double(10000.0) # maximumum track pT before saturation [GeV]
process.l1tTrackJetsEmulation.trk_ptMin = cms.double(0.0) # minimum track pt [GeV]
process.l1tTrackJetsEmulation.trk_etaMax = cms.double(10000.0) # maximum track eta
process.l1tTrackJetsEmulation.trk_etaMax = cms.double(2.4) # maximum track eta
process.l1tTrackJetsEmulation.nStubs4PromptChi2=cms.double(10000.0) #Prompt track quality flags for loose/tight
process.l1tTrackJetsEmulation.nStubs4PromptBend=cms.double(10000.0)
process.l1tTrackJetsEmulation.nStubs5PromptChi2=cms.double(10000.0)
Expand Down
74 changes: 74 additions & 0 deletions L1Trigger/L1TTrackMatch/plugins/L1TrackJetClustering.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,80 @@ namespace l1ttrackjet {
return PassQuality;
}

// Eta binning following the hardware logic
inline unsigned int eta_bin_firmwareStyle(int eta_word){
//Function that reads in 15-bit eta word (in two's complement) and returns the index of eta bin in which it belongs
//Logic follows exactly according to the firmware
//We will first determine if eta is pos/neg from the first bit. Each half of the grid is then split into four coarse bins. Bits 2&3 determine which coarse bin to assign
//The coarse bins are split into 5 fine bins, final 13 bits determine which of these coarse bins this track needs to assign

int eta_coarse = 0;
int eta_fine = 0;

if (eta_word & (1<<15)){ //If eta is negative (first/leftmost bit is 1)
//Second and third bits contain information about which of four coarse bins
eta_coarse = 5*((eta_word&(3<<13))>>13);
}
else { //else eta is positive (first/leftmost bit is 0)
eta_coarse = 5*(4 + ((eta_word&(3<<13))>>13));
}

//Now get the fine bin index. The numbers correspond to the decimal representation of fine bin edges in binary
int j = eta_word & 8191;
if (j < 1638)
eta_fine = 0;
else if (j < 3276)
eta_fine = 1;
else if (j < 4914)
eta_fine = 2;
else if (j < 6552)
eta_fine = 3;
else
eta_fine = 4;

//Final eta bin is coarse bin index + fine bin index, subtract 8 to make eta_bin at eta=-2.4 have index=0
int eta_ = (eta_coarse + eta_fine) - 8;
return eta_;
}

// Phi binning following the hardware logic
inline unsigned int phi_bin_firmwareStyle(int phi_sector_raw, int phi_word){
//Function that reads in decimal integers phi_sector_raw and phi_word and returns the index of phi bin in which it belongs
//phi_sector_raw is integer 0-8 correspoding to one of 9 phi sectors
//phi_word is 12 bit word representing the phi value measured w.r.t the center of the sector

int phi_coarse = 3*phi_sector_raw; //phi_coarse is index of phi coarse binning (sector edges)
int phi_fine = 0; //phi_fine is index of fine bin inside sectors. Each sector contains 3 fine bins

//Determine fine bin. First bit is sign, next 11 bits determine fine bin
//303 is distance from 0 to first fine bin edge
//2047 is eleven 1's, use the &2047 to extract leftmost 11 bits.

if (phi_word & (1<<11)){ //if phi is negative (first bit 1)
//Since negative, we 'flip' the phi word, then check if it is in fine bin 0 or 1
if ((2047 - (phi_word & 2047)) > 303){
phi_fine = 0;
}
else if ((2047 - (phi_word & 2047)) < 303){
phi_fine = 1;
}
}
else{ //else phi is positive (first bit 0)
//positive phi, no 'flip' necessary. Just check if in fine bin 1 or 2
if ((phi_word & 2047) < 303){
phi_fine = 1;
}
else if((phi_word & 2047) > 303){
phi_fine = 2;
}
}

// Final operation is a shift by pi (half a grid) to make bin at index=0 at -pi
int phi_bin_ = (phi_coarse + phi_fine + 12) % 27;

return phi_bin_;
}

// L1 clustering (in eta)
template <typename T, typename Pt, typename Eta, typename Phi>
inline std::vector<T> L1_clustering(T *phislice, int etaBins_, Eta etaStep_) {
Expand Down
101 changes: 33 additions & 68 deletions L1Trigger/L1TTrackMatch/plugins/L1TrackJetEmulatorProducer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ void L1TrackJetEmulatorProducer::produce(Event &iEvent, const EventSetup &iSetup
return;
}


TrackJetEmulationMaxZBin mzb;
mzb.znum = 0;
mzb.nclust = 0;
Expand Down Expand Up @@ -256,22 +257,21 @@ void L1TrackJetEmulatorProducer::produce(Event &iEvent, const EventSetup &iSetup
}
}

//Begin Firmware-style clustering
// logic: loop over z bins find tracks in this bin and arrange them in a 2D eta-phi matrix
for (unsigned int zbin = 0; zbin < zmins.size(); ++zbin) {
// initialize matrices for every z bin
z0_intern zmin = zmins[zbin];
z0_intern zmax = zmaxs[zbin];

TrackJetEmulationEtaPhiBin epbins[phiBins_][etaBins_];
std::copy(&epbins_default[0][0], &epbins_default[0][0] + phiBins_ * etaBins_, &epbins[0][0]);

//clear containers
std::copy(&epbins_default[0][0], &epbins_default[0][0] + phiBins_ * etaBins_, &epbins[0][0]);

L1clusters.clear();
L2clusters.clear();

// fill grid
for (unsigned int k = 0; k < L1TrkPtrs_.size(); ++k) {
//// conversions
//-z0

z0_intern trkZ = L1TrkPtrs_[k]->getZ0Word();

if (zmax < trkZ)
Expand All @@ -281,75 +281,40 @@ void L1TrackJetEmulatorProducer::produce(Event &iEvent, const EventSetup &iSetup
if (zbin == 0 && zmin == trkZ)
continue;

//-pt
// Pt
ap_uint<TTTrack_TrackWord::TrackBitWidths::kRinvSize - 1> ptEmulationBits = L1TrkPtrs_[k]->getRinvWord();
pt_intern trkpt;
trkpt.V = ptEmulationBits.range();

//-eta
TTTrack_TrackWord::tanl_t etaEmulationBits = L1TrkPtrs_[k]->getTanlWord();
glbeta_intern trketa;
trketa.V = etaEmulationBits.range();

//-phi
int Sector = L1TrkPtrs_[k]->phiSector();
double sector_phi_value = 0;
if (Sector < 5) {
sector_phi_value = 2.0 * M_PI * Sector / 9.0;
} else {
sector_phi_value = (-1.0 * M_PI + M_PI / 9.0 + (Sector - 5) * 2.0 * M_PI / 9.0);
}

glbphi_intern trkphiSector = DoubleToBit(sector_phi_value,
TTTrack_TrackWord::TrackBitWidths::kPhiSize + kExtraGlobalPhiBit,
TTTrack_TrackWord::stepPhi0);
glbphi_intern local_phi = 0;
local_phi.V = L1TrkPtrs_[k]->getPhiWord();
glbphi_intern local_phi2 =
DoubleToBit(BitToDouble(local_phi, TTTrack_TrackWord::TrackBitWidths::kPhiSize, TTTrack_TrackWord::stepPhi0),
TTTrack_TrackWord::TrackBitWidths::kPhiSize + kExtraGlobalPhiBit,
TTTrack_TrackWord::stepPhi0);
glbphi_intern trkphi = local_phi2 + trkphiSector;

//-d0

// d0
d0_intern abs_trkD0 = L1TrkPtrs_[k]->getD0Word();

//-nstub
// nstubs
int trk_nstubs = (int)L1TrkPtrs_[k]->getStubRefs().size();

// Phi bin
int i = phi_bin_firmwareStyle(L1TrkPtrs_[k]->phiSector(),L1TrkPtrs_[k]->getPhiWord()); //Function defined in L1TrackJetClustering.h

// Eta bin
int j = eta_bin_firmwareStyle(L1TrkPtrs_[k]->getTanlWord()); //Function defined in L1TrackJetClustering.h

if (trkpt < pt_intern(trkPtMax_))
epbins[i][j].pTtot += trkpt;
else
epbins[i][j].pTtot += pt_intern(trkPtMax_);
if ((abs_trkD0 >
DoubleToBit(d0CutNStubs5_, TTTrack_TrackWord::TrackBitWidths::kD0Size, TTTrack_TrackWord::stepD0) &&
trk_nstubs >= 5 && d0CutNStubs5_ >= 0) ||
(abs_trkD0 >
DoubleToBit(d0CutNStubs4_, TTTrack_TrackWord::TrackBitWidths::kD0Size, TTTrack_TrackWord::stepD0) &&
trk_nstubs == 4 && d0CutNStubs4_ >= 0))
epbins[i][j].nxtracks += 1;

epbins[i][j].trackidx.push_back(k);
++epbins[i][j].ntracks;

// now fill the 2D grid with tracks
for (int i = 0; i < phiBins_; ++i) {
for (int j = 0; j < etaBins_; ++j) {
glbeta_intern eta_min = epbins[i][j].eta - etaStep_ / 2; //eta min
glbeta_intern eta_max = epbins[i][j].eta + etaStep_ / 2; //eta max
glbphi_intern phi_min = epbins[i][j].phi - phiStep_ / 2; //phi min
glbphi_intern phi_max = epbins[i][j].phi + phiStep_ / 2; //phi max
if ((trketa < eta_min) && j != 0)
continue;
if ((trketa > eta_max) && j != etaBins_ - 1)
continue;
if ((trkphi < phi_min) && i != 0)
continue;
if ((trkphi > phi_max) && i != phiBins_ - 1)
continue;

if (trkpt < pt_intern(trkPtMax_))
epbins[i][j].pTtot += trkpt;
else
epbins[i][j].pTtot += pt_intern(trkPtMax_);
if ((abs_trkD0 >
DoubleToBit(d0CutNStubs5_, TTTrack_TrackWord::TrackBitWidths::kD0Size, TTTrack_TrackWord::stepD0) &&
trk_nstubs >= 5 && d0CutNStubs5_ >= 0) ||
(abs_trkD0 >
DoubleToBit(d0CutNStubs4_, TTTrack_TrackWord::TrackBitWidths::kD0Size, TTTrack_TrackWord::stepD0) &&
trk_nstubs == 4 && d0CutNStubs4_ >= 0))
epbins[i][j].nxtracks += 1;

epbins[i][j].trackidx.push_back(k);
++epbins[i][j].ntracks;
} // for each etabin
} // for each phibin
} //end loop over tracks
}
//End Firmware style clustering

// first layer clustering - in eta using grid
for (int phibin = 0; phibin < phiBins_; ++phibin) {
Expand Down

0 comments on commit 0ae1601

Please sign in to comment.