diff --git a/DataFormats/CSCDigi/interface/CSCConstants.h b/DataFormats/CSCDigi/interface/CSCConstants.h index fdf285da94d9e..b4501336b6fef 100644 --- a/DataFormats/CSCDigi/interface/CSCConstants.h +++ b/DataFormats/CSCDigi/interface/CSCConstants.h @@ -53,51 +53,50 @@ class CSCConstants { }; // distrips, strips, half-strips - enum Strip_Info { - // Each CFEB reads out 8 distrips... - NUM_DISTRIPS_PER_CFEB = 8, - //...16 strips... - NUM_STRIPS_PER_CFEB = 2 * NUM_DISTRIPS_PER_CFEB, - //...32 half-strips. - NUM_HALF_STRIPS_PER_CFEB = 2 * NUM_STRIPS_PER_CFEB, - // There are exactly 80 or 112 strips... - MAX_NUM_STRIPS_RUN1 = MAX_CFEBS_RUN1 * NUM_STRIPS_PER_CFEB, // 80 - MAX_NUM_STRIPS_RUN2 = MAX_CFEBS_RUN2 * NUM_STRIPS_PER_CFEB, // 112 - //...and 160 or 224 half-strips for 5 or 7 CFEBs... - MAX_NUM_HALF_STRIPS_RUN1 = MAX_CFEBS_RUN1 * NUM_HALF_STRIPS_PER_CFEB, // 160 - MAX_NUM_HALF_STRIPS_RUN2 = MAX_CFEBS_RUN2 * NUM_HALF_STRIPS_PER_CFEB, // 224 - // ...but depending on the chamber, there may or may not be strip staggering. - /* CMS-MUO-16-001: "[..] alternate layers in a CSC are staggered by half a strip width, except + static constexpr int + // Each CFEB reads out 8 distrips... + NUM_DISTRIPS_PER_CFEB = 8, + //...16 strips... + NUM_STRIPS_PER_CFEB = 2 * NUM_DISTRIPS_PER_CFEB, + //...32 half-strips. + NUM_HALF_STRIPS_PER_CFEB = 2 * NUM_STRIPS_PER_CFEB, + // There are exactly 80 or 112 strips... + MAX_NUM_STRIPS_RUN1 = MAX_CFEBS_RUN1 * NUM_STRIPS_PER_CFEB, // 80 + MAX_NUM_STRIPS_RUN2 = MAX_CFEBS_RUN2 * NUM_STRIPS_PER_CFEB, // 112 + //...and 160 or 224 half-strips for 5 or 7 CFEBs... + MAX_NUM_HALF_STRIPS_RUN1 = MAX_CFEBS_RUN1 * NUM_HALF_STRIPS_PER_CFEB, // 160 + MAX_NUM_HALF_STRIPS_RUN2 = MAX_CFEBS_RUN2 * NUM_HALF_STRIPS_PER_CFEB, // 224 + // ...but depending on the chamber, there may or may not be strip staggering. + /* CMS-MUO-16-001: "[..] alternate layers in a CSC are staggered by half a strip width, except in the ME1/1 chambers where the strips are narrower and the effect is small" */ - // _TRIGGER is added at the end, because these constants are only used in the trigger - MAX_NUM_HALF_STRIPS_RUN1_TRIGGER = 1 + MAX_NUM_HALF_STRIPS_RUN1, // 161 - MAX_NUM_HALF_STRIPS_RUN2_TRIGGER = 1 + MAX_NUM_HALF_STRIPS_RUN2, // 225 - // Number of strips in ME11 (special case) - NUM_STRIPS_ME1A_GANGED = NUM_CFEBS_ME1A_GANGED * NUM_STRIPS_PER_CFEB, // 16 - NUM_STRIPS_ME1A_UNGANGED = NUM_CFEBS_ME1A_UNGANGED * NUM_STRIPS_PER_CFEB, // 48 - NUM_STRIPS_ME1B = NUM_CFEBS_ME1B * NUM_STRIPS_PER_CFEB, // 64 - // Number of half-strips in ME11 (special case) - NUM_HALF_STRIPS_ME1A_GANGED = NUM_CFEBS_ME1A_GANGED * NUM_HALF_STRIPS_PER_CFEB, // 32 - NUM_HALF_STRIPS_ME1A_UNGANGED = NUM_CFEBS_ME1A_UNGANGED * NUM_HALF_STRIPS_PER_CFEB, // 96 - NUM_HALF_STRIPS_ME1B = NUM_CFEBS_ME1B * NUM_HALF_STRIPS_PER_CFEB, // 128 - NUM_HALF_STRIPS_ME11_GANGED = NUM_CFEBS_ME11_GANGED * NUM_HALF_STRIPS_PER_CFEB, // 160 - NUM_HALF_STRIPS_ME11_UNGANGED = NUM_CFEBS_ME11_UNGANGED * NUM_HALF_STRIPS_PER_CFEB, // 224 - // max halfstrip number in ME1/1 chambers - MAX_HALF_STRIP_ME1A_GANGED = NUM_HALF_STRIPS_ME1A_GANGED - 1, // 31 - MAX_HALF_STRIP_ME1A_UNGANGED = NUM_HALF_STRIPS_ME1A_UNGANGED - 1, // 95 - MAX_HALF_STRIP_ME1B = NUM_HALF_STRIPS_ME1B - 1, // 127 - // half-strips for the rest of the system - NUM_HALF_STRIPS_ME12 = NUM_CFEBS_ME12 * NUM_HALF_STRIPS_PER_CFEB, // 160 - NUM_HALF_STRIPS_ME13 = NUM_CFEBS_ME13 * NUM_HALF_STRIPS_PER_CFEB, // 128 - NUM_HALF_STRIPS_ME21 = NUM_CFEBS_ME21 * NUM_HALF_STRIPS_PER_CFEB, // 160 - NUM_HALF_STRIPS_ME22 = NUM_CFEBS_ME22 * NUM_HALF_STRIPS_PER_CFEB, // 160 - NUM_HALF_STRIPS_ME31 = NUM_CFEBS_ME31 * NUM_HALF_STRIPS_PER_CFEB, // 160 - NUM_HALF_STRIPS_ME32 = NUM_CFEBS_ME32 * NUM_HALF_STRIPS_PER_CFEB, // 160 - NUM_HALF_STRIPS_ME41 = NUM_CFEBS_ME41 * NUM_HALF_STRIPS_PER_CFEB, // 160 - NUM_HALF_STRIPS_ME42 = NUM_CFEBS_ME42 * NUM_HALF_STRIPS_PER_CFEB, // 160 - // useful for the comparator code algorithm - INVALID_HALF_STRIP = 65535 - }; + // _TRIGGER is added at the end, because these constants are only used in the trigger + MAX_NUM_HALF_STRIPS_RUN1_TRIGGER = 1 + MAX_NUM_HALF_STRIPS_RUN1, // 161 + MAX_NUM_HALF_STRIPS_RUN2_TRIGGER = 1 + MAX_NUM_HALF_STRIPS_RUN2, // 225 + // Number of strips in ME11 (special case) + NUM_STRIPS_ME1A_GANGED = NUM_CFEBS_ME1A_GANGED * NUM_STRIPS_PER_CFEB, // 16 + NUM_STRIPS_ME1A_UNGANGED = NUM_CFEBS_ME1A_UNGANGED * NUM_STRIPS_PER_CFEB, // 48 + NUM_STRIPS_ME1B = NUM_CFEBS_ME1B * NUM_STRIPS_PER_CFEB, // 64 + // Number of half-strips in ME11 (special case) + NUM_HALF_STRIPS_ME1A_GANGED = NUM_CFEBS_ME1A_GANGED * NUM_HALF_STRIPS_PER_CFEB, // 32 + NUM_HALF_STRIPS_ME1A_UNGANGED = NUM_CFEBS_ME1A_UNGANGED * NUM_HALF_STRIPS_PER_CFEB, // 96 + NUM_HALF_STRIPS_ME1B = NUM_CFEBS_ME1B * NUM_HALF_STRIPS_PER_CFEB, // 128 + NUM_HALF_STRIPS_ME11_GANGED = NUM_CFEBS_ME11_GANGED * NUM_HALF_STRIPS_PER_CFEB, // 160 + NUM_HALF_STRIPS_ME11_UNGANGED = NUM_CFEBS_ME11_UNGANGED * NUM_HALF_STRIPS_PER_CFEB, // 224 + // max halfstrip number in ME1/1 chambers + MAX_HALF_STRIP_ME1A_GANGED = NUM_HALF_STRIPS_ME1A_GANGED - 1, // 31 + MAX_HALF_STRIP_ME1A_UNGANGED = NUM_HALF_STRIPS_ME1A_UNGANGED - 1, // 95 + MAX_HALF_STRIP_ME1B = NUM_HALF_STRIPS_ME1B - 1, // 127 + // half-strips for the rest of the system + NUM_HALF_STRIPS_ME12 = NUM_CFEBS_ME12 * NUM_HALF_STRIPS_PER_CFEB, // 160 + NUM_HALF_STRIPS_ME13 = NUM_CFEBS_ME13 * NUM_HALF_STRIPS_PER_CFEB, // 128 + NUM_HALF_STRIPS_ME21 = NUM_CFEBS_ME21 * NUM_HALF_STRIPS_PER_CFEB, // 160 + NUM_HALF_STRIPS_ME22 = NUM_CFEBS_ME22 * NUM_HALF_STRIPS_PER_CFEB, // 160 + NUM_HALF_STRIPS_ME31 = NUM_CFEBS_ME31 * NUM_HALF_STRIPS_PER_CFEB, // 160 + NUM_HALF_STRIPS_ME32 = NUM_CFEBS_ME32 * NUM_HALF_STRIPS_PER_CFEB, // 160 + NUM_HALF_STRIPS_ME41 = NUM_CFEBS_ME41 * NUM_HALF_STRIPS_PER_CFEB, // 160 + NUM_HALF_STRIPS_ME42 = NUM_CFEBS_ME42 * NUM_HALF_STRIPS_PER_CFEB, // 160 + // useful for the comparator code algorithm + INVALID_HALF_STRIP = 65535; // CSCs have 6 layers. The key (reference) layer is the third layer enum Layer_Info { NUM_LAYERS = 6, KEY_CLCT_LAYER = 3, KEY_ALCT_LAYER = 3 }; diff --git a/DataFormats/L1CSCTrackFinder/interface/CSCTFConstants.h b/DataFormats/L1CSCTrackFinder/interface/CSCTFConstants.h index 52764890fe96b..6cc2c45bb7f3b 100644 --- a/DataFormats/L1CSCTrackFinder/interface/CSCTFConstants.h +++ b/DataFormats/L1CSCTrackFinder/interface/CSCTFConstants.h @@ -31,7 +31,7 @@ class CSCTFConstants { enum Digis_Info { MAX_DIGIS_PER_ALCT = 10, MAX_DIGIS_PER_CLCT = 8 }; - enum eta_info { etaBins = 1 << CSCBitWidths::kGlobalEtaBitWidth }; + static constexpr int etaBins = 1 << CSCBitWidths::kGlobalEtaBitWidth; enum MPC_stubs { maxStubs = 3 }; diff --git a/DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h b/DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h index c235c7f545ba3..ceb793e2affe1 100644 --- a/DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h +++ b/DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h @@ -49,11 +49,11 @@ class TTTrack_TrackWord { kPhiSize = 12, // Width of phi kRinvSize = 15, // Width of Rinv kValidSize = 1, // Valid bit - - kTrackWordSize = kValidSize + kRinvSize + kPhiSize + kChi2RPhiSize + kTanlSize + kZ0Size + kChi2RZSize + kD0Size + - kBendChi2Size + kHitPatternSize + kMVAQualitySize + - kMVAOtherSize, // Width of the track word in bits }; + static constexpr int kTrackWordSize = kValidSize + kRinvSize + kPhiSize + kChi2RPhiSize + kTanlSize + kZ0Size + + kChi2RZSize + kD0Size + kBendChi2Size + kHitPatternSize + kMVAQualitySize + + kMVAOtherSize, // Width of the track word in bits + ; enum TrackBitLocations { // The location of the least significant bit (LSB) and most significant bit (MSB) in the track word for different fields diff --git a/L1Trigger/GlobalCaloTrigger/interface/L1GctHtMissLut.h b/L1Trigger/GlobalCaloTrigger/interface/L1GctHtMissLut.h index 0d9243d8e8b6c..29736bd56e947 100644 --- a/L1Trigger/GlobalCaloTrigger/interface/L1GctHtMissLut.h +++ b/L1Trigger/GlobalCaloTrigger/interface/L1GctHtMissLut.h @@ -21,7 +21,7 @@ class L1GctHtMissLut : public L1GctLut<16, 12> { public: - enum numberOfBits { kHxOrHyMissComponentNBits = 8, kHtMissMagnitudeNBits = 7, kHtMissAngleNBits = 5 }; + static constexpr int kHxOrHyMissComponentNBits = 8, kHtMissMagnitudeNBits = 7, kHtMissAngleNBits = 5; // Definitions. static const int NAddress, NData; diff --git a/L1Trigger/HardwareValidation/plugins/L1DummyProducer.h b/L1Trigger/HardwareValidation/plugins/L1DummyProducer.h index 8b5abfa5fae73..c03bed7574221 100644 --- a/L1Trigger/HardwareValidation/plugins/L1DummyProducer.h +++ b/L1Trigger/HardwareValidation/plugins/L1DummyProducer.h @@ -504,20 +504,21 @@ inline void L1DummyProducer::SimpleDigi(int, //tbd: set non-trivial random values dg.clear(); // set contents to zero //CSCDetId( int iendcap, int istation, int iring, int ichamber, int ilayer = 0 ); - enum eMinNum { MIN_ENDCAP = 1, MIN_STATION = 1, MIN_RING = 1, MIN_CHAMBER = 1, MIN_LAYER = 1 }; - enum eMaxNum { MAX_ENDCAP = 2, MAX_STATION = 4, MAX_RING = 4, MAX_CHAMBER = 36, MAX_LAYER = 6 }; - float rnd = engine->flat(); - int ec = (int)(MIN_ENDCAP + (MAX_ENDCAP - MIN_ENDCAP) * rnd + 1); - int st = (int)(MIN_STATION + (MAX_STATION - MIN_STATION) * rnd + 1); - int rg = (int)(MIN_RING + (MAX_RING - MIN_RING) * rnd + 1); - int ch = (int)(MIN_CHAMBER + (MAX_CHAMBER - MIN_CHAMBER) * rnd + 1); - int lr = (int)(MIN_LAYER + (MAX_LAYER - MIN_LAYER) * rnd + 1); - CSCDetId did = CSCDetId(ec, st, rg, ch, lr); - //CSCDetId did = CSCDetId(); //DetId(DetId::Muon, MuonSubdetId::CSC) - //MuonDigiCollection::insertDigi(const IndexType& index, const DigiType& digi) - data->insertDigi(did, dg); - if (verbose()) - std::cout << "L1DummyProducer::SimpleDigi end.\n" << std::flush; + static constexpr int MIN_ENDCAP = 1, MIN_STATION = 1, MIN_RING = 1, MIN_CHAMBER = 1, MIN_LAYER = 1; + static constexpr int MAX_ENDCAP = 2, MAX_STATION = 4, MAX_RING = 4, MAX_CHAMBER = 36, MAX_LAYER = 6 +}; +float rnd = engine->flat(); +int ec = (int)(MIN_ENDCAP + (MAX_ENDCAP - MIN_ENDCAP) * rnd + 1); +int st = (int)(MIN_STATION + (MAX_STATION - MIN_STATION) * rnd + 1); +int rg = (int)(MIN_RING + (MAX_RING - MIN_RING) * rnd + 1); +int ch = (int)(MIN_CHAMBER + (MAX_CHAMBER - MIN_CHAMBER) * rnd + 1); +int lr = (int)(MIN_LAYER + (MAX_LAYER - MIN_LAYER) * rnd + 1); +CSCDetId did = CSCDetId(ec, st, rg, ch, lr); +//CSCDetId did = CSCDetId(); //DetId(DetId::Muon, MuonSubdetId::CSC) +//MuonDigiCollection::insertDigi(const IndexType& index, const DigiType& digi) +data->insertDigi(did, dg); +if (verbose()) + std::cout << "L1DummyProducer::SimpleDigi end.\n" << std::flush; } template <> diff --git a/L1Trigger/L1ExtraFromDigis/src/L1ExtraTestAnalyzer.cc b/L1Trigger/L1ExtraFromDigis/src/L1ExtraTestAnalyzer.cc index 1adebabaa6a00..5dbaa192094d6 100644 --- a/L1Trigger/L1ExtraFromDigis/src/L1ExtraTestAnalyzer.cc +++ b/L1Trigger/L1ExtraFromDigis/src/L1ExtraTestAnalyzer.cc @@ -105,7 +105,7 @@ L1ExtraTestAnalyzer::L1ExtraTestAnalyzer(const edm::ParameterSet &iConfig) "Triggers", 2 * l1extra::L1ParticleMap::kNumOfL1TriggerTypes + 1, -0.75, - l1extra::L1ParticleMap::kNumOfL1TriggerTypes + 0.5 - 0.75) { + static_cast(l1extra::L1ParticleMap::kNumOfL1TriggerTypes) + 0.5 - 0.75) { // now do what ever initialization is needed } diff --git a/L1Trigger/Phase2L1ParticleFlow/src/JetId.cc b/L1Trigger/Phase2L1ParticleFlow/src/JetId.cc index 3692ad912c6d0..611949001b85c 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/JetId.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/JetId.cc @@ -13,7 +13,7 @@ JetId::JetId(const std::string &iInput, fPt_ = std::make_unique(fNParticles_); fEta_ = std::make_unique(fNParticles_); fPhi_ = std::make_unique(fNParticles_); - fId_ = std::make_unique(fNParticles_); + fId_ = std::make_unique(fNParticles_); fCharge_ = std::make_unique(fNParticles_); fDZ_ = std::make_unique(fNParticles_); fDX_ = std::make_unique(fNParticles_); @@ -31,7 +31,7 @@ JetId::JetId(const std::string &iInput, const std::string &iOutput, const BJetTF fPt_ = std::make_unique(fNParticles_); fEta_ = std::make_unique(fNParticles_); fPhi_ = std::make_unique(fNParticles_); - fId_ = std::make_unique(fNParticles_); + fId_ = std::make_unique(fNParticles_); fCharge_ = std::make_unique(fNParticles_); fDZ_ = std::make_unique(fNParticles_); fDX_ = std::make_unique(fNParticles_); diff --git a/L1Trigger/Phase2L1ParticleFlow/src/TauNNId.cc b/L1Trigger/Phase2L1ParticleFlow/src/TauNNId.cc index 3cce460c0337c..d4d790e115610 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/TauNNId.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/TauNNId.cc @@ -17,7 +17,7 @@ TauNNId::TauNNId(const std::string &iInput, fPt_ = std::make_unique(fNParticles_); fEta_ = std::make_unique(fNParticles_); fPhi_ = std::make_unique(fNParticles_); - fId_ = std::make_unique(fNParticles_); + fId_ = std::make_unique(fNParticles_); fInput_ = iInput; } diff --git a/L1Trigger/RPCTrigger/interface/RPCConst.h b/L1Trigger/RPCTrigger/interface/RPCConst.h index a3789b3358077..84f692a6df314 100644 --- a/L1Trigger/RPCTrigger/interface/RPCConst.h +++ b/L1Trigger/RPCTrigger/interface/RPCConst.h @@ -22,16 +22,15 @@ class RPCConst { public: - enum { - ITOW_MIN = 0, //!< Minimal number of abs(m_tower_number) - ITOW_MAX = 16, //!< Maximal number of abs(m_tower_number) - //ITOW_MAX_LOWPT = 7, //!< Max m_tower number to which low_pt algorithm is used - IPT_MAX = 31, //!< Max pt bin code - NSTRIPS = 1152, //!< m_Number of Rpc strips in phi direction. - NSEG = NSTRIPS / 8, //!< m_Number of trigger segments. One segment covers 8 RPC strips - //! { ~TTStubBuilder() override; // TTStub bendOffset has this added to it, if stub truncated by FE, to indicate reason. - enum FEreject { CBCFailOffset = 500, CICFailOffset = 1000 }; + static constexpr int CBCFailOffset = 500, CICFailOffset = 1000; private: /// Data members diff --git a/L1Trigger/VertexFinder/src/VertexFinder.cc b/L1Trigger/VertexFinder/src/VertexFinder.cc index 7778f4fe4fbfa..87bde28b6bba5 100644 --- a/L1Trigger/VertexFinder/src/VertexFinder.cc +++ b/L1Trigger/VertexFinder/src/VertexFinder.cc @@ -761,464 +761,442 @@ namespace l1tVertexFinder { void VertexFinder::fastHistoEmulation() { // Relevant constants for the track word - enum TrackBitWidths { - kZ0Size = 12, // Width of z-position (40cm / 0.1) - kZ0MagSize = 5, // Width of z-position magnitude (signed) - kPtSize = 14, // Width of pt - kPtMagSize = 9, // Width of pt magnitude (unsigned) - kReducedPrecisionPt = 7, // Width of the reduced precision, integer only, pt - }; - - enum HistogramBitWidths { - 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 = - ((1 << HistogramBitWidths::kSumPtLinkSize) - 1) * HistogramBitWidths::kWindowSize; - - typedef ap_ufixed pt_t; - // Same size as TTTrack_TrackWord::z0_t, but now taking into account the sign bit (i.e. 2's complement) - typedef ap_int z0_t; - // 7 bits chosen to represent values between [0,127] - // This is the next highest power of 2 value to our chosen track pt saturation value (100) - typedef ap_ufixed - track_pt_fixed_t; - // Histogram bin index - typedef ap_uint histbin_t; - // Histogram bin in fixed point representation, before truncation - typedef ap_ufixed - 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 - histbin_pt_sum_fixed_t; - // This value is slightly arbitrary, but small enough that the windows sums aren't too big. - typedef ap_ufixed - link_pt_sum_fixed_t; - // Enough bits to store HistogramBitWidths::kWindowSize * (2**HistogramBitWidths::kSumPtLinkSize) - typedef ap_ufixed - window_pt_sum_fixed_t; - // pt weighted sum of bins in window - typedef ap_fixed - zsliding_t; - // Sum of histogram bins in window - typedef ap_uint slidingsum_t; - // Inverse of sum of bins in a given window - typedef ap_ufixed - inverse_t; - - auto track_quality_check = [&](const track_pt_fixed_t& pt) -> bool { - // Track quality cuts - if (pt.to_double() < settings_->vx_TrackMinPt()) - return false; - return true; - }; - - auto fetch_bin = [&](const z0_t& z0, int nbins) -> std::pair { - // Increase the the number of bits in the word to allow for additional dynamic range - ap_int z0_13 = z0; - // Add a number equal to half of the range in z0, meaning that the range is now [0, 2*z0_max] - ap_int absz0_13 = z0_13 + (1 << (TrackBitWidths::kZ0Size - 1)); - // Shift the bits down to truncate the dynamic range to the most significant HistogramBitWidths::kBinFixedSize bits - ap_int absz0_13_reduced = - absz0_13 >> (TrackBitWidths::kZ0Size - HistogramBitWidths::kBinFixedSize); - // Put the relevant bits into the histbin_t container - histbin_t bin = absz0_13_reduced.range(HistogramBitWidths::kBinFixedSize - 1, 0); + static constexpr int kZ0Size = 12, // Width of z-position (40cm / 0.1) + kZ0MagSize = 5, // Width of z-position magnitude (signed) + kPtSize = 14, // Width of pt + kPtMagSize = 9, // Width of pt magnitude (unsigned) + kReducedPrecisionPt = 7, // Width of the reduced precision, integer only, pt + ; + + static constexpr int + 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(kWindowSize * (1 << kSumPtLinkSize)), + // Number of bits to represent the untruncated sum of track pts in a single bin from a single link + kSumPtUntruncatedLinkSize = kPtSize + 2, kSumPtUntruncatedLinkMagSize = kPtMagSize + 2, + }; + + static constexpr unsigned int kTableSize = ((1 << kSumPtLinkSize) - 1) * kWindowSize; + + typedef ap_ufixed pt_t; + // Same size as TTTrack_TrackWord::z0_t, but now taking into account the sign bit (i.e. 2's complement) + typedef ap_int z0_t; + // 7 bits chosen to represent values between [0,127] + // This is the next highest power of 2 value to our chosen track pt saturation value (100) + typedef ap_ufixed track_pt_fixed_t; + // Histogram bin index + typedef ap_uint histbin_t; + // Histogram bin in fixed point representation, before truncation + typedef ap_ufixed 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 histbin_pt_sum_fixed_t; + // This value is slightly arbitrary, but small enough that the windows sums aren't too big. + typedef ap_ufixed link_pt_sum_fixed_t; + // Enough bits to store kWindowSize * (2**kSumPtLinkSize) + typedef ap_ufixed window_pt_sum_fixed_t; + // pt weighted sum of bins in window + typedef ap_fixed zsliding_t; + // Sum of histogram bins in window + typedef ap_uint slidingsum_t; + // Inverse of sum of bins in a given window + typedef ap_ufixed inverse_t; + + auto track_quality_check = [&](const track_pt_fixed_t& pt) -> bool { + // Track quality cuts + if (pt.to_double() < settings_->vx_TrackMinPt()) + return false; + return true; + }; + + auto fetch_bin = [&](const z0_t& z0, int nbins) -> std::pair { + // Increase the the number of bits in the word to allow for additional dynamic range + ap_int z0_13 = z0; + // Add a number equal to half of the range in z0, meaning that the range is now [0, 2*z0_max] + ap_int absz0_13 = z0_13 + (1 << (kZ0Size - 1)); + // Shift the bits down to truncate the dynamic range to the most significant kBinFixedSize bits + ap_int absz0_13_reduced = absz0_13 >> (kZ0Size - kBinFixedSize); + // Put the relevant bits into the histbin_t container + histbin_t bin = absz0_13_reduced.range(kBinFixedSize - 1, 0); - if (settings_->debug() > 2) { - edm::LogInfo("VertexProducer") - << "fastHistoEmulation::fetchBin() Checking the mapping from z0 to bin index ... \n" - << "histbin_fixed_t(1.0 / settings_->vx_histogram_binwidth()) = " - << histbin_fixed_t(1.0 / settings_->vx_histogram_binwidth()) << "\n" - << "histbin_t(std::floor(nbins / 2) = " << histbin_t(std::floor(nbins / 2.)) << "\n" - << "z0 = " << z0 << "\n" - << "bin = " << bin; - } - bool valid = true; - if (bin < 0) { - return std::make_pair(0, false); - } else if (bin > (nbins - 1)) { - return std::make_pair(0, false); - } - return std::make_pair(bin, valid); - }; - - // Replace with https://stackoverflow.com/questions/13313980/populate-an-array-using-constexpr-at-compile-time ? - auto init_inversion_table = [&]() -> std::vector { - std::vector table_out(kTableSize, 0.); - for (unsigned int ii = 0; ii < kTableSize; ii++) { - // Compute lookup table function. This matches the format of the GTT HLS code. - // Biased generation f(x) = 1 / (x + 1) is inverted by g(y) = inversion(x - 1) = 1 / (x - 1 + 1) = 1 / y - table_out.at(ii) = (1.0 / (ii + 1)); - } - return table_out; - }; - - auto inversion = [&](slidingsum_t& data_den) -> inverse_t { - std::vector inversion_table = init_inversion_table(); - - // Index into the lookup table based on data - int index; - if (data_den < 0) - data_den = 0; - if (data_den > (kTableSize - 1)) - data_den = kTableSize - 1; - index = data_den; - return inversion_table.at(index); - }; - - auto bin_center = [&](zsliding_t iz, int nbins) -> l1t::VertexWord::vtxz0_t { - zsliding_t z = iz - histbin_t(std::floor(nbins / 2.)); - std::unique_ptr log; - if (settings_->debug() >= 1) { - log = std::make_unique("VertexProducer"); - *log << "bin_center information ...\n" - << "iz = " << iz << "\n" - << "histbin_t(std::floor(nbins / 2.)) = " << histbin_t(std::floor(nbins / 2.)) << "\n" - << "binwidth = " << zsliding_t(settings_->vx_histogram_binwidth()) << "\n" - << "z = " << z << "\n" - << "zsliding_t(z * zsliding_t(binwidth)) = " << std::setprecision(7) - << l1t::VertexWord::vtxz0_t(z * zsliding_t(settings_->vx_histogram_binwidth())); - } - return l1t::VertexWord::vtxz0_t(z * zsliding_t(settings_->vx_histogram_binwidth())); - }; - - auto weighted_position = [&](histbin_t b_max, - const std::vector& binpt, - slidingsum_t maximums, - int nbins) -> zsliding_t { - zsliding_t zvtx_sliding = 0; - slidingsum_t zvtx_sliding_sum = 0; - inverse_t inv = 0; - - std::unique_ptr log; - if (settings_->debug() >= 1) { - log = std::make_unique("VertexProducer"); - *log << "Progression of weighted_position() ...\n" - << "zvtx_sliding_sum = "; - } - - // Find the weighted position within the window in index space (width = 1) - for (ap_uint w = 0; w < HistogramBitWidths::kWindowSize; ++w) { - zvtx_sliding_sum += (binpt.at(w) * w); - if (settings_->debug() >= 1) { - *log << "(" << w << " * " << binpt.at(w) << ")"; - if (w < HistogramBitWidths::kWindowSize - 1) { - *log << " + "; - } - } - } - - if (settings_->debug() >= 1) { - *log << " = " << zvtx_sliding_sum << "\n"; - } + if (settings_->debug() > 2) { + edm::LogInfo("VertexProducer") + << "fastHistoEmulation::fetchBin() Checking the mapping from z0 to bin index ... \n" + << "histbin_fixed_t(1.0 / settings_->vx_histogram_binwidth()) = " + << histbin_fixed_t(1.0 / settings_->vx_histogram_binwidth()) << "\n" + << "histbin_t(std::floor(nbins / 2) = " << histbin_t(std::floor(nbins / 2.)) << "\n" + << "z0 = " << z0 << "\n" + << "bin = " << bin; + } + bool valid = true; + if (bin < 0) { + return std::make_pair(0, false); + } else if (bin > (nbins - 1)) { + return std::make_pair(0, false); + } + return std::make_pair(bin, valid); + }; + + // Replace with https://stackoverflow.com/questions/13313980/populate-an-array-using-constexpr-at-compile-time ? + auto init_inversion_table = [&]() -> std::vector { + std::vector table_out(kTableSize, 0.); + for (unsigned int ii = 0; ii < kTableSize; ii++) { + // Compute lookup table function. This matches the format of the GTT HLS code. + // Biased generation f(x) = 1 / (x + 1) is inverted by g(y) = inversion(x - 1) = 1 / (x - 1 + 1) = 1 / y + table_out.at(ii) = (1.0 / (ii + 1)); + } + return table_out; + }; + + auto inversion = [&](slidingsum_t& data_den) -> inverse_t { + std::vector inversion_table = init_inversion_table(); + + // Index into the lookup table based on data + int index; + if (data_den < 0) + data_den = 0; + if (data_den > (kTableSize - 1)) + data_den = kTableSize - 1; + index = data_den; + return inversion_table.at(index); + }; + + auto bin_center = [&](zsliding_t iz, int nbins) -> l1t::VertexWord::vtxz0_t { + zsliding_t z = iz - histbin_t(std::floor(nbins / 2.)); + std::unique_ptr log; + if (settings_->debug() >= 1) { + log = std::make_unique("VertexProducer"); + *log << "bin_center information ...\n" + << "iz = " << iz << "\n" + << "histbin_t(std::floor(nbins / 2.)) = " << histbin_t(std::floor(nbins / 2.)) << "\n" + << "binwidth = " << zsliding_t(settings_->vx_histogram_binwidth()) << "\n" + << "z = " << z << "\n" + << "zsliding_t(z * zsliding_t(binwidth)) = " << std::setprecision(7) + << l1t::VertexWord::vtxz0_t(z * zsliding_t(settings_->vx_histogram_binwidth())); + } + return l1t::VertexWord::vtxz0_t(z * zsliding_t(settings_->vx_histogram_binwidth())); + }; + + auto weighted_position = [&](histbin_t b_max, + const std::vector& binpt, + slidingsum_t maximums, + int nbins) -> zsliding_t { + zsliding_t zvtx_sliding = 0; + slidingsum_t zvtx_sliding_sum = 0; + inverse_t inv = 0; + + std::unique_ptr log; + if (settings_->debug() >= 1) { + log = std::make_unique("VertexProducer"); + *log << "Progression of weighted_position() ...\n" + << "zvtx_sliding_sum = "; + } - if (maximums != 0) { - //match F/W inversion_lut offset (inversion[x] = 1 / (x + 1); inversion[x - 1] = 1 / x;), for consistency - slidingsum_t offsetmaximums = maximums - 1; - inv = inversion(offsetmaximums); - zvtx_sliding = zvtx_sliding_sum * inv; - } else { - zvtx_sliding = (settings_->vx_windowSize() / 2.0) + (((int(settings_->vx_windowSize()) % 2) != 0) ? 0.5 : 0.0); - } + // Find the weighted position within the window in index space (width = 1) + for (ap_uint w = 0; w < kWindowSize; ++w) { + zvtx_sliding_sum += (binpt.at(w) * w); if (settings_->debug() >= 1) { - *log << "inversion(" << maximums << ") = " << inv << "\nzvtx_sliding = " << zvtx_sliding << "\n"; + *log << "(" << w << " * " << binpt.at(w) << ")"; + if (w < kWindowSize - 1) { + *log << " + "; + } } + } - // Add the starting index plus half an index to shift the z position to its weighted position (still in inxex space) within all of the bins - zvtx_sliding += b_max; - zvtx_sliding += ap_ufixed<1, 0>(0.5); - if (settings_->debug() >= 1) { - *log << "b_max = " << b_max << "\n"; - *log << "zvtx_sliding + b_max + 0.5 = " << zvtx_sliding << "\n"; - } + if (settings_->debug() >= 1) { + *log << " = " << zvtx_sliding_sum << "\n"; + } - // Shift the z position from index space into z [cm] space - zvtx_sliding = bin_center(zvtx_sliding, nbins); - if (settings_->debug() >= 1) { - *log << "bin_center(zvtx_sliding + b_max + 0.5, nbins) = " << std::setprecision(7) << zvtx_sliding; - log.reset(); - } - return zvtx_sliding; - }; + if (maximums != 0) { + //match F/W inversion_lut offset (inversion[x] = 1 / (x + 1); inversion[x - 1] = 1 / x;), for consistency + slidingsum_t offsetmaximums = maximums - 1; + inv = inversion(offsetmaximums); + zvtx_sliding = zvtx_sliding_sum * inv; + } else { + zvtx_sliding = (settings_->vx_windowSize() / 2.0) + (((int(settings_->vx_windowSize()) % 2) != 0) ? 0.5 : 0.0); + } + if (settings_->debug() >= 1) { + *log << "inversion(" << maximums << ") = " << inv << "\nzvtx_sliding = " << zvtx_sliding << "\n"; + } - // 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() + 1; - std::vector hist(nbins, 0); - std::vector hist_untruncated(nbins, 0); + // Add the starting index plus half an index to shift the z position to its weighted position (still in inxex space) within all of the bins + zvtx_sliding += b_max; + zvtx_sliding += ap_ufixed<1, 0>(0.5); + if (settings_->debug() >= 1) { + *log << "b_max = " << b_max << "\n"; + *log << "zvtx_sliding + b_max + 0.5 = " << zvtx_sliding << "\n"; + } - // Loop over the tracks and fill the histogram - if (settings_->debug() > 2) { - edm::LogInfo("VertexProducer") << "fastHistoEmulation::Processing " << fitTracks_.size() << " tracks"; + // Shift the z position from index space into z [cm] space + zvtx_sliding = bin_center(zvtx_sliding, nbins); + if (settings_->debug() >= 1) { + *log << "bin_center(zvtx_sliding + b_max + 0.5, nbins) = " << std::setprecision(7) << zvtx_sliding; + log.reset(); } - for (const L1Track& track : fitTracks_) { - // Get the track pt and z0 - // Convert them to an appropriate data format - // 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); - z0_t tkZ0 = track.getTTTrackPtr()->getZ0Word(); - - if ((settings_->vx_DoQualityCuts() && track_quality_check(tkpt)) || (!settings_->vx_DoQualityCuts())) { - // - // Check bin validity of bin found for the current track - // - std::pair bin = fetch_bin(tkZ0, nbins); - assert(bin.first >= 0 && bin.first < nbins); - - // - // If the bin is valid then sum the tracks - // - if (settings_->debug() > 2) { - edm::LogInfo("VertexProducer") << "fastHistoEmulation::Checking the track word ... \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) - << ")\tbin = " << bin.first.to_int() << "\n" - << "pt sum in bin " << bin.first.to_int() - << " BEFORE adding track = " << hist_untruncated.at(bin.first).to_double(); - } - if (bin.second) { - 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_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) << ")"; - } + return zvtx_sliding; + }; + + // 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() + 1; + std::vector hist(nbins, 0); + std::vector hist_untruncated(nbins, 0); + + // Loop over the tracks and fill the histogram + if (settings_->debug() > 2) { + edm::LogInfo("VertexProducer") << "fastHistoEmulation::Processing " << fitTracks_.size() << " tracks"; + } + for (const L1Track& track : fitTracks_) { + // Get the track pt and z0 + // Convert them to an appropriate data format + // 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); + z0_t tkZ0 = track.getTTTrackPtr()->getZ0Word(); + + if ((settings_->vx_DoQualityCuts() && track_quality_check(tkpt)) || (!settings_->vx_DoQualityCuts())) { + // + // Check bin validity of bin found for the current track + // + std::pair bin = fetch_bin(tkZ0, nbins); + assert(bin.first >= 0 && bin.first < nbins); + + // + // If the bin is valid then sum the tracks + // + if (settings_->debug() > 2) { + edm::LogInfo("VertexProducer") << "fastHistoEmulation::Checking the track word ... \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) + << ")\tbin = " << bin.first.to_int() << "\n" + << "pt sum in bin " << bin.first.to_int() + << " BEFORE adding track = " << hist_untruncated.at(bin.first).to_double(); } - } // 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 (bin.second) { + 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_untruncated.at(bin.first).to_double(); + } + } else { 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) << ")"; + 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) << ")"; } } + } // 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( + kSumPtUntruncatedLinkSize - 1, kSumPtUntruncatedLinkSize - 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 hist_window_sums(nsums, 0); - for (unsigned int b = 0; b < nsums; ++b) { - for (unsigned int w = 0; w < HistogramBitWidths::kWindowSize; ++w) { - unsigned int index = b + w; - hist_window_sums.at(b) += hist.at(index); - } + // 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 hist_window_sums(nsums, 0); + for (unsigned int b = 0; b < nsums; ++b) { + for (unsigned int w = 0; w < kWindowSize; ++w) { + unsigned int index = b + w; + hist_window_sums.at(b) += hist.at(index); } + } - // Find the top N vertices - std::vector found; - found.reserve(settings_->vx_nvtx()); - for (unsigned int ivtx = 0; ivtx < settings_->vx_nvtx(); ivtx++) { - histbin_t b_max = 0; - window_pt_sum_fixed_t max_pt = 0; - zsliding_t zvtx_sliding = -999; - std::vector binpt_max(HistogramBitWidths::kWindowSize, 0); + // Find the top N vertices + std::vector found; + found.reserve(settings_->vx_nvtx()); + for (unsigned int ivtx = 0; ivtx < settings_->vx_nvtx(); ivtx++) { + histbin_t b_max = 0; + window_pt_sum_fixed_t max_pt = 0; + zsliding_t zvtx_sliding = -999; + std::vector binpt_max(kWindowSize, 0); - // Find the maxima of the sums - for (unsigned int i = 0; i < hist_window_sums.size(); i++) { - // Skip this window if it will already be returned - if (find(found.begin(), found.end(), i) != found.end()) - continue; - if (hist_window_sums.at(i) > max_pt) { - b_max = i; - max_pt = hist_window_sums.at(b_max); - std::copy(std::begin(hist) + b_max, - std::begin(hist) + b_max + HistogramBitWidths::kWindowSize, - std::begin(binpt_max)); - - // Find the weighted position only for the highest sum pt window - zvtx_sliding = weighted_position(b_max, binpt_max, max_pt, nbins); - } + // Find the maxima of the sums + for (unsigned int i = 0; i < hist_window_sums.size(); i++) { + // Skip this window if it will already be returned + if (find(found.begin(), found.end(), i) != found.end()) + continue; + if (hist_window_sums.at(i) > max_pt) { + b_max = i; + max_pt = hist_window_sums.at(b_max); + std::copy(std::begin(hist) + b_max, std::begin(hist) + b_max + kWindowSize, std::begin(binpt_max)); + + // Find the weighted position only for the highest sum pt window + zvtx_sliding = weighted_position(b_max, binpt_max, max_pt, nbins); } - if (settings_->debug() >= 1) { - edm::LogInfo log("VertexProducer"); - log << "fastHistoEmulation::Checking the output parameters ... \n"; - if (found.empty()) { - printHistogram(log, hist, 80, 0, -1, "fastHistoEmulation::hist", "\e[92m"); - printHistogram( - log, hist_window_sums, 80, 0, -1, "fastHistoEmulation::hist_window_sums", "\e[92m"); - } - printHistogram( - log, binpt_max, 80, 0, -1, "fastHistoEmulation::binpt_max", "\e[92m"); - log << "bin index (not a VertexWord parameter) = " << b_max << "\n" - << "sumPt = " << max_pt.to_double() << "\n" - << "z0 = " << zvtx_sliding.to_double(); + } + if (settings_->debug() >= 1) { + edm::LogInfo log("VertexProducer"); + log << "fastHistoEmulation::Checking the output parameters ... \n"; + if (found.empty()) { + printHistogram(log, hist, 80, 0, -1, "fastHistoEmulation::hist", "\e[92m"); + printHistogram( + log, hist_window_sums, 80, 0, -1, "fastHistoEmulation::hist_window_sums", "\e[92m"); } - found.push_back(b_max); - verticesEmulation_.emplace_back(l1t::VertexWord::vtxvalid_t(1), - l1t::VertexWord::vtxz0_t(zvtx_sliding), - l1t::VertexWord::vtxmultiplicity_t(0), - l1t::VertexWord::vtxsumpt_t(max_pt), - l1t::VertexWord::vtxquality_t(0), - l1t::VertexWord::vtxinversemult_t(0), - l1t::VertexWord::vtxunassigned_t(0)); + printHistogram( + log, binpt_max, 80, 0, -1, "fastHistoEmulation::binpt_max", "\e[92m"); + log << "bin index (not a VertexWord parameter) = " << b_max << "\n" + << "sumPt = " << max_pt.to_double() << "\n" + << "z0 = " << zvtx_sliding.to_double(); } - pv_index_ = 0; - } // end of fastHistoEmulation - - void VertexFinder::NNVtxEmulation(tensorflow::Session* TrackWeightSesh, - tensorflow::Session* PatternRecSesh, - tensorflow::Session* AssociationSesh) { - // #### Weight Tracks: #### - // Loop over tracks -> weight the network -> set track weights - tensorflow::Tensor inputTrkWeight(tensorflow::DT_FLOAT, {1, 3}); //Single batch of 3 values - uint counter = 0; - - for (auto& track : fitTracks_) { - // Quantised Network: Use values from L1GTTInputProducer pT, MVA1, eta - auto& gttTrack = fitTracks_.at(counter); + found.push_back(b_max); + verticesEmulation_.emplace_back(l1t::VertexWord::vtxvalid_t(1), + l1t::VertexWord::vtxz0_t(zvtx_sliding), + l1t::VertexWord::vtxmultiplicity_t(0), + l1t::VertexWord::vtxsumpt_t(max_pt), + l1t::VertexWord::vtxquality_t(0), + l1t::VertexWord::vtxinversemult_t(0), + l1t::VertexWord::vtxunassigned_t(0)); + } + pv_index_ = 0; +} // end of fastHistoEmulation - TTTrack_TrackWord::tanl_t etaEmulationBits = gttTrack.getTTTrackPtr()->getTanlWord(); - ap_fixed<16, 3> etaEmulation; - etaEmulation.V = (etaEmulationBits.range()); +void VertexFinder::NNVtxEmulation(tensorflow::Session* TrackWeightSesh, + tensorflow::Session* PatternRecSesh, + tensorflow::Session* AssociationSesh) { + // #### Weight Tracks: #### + // Loop over tracks -> weight the network -> set track weights + tensorflow::Tensor inputTrkWeight(tensorflow::DT_FLOAT, {1, 3}); //Single batch of 3 values + uint counter = 0; - ap_uint<14> ptEmulationBits = gttTrack.getTTTrackPtr()->getTrackWord()( - TTTrack_TrackWord::TrackBitLocations::kRinvMSB - 1, TTTrack_TrackWord::TrackBitLocations::kRinvLSB); - ap_ufixed<14, 9> ptEmulation; - ptEmulation.V = (ptEmulationBits.range()); + for (auto& track : fitTracks_) { + // Quantised Network: Use values from L1GTTInputProducer pT, MVA1, eta + auto& gttTrack = fitTracks_.at(counter); - ap_ufixed<22, 9> ptEmulation_rescale; - ptEmulation_rescale = ptEmulation.to_double(); + TTTrack_TrackWord::tanl_t etaEmulationBits = gttTrack.getTTTrackPtr()->getTanlWord(); + ap_fixed<16, 3> etaEmulation; + etaEmulation.V = (etaEmulationBits.range()); - ap_ufixed<22, 9> etaEmulation_rescale; - etaEmulation_rescale = abs(etaEmulation.to_double()); + ap_uint<14> ptEmulationBits = gttTrack.getTTTrackPtr()->getTrackWord()( + TTTrack_TrackWord::TrackBitLocations::kRinvMSB - 1, TTTrack_TrackWord::TrackBitLocations::kRinvLSB); + ap_ufixed<14, 9> ptEmulation; + ptEmulation.V = (ptEmulationBits.range()); - ap_ufixed<22, 9> MVAEmulation_rescale; - MVAEmulation_rescale = gttTrack.getTTTrackPtr()->getMVAQualityBits(); + ap_ufixed<22, 9> ptEmulation_rescale; + ptEmulation_rescale = ptEmulation.to_double(); - inputTrkWeight.tensor()(0, 0) = ptEmulation_rescale.to_double(); - inputTrkWeight.tensor()(0, 1) = MVAEmulation_rescale.to_double(); - inputTrkWeight.tensor()(0, 2) = etaEmulation_rescale.to_double(); + ap_ufixed<22, 9> etaEmulation_rescale; + etaEmulation_rescale = abs(etaEmulation.to_double()); - // CNN output: track weight - std::vector outputTrkWeight; - tensorflow::run(TrackWeightSesh, {{"weight:0", inputTrkWeight}}, {"Identity:0"}, &outputTrkWeight); - // Set track weight pack into tracks: + ap_ufixed<22, 9> MVAEmulation_rescale; + MVAEmulation_rescale = gttTrack.getTTTrackPtr()->getMVAQualityBits(); - ap_ufixed<16, 5> NNOutput; - NNOutput = (double)outputTrkWeight[0].tensor()(0, 0); + inputTrkWeight.tensor()(0, 0) = ptEmulation_rescale.to_double(); + inputTrkWeight.tensor()(0, 1) = MVAEmulation_rescale.to_double(); + inputTrkWeight.tensor()(0, 2) = etaEmulation_rescale.to_double(); - //std::cout<<"NNOutput_weight_network = "<< NNOutput < outputTrkWeight; + tensorflow::run(TrackWeightSesh, {{"weight:0", inputTrkWeight}}, {"Identity:0"}, &outputTrkWeight); + // Set track weight pack into tracks: - track.setWeight(NNOutput.to_double()); + ap_ufixed<16, 5> NNOutput; + NNOutput = (double)outputTrkWeight[0].tensor()(0, 0); - ++counter; - } - // #### Find Vertices: #### - tensorflow::Tensor inputPV(tensorflow::DT_FLOAT, - {1, settings_->vx_histogram_numbins(), 1}); //Single batch with 256 bins and 1 weight - std::vector outputPV; - RecoVertexCollection vertices(settings_->vx_histogram_numbins()); - std::map vertexMap; - std::map histogram; - std::map nnOutput; + //std::cout<<"NNOutput_weight_network = "<< NNOutput <vx_histogram_binwidth(); + track.setWeight(NNOutput.to_double()); - int track_z = 0; + ++counter; + } + // #### Find Vertices: #### + tensorflow::Tensor inputPV(tensorflow::DT_FLOAT, + {1, settings_->vx_histogram_numbins(), 1}); //Single batch with 256 bins and 1 weight + std::vector outputPV; + RecoVertexCollection vertices(settings_->vx_histogram_numbins()); + std::map vertexMap; + std::map histogram; + std::map nnOutput; - for (int z = 0; z < settings_->vx_histogram_numbins(); z += 1) { - counter = 0; - double vxWeight = 0; + float binWidth = settings_->vx_histogram_binwidth(); - for (const L1Track& track : fitTracks_) { - auto& gttTrack = fitTracks_.at(counter); - double temp_z0 = gttTrack.getTTTrackPtr()->z0(); + int track_z = 0; - track_z = std::floor((temp_z0 + settings_->vx_histogram_max()) / binWidth); + for (int z = 0; z < settings_->vx_histogram_numbins(); z += 1) { + counter = 0; + double vxWeight = 0; - if (track_z >= z && track_z < (z + 1)) { - vertices.at(z).insert(&track); - vxWeight += track.weight(); - } - ++counter; - } - // Get centre of bin before setting z0 - vertices.at(z).setZ0(((z + 0.5) * binWidth) - settings_->vx_histogram_max()); + for (const L1Track& track : fitTracks_) { + auto& gttTrack = fitTracks_.at(counter); + double temp_z0 = gttTrack.getTTTrackPtr()->z0(); - vertexMap[vxWeight] = z; - inputPV.tensor()(0, z, 0) = vxWeight; - //Fill histogram for 3 bin sliding window: - histogram[z] = vxWeight; - } + track_z = std::floor((temp_z0 + settings_->vx_histogram_max()) / binWidth); - // Run PV Network: - tensorflow::run(PatternRecSesh, {{"hist:0", inputPV}}, {"Identity:0"}, &outputPV); - // Threshold needed due to rounding differences in internal CNN layer emulation versus firmware - const float histogrammingThreshold_ = 0.0; - for (int i(0); i < settings_->vx_histogram_numbins(); ++i) { - if (outputPV[0].tensor()(0, i, 0) >= histogrammingThreshold_) { - nnOutput[i] = outputPV[0].tensor()(0, i, 0); + if (track_z >= z && track_z < (z + 1)) { + vertices.at(z).insert(&track); + vxWeight += track.weight(); } + ++counter; } + // Get centre of bin before setting z0 + vertices.at(z).setZ0(((z + 0.5) * binWidth) - settings_->vx_histogram_max()); - //Find max then find all occurances of it in histogram and average their position -> python argmax layer - //Performance is not optimised for multiple peaks in histogram or spread peaks these are edge cases, need to revisit - int max_index = 0; - int num_maxes = 0; - float max_element = 0.0; - for (int i(0); i < settings_->vx_histogram_numbins(); ++i) { - if (nnOutput[i] > max_element) { - max_element = nnOutput[i]; - } + vertexMap[vxWeight] = z; + inputPV.tensor()(0, z, 0) = vxWeight; + //Fill histogram for 3 bin sliding window: + histogram[z] = vxWeight; + } + + // Run PV Network: + tensorflow::run(PatternRecSesh, {{"hist:0", inputPV}}, {"Identity:0"}, &outputPV); + // Threshold needed due to rounding differences in internal CNN layer emulation versus firmware + const float histogrammingThreshold_ = 0.0; + for (int i(0); i < settings_->vx_histogram_numbins(); ++i) { + if (outputPV[0].tensor()(0, i, 0) >= histogrammingThreshold_) { + nnOutput[i] = outputPV[0].tensor()(0, i, 0); } + } - for (int i(0); i < settings_->vx_histogram_numbins(); ++i) { - if (nnOutput[i] == max_element) { - num_maxes++; - max_index += i; - } + //Find max then find all occurances of it in histogram and average their position -> python argmax layer + //Performance is not optimised for multiple peaks in histogram or spread peaks these are edge cases, need to revisit + int max_index = 0; + int num_maxes = 0; + float max_element = 0.0; + for (int i(0); i < settings_->vx_histogram_numbins(); ++i) { + if (nnOutput[i] > max_element) { + max_element = nnOutput[i]; + } + } + + for (int i(0); i < settings_->vx_histogram_numbins(); ++i) { + if (nnOutput[i] == max_element) { + num_maxes++; + max_index += i; } - int PV_index = ceil((float)max_index / (float)num_maxes); + } + int PV_index = ceil((float)max_index / (float)num_maxes); - edm::LogVerbatim("VertexFinder") << " NNVtxEmulation Chosen PV: prob: " << nnOutput[PV_index] - << " bin = " << PV_index << " z0 = " << vertices.at(PV_index).z0() << '\n'; + edm::LogVerbatim("VertexFinder") << " NNVtxEmulation Chosen PV: prob: " << nnOutput[PV_index] << " bin = " << PV_index + << " z0 = " << vertices.at(PV_index).z0() << '\n'; - verticesEmulation_.emplace_back(1, vertices.at(PV_index).z0(), 0, vertices.at(PV_index).pt(), 0, 0, 0); + verticesEmulation_.emplace_back(1, vertices.at(PV_index).z0(), 0, vertices.at(PV_index).pt(), 0, 0, 0); - } // end of NNVtx Algorithm +} // end of NNVtx Algorithm } // namespace l1tVertexFinder