From 0ae16019b3f20c21b1102de9f1e7abe43eb82f56 Mon Sep 17 00:00:00 2001 From: SClarkPhysics Date: Fri, 22 Sep 2023 13:42:53 -0400 Subject: [PATCH] Implement firmware style clustering, fix etaMax in config file --- .../test/gtt/createFirmwareInputFiles_cfg.py | 2 +- .../plugins/L1TrackJetClustering.h | 74 +++++++++++++ .../plugins/L1TrackJetEmulatorProducer.cc | 101 ++++++------------ 3 files changed, 108 insertions(+), 69 deletions(-) diff --git a/L1Trigger/DemonstratorTools/test/gtt/createFirmwareInputFiles_cfg.py b/L1Trigger/DemonstratorTools/test/gtt/createFirmwareInputFiles_cfg.py index 1a5540c377d94..38352ee6d011d 100644 --- a/L1Trigger/DemonstratorTools/test/gtt/createFirmwareInputFiles_cfg.py +++ b/L1Trigger/DemonstratorTools/test/gtt/createFirmwareInputFiles_cfg.py @@ -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) diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TrackJetClustering.h b/L1Trigger/L1TTrackMatch/plugins/L1TrackJetClustering.h index c4fdf3dfd1c02..f26cc059f493f 100644 --- a/L1Trigger/L1TTrackMatch/plugins/L1TrackJetClustering.h +++ b/L1Trigger/L1TTrackMatch/plugins/L1TrackJetClustering.h @@ -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 inline std::vector L1_clustering(T *phislice, int etaBins_, Eta etaStep_) { diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TrackJetEmulatorProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1TrackJetEmulatorProducer.cc index 7382ef37bb818..ab01402ee41b7 100644 --- a/L1Trigger/L1TTrackMatch/plugins/L1TrackJetEmulatorProducer.cc +++ b/L1Trigger/L1TTrackMatch/plugins/L1TrackJetEmulatorProducer.cc @@ -212,6 +212,7 @@ void L1TrackJetEmulatorProducer::produce(Event &iEvent, const EventSetup &iSetup return; } + TrackJetEmulationMaxZBin mzb; mzb.znum = 0; mzb.nclust = 0; @@ -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) @@ -281,75 +281,40 @@ void L1TrackJetEmulatorProducer::produce(Event &iEvent, const EventSetup &iSetup if (zbin == 0 && zmin == trkZ) continue; - //-pt + // Pt ap_uint 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) {