Skip to content

Commit

Permalink
FastHisto update to match firmware approximately for June 2023
Browse files Browse the repository at this point in the history
Update VertexFinder to 256 bins, delay truncation of track pt until histogramming is finished to match HDLS firmware.

Update typedefs, switch vertex-finder to use selected tracks instead of converted, sync to global/EDProducer from cmssw master

FastHisto update, split part 2 of commit b17fb0e

Adjust VertexFinder inversion table.

Port note: Removed include of global/EDProducer.h in L1Trigger/VertexFinder/plugins/VertexProducer.cc, as it's present in L1Trigger/VertexFinder/interface/VertexProducer.h already
  • Loading branch information
Nick Manganelli committed Jul 11, 2023
1 parent 8791748 commit 4246b05
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 30 deletions.
10 changes: 7 additions & 3 deletions L1Trigger/VertexFinder/interface/VertexProducer.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#ifndef __L1Trigger_VertexFinder_VertexProducer_h__
#define __L1Trigger_VertexFinder_VertexProducer_h__

#include "DataFormats/Common/interface/Ptr.h"
#include "DataFormats/Common/interface/RefToPtr.h"
#include "DataFormats/L1Trigger/interface/Vertex.h"
#include "FWCore/Framework/interface/global/EDProducer.h"
#include "DataFormats/L1TrackTrigger/interface/TTTypes.h"
#include "DataFormats/L1Trigger/interface/VertexWord.h"
#include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
Expand Down Expand Up @@ -33,12 +34,15 @@ class VertexProducer : public edm::global::EDProducer<> {
~VertexProducer() override {}

private:
typedef edm::View<TTTrack<Ref_Phase2TrackerDigi_>> TTTrackCollectionView;
typedef TTTrack<Ref_Phase2TrackerDigi_> TTTrackType;
typedef std::vector<TTTrackType> TTTrackCollectionType;
typedef edm::RefVector<TTTrackCollectionType> TTTrackRefCollectionType;
typedef edm::View<TTTrackType> TTTrackCollectionView;

void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;

private:
const edm::EDGetTokenT<TTTrackCollectionView> l1TracksToken_;
const edm::EDGetTokenT<TTTrackRefCollectionType> l1TracksToken_;
const edm::ESGetToken<TrackerTopology, TrackerTopologyRcd> tTopoToken;
const std::string outputCollectionName_;

Expand Down
12 changes: 5 additions & 7 deletions L1Trigger/VertexFinder/plugins/VertexProducer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ using namespace l1tVertexFinder;
using namespace std;

VertexProducer::VertexProducer(const edm::ParameterSet& iConfig)
: l1TracksToken_(consumes<TTTrackCollectionView>(iConfig.getParameter<edm::InputTag>("l1TracksInputTag"))),
: l1TracksToken_(consumes<TTTrackRefCollectionType>(iConfig.getParameter<edm::InputTag>("l1TracksInputTag"))),
tTopoToken(esConsumes<TrackerTopology, TrackerTopologyRcd>()),
outputCollectionName_(iConfig.getParameter<std::string>("l1VertexCollectionName")),
settings_(AlgoSettings(iConfig)) {
Expand Down Expand Up @@ -67,19 +67,16 @@ VertexProducer::VertexProducer(const edm::ParameterSet& iConfig)
}

void VertexProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const {
edm::Handle<TTTrackCollectionView> l1TracksHandle;
edm::Handle<TTTrackRefCollectionType> l1TracksHandle;
iEvent.getByToken(l1TracksToken_, l1TracksHandle);

std::vector<l1tVertexFinder::L1Track> l1Tracks;
l1Tracks.reserve(l1TracksHandle->size());
if (settings_.debug() > 1) {
edm::LogInfo("VertexProducer") << "produce::Processing " << l1TracksHandle->size() << " tracks";
}
for (const auto& track : l1TracksHandle->ptrs()) {
auto l1track = L1Track(track);
// Check the minimum pT of the tracks
// This is left here because it represents the smallest pT to be sent by the track finding boards
// This has less to do with the algorithms than the constraints of what will be sent to the vertexing algorithm
for (const auto& track : *l1TracksHandle) {
auto l1track = L1Track(edm::refToPtr(track));
if (l1track.pt() >= settings_.vx_TrackMinPt()) {
l1Tracks.push_back(l1track);
} else {
Expand All @@ -89,6 +86,7 @@ void VertexProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::Event
}
}
}

if (settings_.debug() > 1) {
edm::LogInfo("VertexProducer") << "produce::Processing " << l1Tracks.size() << " tracks after minimum pt cut of"
<< settings_.vx_TrackMinPt() << " GeV";
Expand Down
6 changes: 3 additions & 3 deletions L1Trigger/VertexFinder/python/l1tVertexProducer_cfi.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@
# TDR settings: [-14.95, 15.0, 0.1]
# L1TkPrimaryVertexProducer: [-30.0, 30.0, 0.09983361065]
# HLS Firmware: [-14.4, 14.4, 0.4]
# Track word limits (128 binns): [-20.46921512, 20.46921512, 0.31983148625]
# Track word limits (256 binns): [-20.46921512, 20.46921512, 0.159915743125]
FH_HistogramParameters = cms.vdouble(-20.46921512, 20.46921512, 0.31983148625),
# Track word limits (128 binns): [-20.46912512, 20.46912512, 0.31983008]
# Track word limits (256 binns): [-20.46912512, 20.46912512, 0.15991504]
FH_HistogramParameters = cms.vdouble(-20.46912512, 20.46912512, 0.15991504),
# The number of vertixes to return (i.e. N windows with the highest combined pT)
FH_NVtx = cms.uint32(10),
# fastHisto algorithm assumed vertex half-width [cm]
Expand Down
62 changes: 45 additions & 17 deletions L1Trigger/VertexFinder/src/VertexFinder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ namespace l1tVertexFinder {
int nbins =
std::ceil((settings_->vx_histogram_max() - settings_->vx_histogram_min()) / settings_->vx_histogram_binwidth());
std::vector<RecoVertex<>> hist(nbins);
std::vector<RecoVertex<>> sums(nbins - settings_->vx_windowSize());
std::vector<RecoVertex<>> sums(nbins - settings_->vx_windowSize() + 1);
std::vector<float> bounds(nbins + 1);
strided_iota(std::begin(bounds),
std::next(std::begin(bounds), nbins + 1),
Expand Down Expand Up @@ -770,17 +770,21 @@ namespace l1tVertexFinder {
};

enum HistogramBitWidths {
kBinSize = 10, // Width of a single bin in z
kBinFixedSize = 7, // Width of a single z0 bin in fixed point representation
kBinFixedMagSize = 4, // Width (magnitude) of a single z0 bin in fixed point representation
kBinSize = 8, // Width of a single bin in z
kBinFixedSize = 8, // Width of a single z0 bin in fixed point representation
kBinFixedMagSize = 5, // Width (magnitude) of a single z0 bin in fixed point representation
kSlidingSumSize = 11, // Width of the sum of a window of bins
kInverseSize = 14, // Width of the inverse sum
kInverseMagSize = 1, // Width of the inverse sum magnitude (unsigned)
kWeightedSlidingSumSize = 20, // Width of the pT weighted sliding sum
kWeightedSlidingSumMagSize = 10, // Width of the pT weighted sliding sum magnitude (signed)
kWindowSize = 3, // Number of bins in the window used to sum histogram bins
kSumPtLinkSize = 9, // Number of bits used to represent the sum of track pts in a single bin from a single link

kSumPtWindowBits = BitsToRepresent(HistogramBitWidths::kWindowSize * (1 << HistogramBitWidths::kSumPtLinkSize)),
// Number of bits to represent the untruncated sum of track pts in a single bin from a single link
kSumPtUntruncatedLinkSize = TrackBitWidths::kPtSize + 2,
kSumPtUntruncatedLinkMagSize = TrackBitWidths::kPtMagSize + 2,
};

static constexpr unsigned int kTableSize =
Expand All @@ -798,6 +802,13 @@ namespace l1tVertexFinder {
// Histogram bin in fixed point representation, before truncation
typedef ap_ufixed<HistogramBitWidths::kBinFixedSize, HistogramBitWidths::kBinFixedMagSize, AP_RND_INF, AP_SAT>
histbin_fixed_t;
// This type is slightly arbitrary, but 2 bits larger than untruncated track pt to store sums in histogram bins
// with truncation just before vertex-finding
typedef ap_ufixed<HistogramBitWidths::kSumPtUntruncatedLinkSize,
HistogramBitWidths::kSumPtUntruncatedLinkMagSize,
AP_RND_INF,
AP_SAT>
histbin_pt_sum_fixed_t;
// This value is slightly arbitrary, but small enough that the windows sums aren't too big.
typedef ap_ufixed<HistogramBitWidths::kSumPtLinkSize, HistogramBitWidths::kSumPtLinkSize, AP_RND_INF, AP_SAT>
link_pt_sum_fixed_t;
Expand Down Expand Up @@ -855,12 +866,12 @@ namespace l1tVertexFinder {
// Replace with https://stackoverflow.com/questions/13313980/populate-an-array-using-constexpr-at-compile-time ?
auto init_inversion_table = [&]() -> std::vector<inverse_t> {
std::vector<inverse_t> table_out(kTableSize, 0.);
for (unsigned int ii = 0; ii < kTableSize; ii++) {
// First, convert from table index to X-value (unsigned 8-bit, range 0 to +1533)
float in_val = 1533.0 * (ii / float(kTableSize));
// Next, compute lookup table function
table_out.at(ii) = (in_val > 0) ? (1.0 / in_val) : 0.0;
for (unsigned int ii = 1; ii < (kTableSize - 1); ii++) {
// Compute lookup table function, table_out.at(0) = 0.0 by default
table_out.at(ii) = (1.0 / ii);
}
//explicitly set boundary to ensure weighted position doesn't exceed window, consistent with previous implementation of 1/(ii+1)
table_out.at(kTableSize - 1) = 1.0 / (kTableSize);
return table_out;
};

Expand Down Expand Up @@ -953,8 +964,9 @@ namespace l1tVertexFinder {
// Create the histogram
unsigned int nbins = std::round((settings_->vx_histogram_max() - settings_->vx_histogram_min()) /
settings_->vx_histogram_binwidth());
unsigned int nsums = nbins - settings_->vx_windowSize();
unsigned int nsums = nbins - settings_->vx_windowSize() + 1;
std::vector<link_pt_sum_fixed_t> hist(nbins, 0);
std::vector<histbin_pt_sum_fixed_t> hist_untruncated(nbins, 0);

// Loop over the tracks and fill the histogram
if (settings_->debug() > 2) {
Expand All @@ -963,11 +975,10 @@ namespace l1tVertexFinder {
for (const L1Track& track : fitTracks_) {
// Get the track pt and z0
// Convert them to an appropriate data format
// Truncation and saturdation taken care of by the data type specification
// Truncation and saturation taken care of by the data type specification, now delayed to end of histogramming
pt_t tkpt = 0;
tkpt.V = track.getTTTrackPtr()->getTrackWord()(TTTrack_TrackWord::TrackBitLocations::kRinvMSB - 1,
TTTrack_TrackWord::TrackBitLocations::kRinvLSB);
track_pt_fixed_t pt_tmp = tkpt;
z0_t tkZ0 = track.getTTTrackPtr()->getZ0Word();

if ((settings_->vx_DoQualityCuts() && track_quality_check(tkpt)) || (!settings_->vx_DoQualityCuts())) {
Expand All @@ -986,29 +997,46 @@ namespace l1tVertexFinder {
<< "\n"
<< "tkZ0 = " << tkZ0.to_double() << "(" << tkZ0.to_string(2)
<< ")\ttkpt = " << tkpt.to_double() << "(" << tkpt.to_string(2)
<< ")\tpt_tmp = " << pt_tmp << "\tbin = " << bin.first.to_int() << "\n"
<< ")\tbin = " << bin.first.to_int() << "\n"
<< "pt sum in bin " << bin.first.to_int()
<< " BEFORE adding track = " << hist.at(bin.first).to_double();
}
if (bin.second) {
hist.at(bin.first) = hist.at(bin.first) + pt_tmp;
hist_untruncated.at(bin.first) = hist_untruncated.at(bin.first) + tkpt;
}
if (settings_->debug() > 2) {
edm::LogInfo("VertexProducer") << "fastHistoEmulation::\npt sum in bin " << bin.first.to_int()
<< " AFTER adding track = " << hist.at(bin.first).to_double();
<< " AFTER adding track = " << hist_untruncated.at(bin.first).to_double();
}
} else {
if (settings_->debug() > 2) {
edm::LogInfo("VertexProducer") << "fastHistoEmulation::Did not add the following track ... \n"
<< "track word = " << track.getTTTrackPtr()->getTrackWord().to_string(2)
<< "\n"
<< "tkZ0 = " << tkZ0.to_double() << "(" << tkZ0.to_string(2)
<< ")\ttkpt = " << tkpt.to_double() << "(" << tkpt.to_string(2)
<< ")\tpt_tmp = " << pt_tmp;
<< ")\ttkpt = " << tkpt.to_double() << "(" << tkpt.to_string(2) << ")";
}
}
} // end loop over tracks

// HLS histogramming used to truncate track pt before adding, using
// track_pt_fixed_t pt_tmp = tkpt;
// Now, truncation should happen after histograms are filled but prior to the vertex-finding part of the algo
for (unsigned int hb = 0; hb < hist.size(); ++hb) {
link_pt_sum_fixed_t bin_trunc = hist_untruncated.at(hb).range(
HistogramBitWidths::kSumPtUntruncatedLinkSize - 1,
HistogramBitWidths::kSumPtUntruncatedLinkSize - HistogramBitWidths::kSumPtUntruncatedLinkMagSize);
hist.at(hb) = bin_trunc;
if (settings_->debug() > 2) {
edm::LogInfo("VertexProducer") << "fastHistoEmulation::truncating histogram bin pt once filling is complete \n"
<< "hist_untruncated.at(" << hb << ") = " << hist_untruncated.at(hb).to_double()
<< "(" << hist_untruncated.at(hb).to_string(2)
<< ")\tbin_trunc = " << bin_trunc.to_double() << "(" << bin_trunc.to_string(2)
<< ")\n\thist.at(" << hb << ") = " << hist.at(hb).to_double() << "("
<< hist.at(hb).to_string(2) << ")";
}
}

// Loop through all bins, taking into account the fact that the last bin is nbins-window_width+1,
// and compute the sums using sliding windows ... sum_i_i+(w-1) where i in (0,nbins-w) and w is the window size
std::vector<window_pt_sum_fixed_t> hist_window_sums(nsums, 0);
Expand Down

0 comments on commit 4246b05

Please sign in to comment.