diff --git a/Configuration/StandardSequences/python/L1TrackTrigger_cff.py b/Configuration/StandardSequences/python/L1TrackTrigger_cff.py index 213f0c82c7c5e..197bac97529e7 100644 --- a/Configuration/StandardSequences/python/L1TrackTrigger_cff.py +++ b/Configuration/StandardSequences/python/L1TrackTrigger_cff.py @@ -2,10 +2,10 @@ from L1Trigger.TrackTrigger.TrackTrigger_cff import * from SimTracker.TrackTriggerAssociation.TrackTriggerAssociator_cff import * -from L1Trigger.TrackerDTC.ProducerED_cff import * +from L1Trigger.TrackerDTC.DTC_cff import * from L1Trigger.TrackFindingTracklet.L1HybridEmulationTracks_cff import * -L1TrackTrigger=cms.Sequence(TrackTriggerClustersStubs*TrackTriggerAssociatorClustersStubs*TrackerDTCProducer) +L1TrackTrigger=cms.Sequence(TrackTriggerClustersStubs*TrackTriggerAssociatorClustersStubs*ProducerDTC) # Customisation to enable TTTracks in geometry D41 and later (corresponding to phase2_trackerV14 or later). Includes the HGCAL L1 trigger _tttracks_l1tracktrigger = L1TrackTrigger.copy() diff --git a/DataFormats/L1TrackTrigger/interface/TTBV.h b/DataFormats/L1TrackTrigger/interface/TTBV.h index f18f96cacd900..f05b348cc8471 100644 --- a/DataFormats/L1TrackTrigger/interface/TTBV.h +++ b/DataFormats/L1TrackTrigger/interface/TTBV.h @@ -1,6 +1,8 @@ #ifndef DataFormats_L1TrackTrigger_TTBV_h #define DataFormats_L1TrackTrigger_TTBV_h +#include "FWCore/Utilities/interface/Exception.h" + #include #include #include @@ -20,16 +22,13 @@ class TTBV { public: static constexpr int S_ = 64; // Frame width of emp infrastructure f/w, max number of bits a TTBV can handle - private: bool twos_; // Two's complement (true) or binary (false) int size_; // number or bits std::bitset bs_; // underlying storage - public: // constructor: default TTBV() : twos_(false), size_(0), bs_() {} - // constructor: double precision (IEEE 754); from most to least significant bit: 1 bit sign + 11 bit binary exponent + 52 bit binary mantisse TTBV(const double d) : twos_(false), size_(S_) { int index(0); @@ -42,14 +41,17 @@ class TTBV { } // constructor: unsigned int value - TTBV(unsigned long long int value, int size) : twos_(false), size_(size), bs_(value) {} + TTBV(unsigned long long int value, int size) : twos_(false), size_(size), bs_(value) { checkU(value); } // constructor: int value TTBV(int value, int size, bool twos = false) - : twos_(twos), size_(size), bs_((!twos || value >= 0) ? value : value + iMax()) {} + : twos_(twos), size_(size), bs_((!twos || value >= 0) ? value : value + iMax()) { + checkI(value); + } // constructor: double value + precision, biased (floor) representation - TTBV(double value, double base, int size, bool twos = false) : TTBV((int)std::floor(value / base), size, twos) {} + TTBV(double value, double base, int size, bool twos = false) + : TTBV((int)std::floor(value / base + 1.e-12), size, twos) {} // constructor: string TTBV(const std::string& str, bool twos = false) : twos_(twos), size_(str.size()), bs_(str) {} @@ -70,10 +72,15 @@ class TTBV { // underlying storage const std::bitset& bs() const { return bs_; } - // access: single bit + // access: single bit value bool operator[](int pos) const { return bs_[pos]; } + + // access: single bit reference std::bitset::reference operator[](int pos) { return bs_[pos]; } + // access: single bit value with bounds check + bool test(int pos) const { return bs_.test(pos); } + // access: most significant bit copy bool msb() const { return bs_[size_ - 1]; } @@ -95,31 +102,31 @@ class TTBV { // operator: boolean and TTBV& operator&=(const TTBV& rhs) { - const int m(std::max(size_, rhs.size())); - this->resize(m); - TTBV bv(rhs); - bv.resize(m); - bs_ &= bv.bs_; + bs_ &= rhs.bs_; return *this; } + // operator: boolean and + TTBV operator&&(const TTBV& rhs) { + TTBV copy(*this); + return copy &= rhs; + } + // operator: boolean or TTBV& operator|=(const TTBV& rhs) { - const int m(std::max(size_, rhs.size())); - this->resize(m); - TTBV bv(rhs); - bv.resize(m); - bs_ |= bv.bs_; + bs_ |= rhs.bs_; return *this; } + // operator: boolean or + TTBV operator||(const TTBV& rhs) { + TTBV copy(*this); + return copy |= rhs; + } + // operator: boolean xor TTBV& operator^=(const TTBV& rhs) { - const int m(std::max(size_, rhs.size())); - this->resize(m); - TTBV bv(rhs); - bv.resize(m); - bs_ ^= bv.bs_; + bs_ ^= rhs.bs_; return *this; } @@ -242,7 +249,7 @@ class TTBV { bs_.set(n, msb); size_ = size; } else if (size < size_ && size > 0) { - this->operator<<=(size - size_); + this->operator<<=(size_ - size); if (twos_) this->msb() = msb; } @@ -281,11 +288,18 @@ class TTBV { // maniplulation and conversion: extracts range based to int reinterpret sign and removes these bits int extract(int size, bool twos = false) { - double val = this->val(size, 0, twos); + int val = this->val(size, 0, twos); this->operator>>=(size); return val; } + // maniplulation and conversion: extracts bool and removes this bit + bool extract() { + bool val = bs_[0]; + this->operator>>=(1); + return val; + } + // manipulation: extracts slice and removes these bits TTBV slice(int size, bool twos = false) { TTBV ttBV(*this, size, 0, twos); @@ -310,6 +324,14 @@ class TTBV { return size_; } + // position of least significant '1' or '0' in range [begin, end) + int plEncode(int begin, int end, bool b = true) const { + for (int e = begin; e < end; e++) + if (bs_.test(e) == b) + return e; + return size_; + } + // position of most significant '1' or '0' int pmEncode(bool b = true) const { for (int e = size_ - 1; e > -1; e--) @@ -318,6 +340,14 @@ class TTBV { return size_; } + // position of most significant '1' or '0' in range [begin, end) + int pmEncode(int begin, int end, bool b = true) const { + for (int e = end - 1; e >= begin; e--) + if (bs_.test(e) == b) + return e; + return end; + } + // position for n'th '1' or '0' counted from least to most significant bit int encode(int n, bool b = true) const { int sum(0); @@ -344,17 +374,58 @@ class TTBV { private: // look up table initializer for powers of 2 - constexpr std::array powersOfTwo() const { - std::array lut = {}; - for (int i = 0; i < S_; i++) + constexpr std::array powersOfTwo() const { + std::array lut = {}; + for (int i = 0; i <= S_; i++) lut[i] = std::pow(2, i); return lut; } // returns 2 ** size_ - unsigned long long int iMax() const { - static const std::array lut = powersOfTwo(); - return lut[size_]; + double iMax() const { + static const std::array lut = powersOfTwo(); + return std::round(lut[size_]); + } + + // check if value fits into binary BV + void checkU(unsigned long long int value) { + if (size_ == 0) + return; + if (value < iMax()) + return; + cms::Exception exception("RunTimeError."); + exception << "Value " << value << " does not fit into a " << size_ << "b binary."; + exception.addContext("TTBV::checkU"); + throw exception; + } + + // check if value fits into twos's complement BV + void checkT(int value) { + if (size_ == 0) + return; + static const std::array lut = powersOfTwo(); + auto abs = [](int val) { return val < 0 ? std::abs(val) - 1 : val; }; + if (abs(value) < std::round(lut[size_ - 1])) + return; + cms::Exception exception("RunTimeError."); + exception << "Value " << value << " does not fit into a " << size_ << "b two's complement."; + exception.addContext("TTBV::checkT"); + throw exception; + } + + // check if value fits into twos complement / binary BV + void checkI(int value) { + if (size_ == 0) + return; + if (twos_) + checkT(value); + else if (value < 0) { + cms::Exception exception("RunTimeError."); + exception << size_ << "b Binary TTBV constructor called with negative value (" << value << ")."; + exception.addContext("TTBV::checkI"); + throw exception; + } else + checkU(value); } }; diff --git a/DataFormats/L1TrackTrigger/src/TTDTC.cc b/DataFormats/L1TrackTrigger/src/TTDTC.cc index 241866ae1b0a4..2cd234e798a7e 100644 --- a/DataFormats/L1TrackTrigger/src/TTDTC.cc +++ b/DataFormats/L1TrackTrigger/src/TTDTC.cc @@ -3,10 +3,6 @@ #include -using namespace std; -using namespace edm; -using namespace tt; - TTDTC::TTDTC(int numRegions, int numOverlappingRegions, int numDTCsPerRegion) : numRegions_(numRegions), numOverlappingRegions_(numOverlappingRegions), @@ -15,13 +11,13 @@ TTDTC::TTDTC(int numRegions, int numOverlappingRegions, int numDTCsPerRegion) regions_(numRegions_), channels_(numDTCsPerTFP_), streams_(numRegions_ * numDTCsPerTFP_) { - iota(regions_.begin(), regions_.end(), 0); - iota(channels_.begin(), channels_.end(), 0); + std::iota(regions_.begin(), regions_.end(), 0); + std::iota(channels_.begin(), channels_.end(), 0); } // write one specific stream of TTStubRefs using DTC identifier (region[0-8], board[0-23], channel[0-1]) // dtcRegions aka detector regions are defined by tk layout -void TTDTC::setStream(int dtcRegion, int dtcBoard, int dtcChannel, const StreamStub& stream) { +void TTDTC::setStream(int dtcRegion, int dtcBoard, int dtcChannel, const tt::StreamStub& stream) { // check arguments const bool oorRegion = dtcRegion >= numRegions_ || dtcRegion < 0; const bool oorBoard = dtcBoard >= numDTCsPerRegion_ || dtcBoard < 0; @@ -45,7 +41,7 @@ void TTDTC::setStream(int dtcRegion, int dtcBoard, int dtcChannel, const StreamS // read one specific stream of TTStubRefs using TFP identifier (region[0-8], channel[0-47]) // tfpRegions aka processing regions are rotated by -0.5 region width w.r.t detector regions -const StreamStub& TTDTC::stream(int tfpRegion, int tfpChannel) const { +const tt::StreamStub& TTDTC::stream(int tfpRegion, int tfpChannel) const { // check arguments const bool oorRegion = tfpRegion >= numRegions_ || tfpRegion < 0; const bool oorChannel = tfpChannel >= numDTCsPerTFP_ || tfpChannel < 0; @@ -65,25 +61,25 @@ const StreamStub& TTDTC::stream(int tfpRegion, int tfpChannel) const { // total number of frames int TTDTC::size() const { - auto all = [](int sum, const StreamStub& stream) { return sum + stream.size(); }; - return accumulate(streams_.begin(), streams_.end(), 0, all); + auto all = [](int sum, const tt::StreamStub& stream) { return sum + stream.size(); }; + return std::accumulate(streams_.begin(), streams_.end(), 0, all); } // total number of stubs int TTDTC::nStubs() const { - auto stubs = [](int sum, const FrameStub& frame) { return sum + frame.first.isNonnull(); }; + auto stubs = [](int sum, const tt::FrameStub& frame) { return sum + frame.first.isNonnull(); }; int n(0); - for (const StreamStub& stream : streams_) - n += accumulate(stream.begin(), stream.end(), 0, stubs); + for (const tt::StreamStub& stream : streams_) + n += std::accumulate(stream.begin(), stream.end(), 0, stubs); return n; } // total number of gaps int TTDTC::nGaps() const { - auto gaps = [](int sum, const FrameStub& frame) { return sum + frame.first.isNull(); }; + auto gaps = [](int sum, const tt::FrameStub& frame) { return sum + frame.first.isNull(); }; int n(0); - for (const StreamStub& stream : streams_) - n += accumulate(stream.begin(), stream.end(), 0, gaps); + for (const tt::StreamStub& stream : streams_) + n += std::accumulate(stream.begin(), stream.end(), 0, gaps); return n; } diff --git a/DataFormats/WrappedStdDictionaries/src/classes_def.xml b/DataFormats/WrappedStdDictionaries/src/classes_def.xml index b179ffd11dd41..2329c0045ec33 100644 --- a/DataFormats/WrappedStdDictionaries/src/classes_def.xml +++ b/DataFormats/WrappedStdDictionaries/src/classes_def.xml @@ -56,4 +56,5 @@ + diff --git a/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker.cc b/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker.cc index 215a34b0bb41a..1de56430c9a50 100644 --- a/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker.cc +++ b/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker.cc @@ -2653,7 +2653,7 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even myFake = 1; myTP_pdgid = my_tp->pdgId(); - if (my_tp->genParticles().size() > 0) { + if (!my_tp->genParticles().empty()) { myTP_mother_pdgid = my_tp->genParticles().at(0)->mother(0)->pdgId(); } myTP_pt = my_tp->p4().pt(); diff --git a/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker_cfg.py b/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker_cfg.py index 34ddd5a71b531..d775d2731af79 100644 --- a/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker_cfg.py +++ b/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker_cfg.py @@ -81,8 +81,8 @@ # DTC emulation -process.load('L1Trigger.TrackerDTC.ProducerED_cff') -process.dtc = cms.Path(process.TrackerDTCProducer) +process.load('L1Trigger.TrackerDTC.DTC_cff') +process.dtc = cms.Path(process.ProducerDTC) process.load("L1Trigger.TrackFindingTracklet.L1HybridEmulationTracks_cff") process.load("L1Trigger.L1TTrackMatch.l1tTrackSelectionProducer_cfi") diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ctLayer1_dumpFiles_fromRAW_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ctLayer1_dumpFiles_fromRAW_cfg.py index c0a15ebcdff85..5b9f89f76d3a2 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ctLayer1_dumpFiles_fromRAW_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ctLayer1_dumpFiles_fromRAW_cfg.py @@ -33,8 +33,7 @@ process.load('Configuration.StandardSequences.SimL1Emulator_cff') process.load('L1Trigger.TrackTrigger.TrackTrigger_cff') process.load("L1Trigger.TrackFindingTracklet.L1HybridEmulationTracks_cff") -process.load("L1Trigger.TrackerDTC.ProducerES_cff") -process.load("L1Trigger.TrackerDTC.ProducerED_cff") +process.load("L1Trigger.TrackerDTC.DTC_cff") process.load("RecoVertex.BeamSpotProducer.BeamSpot_cfi") process.l1tLayer1Barrel9 = process.l1tLayer1Barrel.clone() @@ -52,7 +51,7 @@ process.PFInputsTask = cms.Task( process.TTClustersFromPhase2TrackerDigis, process.TTStubsFromPhase2TrackerDigis, - process.TrackerDTCProducer, + process.ProducerDTC, process.offlineBeamSpot, process.l1tTTTracksFromTrackletEmulation, process.SimL1EmulatorTask diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_fromRAW_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_fromRAW_cfg.py index c519341d5963e..7ddaf341bbce9 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_fromRAW_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_fromRAW_cfg.py @@ -33,8 +33,7 @@ process.load('Configuration.StandardSequences.SimL1Emulator_cff') process.load('L1Trigger.TrackTrigger.TrackTrigger_cff') process.load("L1Trigger.TrackFindingTracklet.L1HybridEmulationTracks_cff") -process.load("L1Trigger.TrackerDTC.ProducerES_cff") -process.load("L1Trigger.TrackerDTC.ProducerED_cff") +process.load("L1Trigger.TrackerDTC.DTC_cff") process.load("RecoVertex.BeamSpotProducer.BeamSpot_cfi") from L1Trigger.Phase2L1ParticleFlow.l1tSeedConePFJetProducer_cfi import l1tSeedConePFJetEmulatorProducer @@ -69,7 +68,7 @@ process.PFInputsTask = cms.Task( process.TTClustersFromPhase2TrackerDigis, process.TTStubsFromPhase2TrackerDigis, - process.TrackerDTCProducer, + process.ProducerDTC, process.offlineBeamSpot, process.l1tTTTracksFromTrackletEmulation, process.SimL1EmulatorTask diff --git a/L1Trigger/TrackFindingTMTT/interface/L1track3D.h b/L1Trigger/TrackFindingTMTT/interface/L1track3D.h index 3b3b7dc77e3a2..de47f64ffc396 100644 --- a/L1Trigger/TrackFindingTMTT/interface/L1track3D.h +++ b/L1Trigger/TrackFindingTMTT/interface/L1track3D.h @@ -72,6 +72,32 @@ namespace tmtt { : L1track3D( settings, stubs, cellLocationHT, helixRphi, helixRz, 0.0, iPhiSec, iEtaReg, optoLinkID, mergedHTcell) {} + // KF emulator: constructor + L1track3D(Settings* settings, + std::vector stubs, + double qOverPt, + double phi0, + double z0, + double tanLambda, + double helixD0, + int iPhiSec, + int iEtaReg) + : settings_(settings), + stubs_(std::move(stubs)), + nLayers_(0), + cellLocationHT_(0, 0), + helixRphi_(qOverPt, phi0), + helixRz_(z0, tanLambda), + helixD0_(helixD0), + iPhiSec_(iPhiSec), + iEtaReg_(iEtaReg), + optoLinkID_(0), + mergedHTcell_(false), + seedLayerType_(TrackletSeedType()), + seedPS_(0), + matchedTP_(nullptr), + nMatchedLayers_(0) {} + ~L1track3D() override = default; //--- Set/get optional info for tracklet tracks. diff --git a/L1Trigger/TrackFindingTMTT/interface/Stub.h b/L1Trigger/TrackFindingTMTT/interface/Stub.h index 526e8944d63b7..bbbcc6980f678 100644 --- a/L1Trigger/TrackFindingTMTT/interface/Stub.h +++ b/L1Trigger/TrackFindingTMTT/interface/Stub.h @@ -69,6 +69,19 @@ namespace tmtt { const DegradeBend* degradeBend, const StubKiller* stubKiller); + // KF emualtor: stub constructor + Stub(const TTStubRef& ttStubRef, + double r, + double phi, + double z, + int layerId, + int layerIdReduced, + double stripPitch, + double stripLength, + bool psModule, + bool barrel, + bool tiltedBarrel); + bool operator==(const Stub& stubOther) { return (this->index() == stubOther.index()); } // Return reference to original TTStub. diff --git a/L1Trigger/TrackFindingTMTT/python/TMTrackProducer_Defaults_cfi.py b/L1Trigger/TrackFindingTMTT/python/TMTrackProducer_Defaults_cfi.py index 83d6d3763bdda..fc9ed066f1287 100644 --- a/L1Trigger/TrackFindingTMTT/python/TMTrackProducer_Defaults_cfi.py +++ b/L1Trigger/TrackFindingTMTT/python/TMTrackProducer_Defaults_cfi.py @@ -358,7 +358,7 @@ #--- Options for Kalman filter track fitters --- # # Larger number has more debug printout. "1" is useful for understanding why tracks are lost, best combined with TrackFitCheat=True. - KalmanDebugLevel = cms.uint32(0), + KalmanDebugLevel = cms.uint32(2), # Fit will reject fitted tracks unless it can assign at least this number of stubs to them. KalmanMinNumStubs = cms.uint32(4), # Fit will attempt to add up to this nummber of stubs to each fitted tracks, but won't bother adding more. diff --git a/L1Trigger/TrackFindingTMTT/src/Settings.cc b/L1Trigger/TrackFindingTMTT/src/Settings.cc index 8f54fec900240..2a782e407840b 100644 --- a/L1Trigger/TrackFindingTMTT/src/Settings.cc +++ b/L1Trigger/TrackFindingTMTT/src/Settings.cc @@ -39,7 +39,7 @@ namespace tmtt { // Kalman filter track fit cfg kalmanDebugLevel_(0), - //kalmanDebugLevel_(2), // Good for debugging + //kalmanDebugLevel_(2), // Good for debugging kalmanMinNumStubs_(4), kalmanMaxNumStubs_(6), kalmanAddBeamConstr_(false), // Apply post-fit beam-spot constraint to 5-param fit diff --git a/L1Trigger/TrackFindingTMTT/src/Stub.cc b/L1Trigger/TrackFindingTMTT/src/Stub.cc index 094a36d9bbc92..3a61edd624563 100644 --- a/L1Trigger/TrackFindingTMTT/src/Stub.cc +++ b/L1Trigger/TrackFindingTMTT/src/Stub.cc @@ -158,6 +158,53 @@ namespace tmtt { } } + // KF emualtor: stub constructor + Stub::Stub(const TTStubRef& ttStubRef, + double r, + double phi, + double z, + int layerId, + int layerIdReduced, + double stripPitch, + double stripLength, + bool psModule, + bool barrel, + bool tiltedBarrel) + : ttStubRef_(ttStubRef), + settings_(nullptr), + index_in_vStubs_(0), + phi_(phi), + r_(r), + z_(z), + bend_(0.), + dphiOverBend_(0.), + min_qOverPt_bin_(0), + max_qOverPt_bin_(0), + localU_cluster_({{0., 0.}}), + localV_cluster_({{0., 0.}}), + iphi_(0), + alpha_(0.), + frontendPass_(false), + stubFailedDegradeWindow_(false), + bendInFrontend_(0), + numMergedBend_(0), + assocTP_(nullptr), + assocTPs_(set()), + assocTPofCluster_({{nullptr, nullptr}}), + digitalStub_(nullptr), + lastDigiStep_(DigiStage()), + digitizeWarningsOn_(false), + trackerModule_(nullptr), + degradeBend_(nullptr), + layerId_(layerId), + layerIdReduced_(layerIdReduced), + stripPitch_(stripPitch), + stripLength_(stripLength), + nStrips_(0), + psModule_(psModule), + barrel_(barrel), + tiltedBarrel_(tiltedBarrel) {} + //=== Calculate bin range along q/Pt axis of r-phi Hough transform array consistent with bend of this stub. void Stub::calcQoverPtrange() { diff --git a/L1Trigger/TrackFindingTracklet/README.md b/L1Trigger/TrackFindingTracklet/README.md index f0ce377f62a95..f9b647c77ed00 100644 --- a/L1Trigger/TrackFindingTracklet/README.md +++ b/L1Trigger/TrackFindingTracklet/README.md @@ -1,20 +1,17 @@ -To run the L1 tracking & create a TTree of tracking performance: +To run the L1 tracking & create a TTree of tracking performance: cmsRun L1TrackNtupleMaker_cfg.py -By setting variable L1TRKALGO inside this script, you can change which -L1 tracking algo is used. It defaults to HYBRID. +By setting variable L1TRKALGO inside this script, you can change which L1 tracking algo is used. It defaults to HYBRID, which runs Tracklet pattern reco followed by old Kalman track fit. -For the baseline HYBRID algo, which runs Tracklet pattern reco followed -by KF track fit, TrackFindingTracklet/interface/Settings.h configures the pattern reco stage, (although some parameters there are overridden by l1tTTTracksFromTrackletEmulation_cfi.py). -The KF fit is configured by the constructor of TrackFindingTMTT/src/Settings.cc. +The version of the hybrid algorithm that corresponds to the current firmware, and includes the new Kalman track fit, can be run by changing L1TRKALGO=HYBRID_NEWKF. It is not yet the default for MC production, as it's tracking performance is not quite has good as HYBRID. e.g. Only a basic duplicate track removal is available for it. -The ROOT macros L1TrackNtuplePlot.C & L1TrackQualityPlot.C make track -performance & BDT track quality performance plots from the TTree. -Both can be run via makeHists.csh . +Displaced Hybrid tracking can be run by setting L1TRKALGO=HYBRID_DISPLACED. + +The ROOT macros L1TrackNtuplePlot.C & L1TrackQualityPlot.C make track performance & BDT track quality performance plots from the TTree. Both can be run via makeHists.csh . + +If you need to modify the cfg params of the algorithm, then TrackFindingTracklet/interface/Settings.h configures the pattern reco stage, (although some parameters there are overridden by l1tTTTracksFromTrackletEmulation_cfi.py). The old KF fit is configured by the constructor of TrackFindingTMTT/src/Settings.cc. The DTC and new KF fit are configured via TrackTrigger/python/ProducerSetup_cfi.py. -The optional "NewKF" track fit can be run by changing L1TRKALGO=HYBRID_NEWKF. It corresponds to the curent FW, but is is not yet the default, as only a basic duplicate track removal is available for it. It is configured via -TrackTrigger/python/ProducerSetup_cfi.py, (which also configures the DTC). For experts ============ diff --git a/L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h b/L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h index c4d644d41d56b..c21985a384714 100644 --- a/L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h +++ b/L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h @@ -19,31 +19,46 @@ namespace trklet { */ class ChannelAssignment { public: + struct Config { + std::vector tmMuxOrder_; + int tmNumLayers_; + int tmWidthStubId_; + int tmWidthCot_; + int numComparisonModules_; + int minIdenticalStubs_; + std::vector seedTypeNames_; + int numChannelsStub_; + std::vector> seedTypesSeedLayers_; + std::vector> seedTypesProjectionLayers_; + int maxNumProjectionLayers_; + std::vector channelEncoding_; + std::vector offsetsStubs_; + int numSeedingLayers_; + std::vector tmMuxOrderInt_; + }; ChannelAssignment() {} - ChannelAssignment(const edm::ParameterSet& iConfig, const tt::Setup* setup); + ChannelAssignment(const Config& iConfig, const tt::Setup* setup); ~ChannelAssignment() {} + // helper class to store configurations + const tt::Setup* setup() const { return setup_; } // returns channelId of given TTTrackRef from TrackBuilder int channelId(const TTTrackRef& ttTrackRef) const; // number of used TB channels for tracks int numChannelsTrack() const { return numChannelsTrack_; } // number of used TB channels for stubs int numChannelsStub() const { return numChannelsStub_; } - // number of bits used to represent layer id [barrel: 0-5, discs: 6-10] - int widthLayerId() const { return widthLayerId_; } + // + const std::vector& tmMuxOrder() const { return tmMuxOrderInt_; } + // number of layers per rtack + int tmNumLayers() const { return tmNumLayers_; } // number of bits used to represent stub id for projected stubs - int widthStubId() const { return widthStubId_; } - // number of bits used to represent stub id for seed stubs - int widthSeedStubId() const { return widthSeedStubId_; } - // number of bits used to distinguish between tilted and untilded barrel modules or 2S and PS endcap modules - int widthPSTilt() const { return widthPSTilt_; } - // depth of fifos within systolic array - int depthMemory() const { return depthMemory_; } + int tmWidthStubId() const { return tmWidthStubId_; } + // + int tmWidthCot() const { return tmWidthCot_; } // number of comparison modules used in each DR node int numComparisonModules() const { return numComparisonModules_; } // min number of shared stubs to identify duplicates int minIdenticalStubs() const { return minIdenticalStubs_; } - // number of DR nodes - int numNodesDR() const { return numNodesDR_; } // number of used seed types in tracklet algorithm int numSeedTypes() const { return numSeedTypes_; } // sets layerId (0-7 in sequence the seed type projects to) of given TTStubRef and seedType, returns false if seeed stub @@ -66,34 +81,22 @@ namespace trklet { int channelId(int seedType, int layerId) const; // max number of seeding layers int numSeedingLayers() const { return numSeedingLayers_; } - // return DR node for given ttTrackRef - int nodeDR(const TTTrackRef& ttTrackRef) const; private: // helper class to store configurations const tt::Setup* setup_; - // DRin parameter - edm::ParameterSet pSetDRin_; - // number of bits used to represent layer id [barrel: 0-5, discs: 6-10] - int widthLayerId_; + // + std::vector tmMuxOrder_; + // number of layers per rtack + int tmNumLayers_; // number of bits used to represent stub id for projected stubs - int widthStubId_; - // number of bits used to represent stub id for seed stubs - int widthSeedStubId_; - // number of bits used to distinguish between tilted and untilded barrel modules or 2S and PS endcap modules - int widthPSTilt_; - // depth of fifos within systolic array - int depthMemory_; - // positive pt Boundaries in GeV (symmetric negatives are assumed), first boundary is pt cut, last boundary is infinity, defining ot bins used by DR - std::vector ptBoundaries_; - // DRin parameter - edm::ParameterSet pSetDR_; + int tmWidthStubId_; + // + int tmWidthCot_; // number of comparison modules used in each DR node int numComparisonModules_; // min number of shared stubs to identify duplicates [default: 3] int minIdenticalStubs_; - // number of DR nodes - int numNodesDR_; // seed type names std::vector seedTypeNames_; // number of used seed types in tracklet algorithm @@ -114,6 +117,8 @@ namespace trklet { std::vector offsetsStubs_; // max number of seeding layers int numSeedingLayers_; + // + std::vector tmMuxOrderInt_; }; } // namespace trklet diff --git a/L1Trigger/TrackFindingTracklet/interface/DataFormats.h b/L1Trigger/TrackFindingTracklet/interface/DataFormats.h new file mode 100644 index 0000000000000..a0f1e9d398ad8 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/DataFormats.h @@ -0,0 +1,485 @@ +#ifndef L1Trigger_TrackFindingTracklet_DataFormats_h +#define L1Trigger_TrackFindingTracklet_DataFormats_h + +/*---------------------------------------------------------------------- +Classes to calculate and provide dataformats used by Hybrid emulator +enabling automated conversions from frames to stubs/tracks and vice versa +In data members of classes Stub* & Track* below, the variables describing +stubs/tracks are stored both in digitial format as a 64b word in frame_, +and in undigitized format in an std::tuple. (This saves CPU) +----------------------------------------------------------------------*/ + +#include "FWCore/Framework/interface/data_default_record_trait.h" +#include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h" +#include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "DataFormats/L1TrackTrigger/interface/TTBV.h" + +#include +#include +#include +#include +#include +#include + +namespace trklet { + + // hybrid processes + enum class Process { begin, tm = begin, dr, kf, tfp, end, x }; + // hybrid variables + enum class Variable { begin, stubId = begin, r, phi, z, dPhi, dZ, inv2R, phiT, cot, zT, end, x }; + // hybrid process order + constexpr std::initializer_list Processes = {Process::tm, Process::dr, Process::kf, Process::tfp}; + // conversion: Process to int + inline constexpr int operator+(Process p) { return static_cast(p); } + // conversion: Variable to int + inline constexpr int operator+(Variable v) { return static_cast(v); } + // increment of Process + inline constexpr Process operator++(Process p) { return Process(+p + 1); } + // increment of Variable + inline constexpr Variable operator++(Variable v) { return Variable(+v + 1); } + + //Base class representing format of a variable + class DataFormat { + public: + DataFormat(bool twos, bool biased = true) : twos_(twos), width_(0), base_(1.), range_(0.) {} + DataFormat(bool twos, int width, double base, double range) + : twos_(twos), width_(width), base_(base), range_(range) {} + DataFormat() {} + virtual ~DataFormat() {} + // converts int to bitvector + TTBV ttBV(int i) const { return TTBV(i, width_, twos_); } + // converts double to bitvector + TTBV ttBV(double d) const { return TTBV(d, base_, width_, twos_); } + // extracts int from bitvector, removing these bits from bitvector + void extract(TTBV& in, int& out) const { out = in.extract(width_, twos_); } + // extracts double from bitvector, removing these bits from bitvector + void extract(TTBV& in, double& out) const { out = in.extract(base_, width_, twos_); } + // extracts double from bitvector, removing these bits from bitvector + void extract(TTBV& in, TTBV& out) const { out = in.slice(width_, twos_); } + // extracts bool from bitvector, removing these bits from bitvector + void extract(TTBV& in, bool& out) const { out = in.extract(); } + // attaches integer to bitvector + void attach(const int i, TTBV& ttBV) const { ttBV += TTBV(i, width_, twos_); } + // attaches double to bitvector + void attach(const double d, TTBV& ttBV) const { ttBV += TTBV(d, base_, width_, twos_); } + // attaches bitvector to bitvector + void attach(const TTBV& bv, TTBV& ttBV) const { ttBV += bv; } + // converts int to double + double floating(int i) const { return (i + .5) * base_; } + // converts double to int + int integer(double d) const { return std::floor(d / base_ + 1.e-12); } + // converts double to int and back to double + double digi(double d) const { return floating(integer(d)); } + // converts binary integer value to twos complement integer value + int toSigned(int i) const { return i - std::pow(2, width_) / 2; } + // converts twos complement integer value to binary integer value + int toUnsigned(int i) const { return i + std::pow(2, width_) / 2; } + // converts floating point value to binary integer value + int toUnsigned(double d) const { return this->integer(d) + std::pow(2, width_) / 2; } + // biggest representable floating point value + //double limit() const { return (range_ - base_) / (twos_ ? 2. : 1.); } + // returns false if data format would oferflow for this double value + bool inRange(double d, bool digi = true) const { + const double range = digi ? base_ * pow(2, width_) : range_; + return d >= -range / 2. && d < range / 2.; + } + // returns false if data format would oferflow for this int value + bool inRange(int i) const { return inRange(floating(i)); } + // true if twos'complement or false if binary representation is chosen + bool twos() const { return twos_; } + // number of used bits + int width() const { return width_; } + // precision + double base() const { return base_; } + // covered range + double range() const { return range_; } + + protected: + // true if twos'complement or false if binary representation is chosen + bool twos_; + // number of used bits + int width_; + // precision + double base_; + // covered range + double range_; + }; + + // function template for DataFormat generation + template + DataFormat makeDataFormat(const ChannelAssignment* ca); + + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca); + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca); + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca); + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca); + + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca); + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca); + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca); + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca); + + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca); + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca); + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca); + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca); + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca); + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca); + + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca); + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca); + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca); + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca); + + /*! \class trklet::DataFormats + * \brief Class to calculate and provide dataformats used by Hybrid emulator + * \author Thomas Schuh + * \date 2024, Sep + */ + class DataFormats { + private: + // variable flavour mapping, Each row below declares which processing steps use the variable named in the comment at the end of the row + static constexpr std::array, +Variable::end> config_ = {{ + // Process::tm Process::dr Process::kf Process::tfp + {{Process::tm, Process::x, Process::x, Process::x}}, // Variable::stubId + {{Process::tm, Process::tm, Process::tm, Process::x}}, // Variable::r + {{Process::tm, Process::tm, Process::tm, Process::x}}, // Variable::phi + {{Process::tm, Process::tm, Process::tm, Process::x}}, // Variable::z + {{Process::tm, Process::tm, Process::tm, Process::x}}, // Variable::dPhi + {{Process::tm, Process::tm, Process::tm, Process::x}}, // Variable::dZ + {{Process::tm, Process::tm, Process::kf, Process::tfp}}, // Variable::inv2R + {{Process::tm, Process::tm, Process::kf, Process::tfp}}, // Variable::phiT + {{Process::tm, Process::tm, Process::kf, Process::tfp}}, // Variable::cot + {{Process::tm, Process::tm, Process::kf, Process::tfp}} // Variable::zT + }}; + // stub word assembly, shows which stub variables are used by each process + static constexpr std::array, +Process::end> stubs_ = {{ + {Variable::stubId, Variable::r, Variable::phi, Variable::z}, // Process::tm + {Variable::r, Variable::phi, Variable::z, Variable::dPhi, Variable::dZ}, // Process::dr + {Variable::r, Variable::phi, Variable::z, Variable::dPhi, Variable::dZ}, // Process::kf + {} // Process::tfp + }}; + // track word assembly, shows which track variables are used by each process + static constexpr std::array, +Process::end> tracks_ = {{ + {Variable::inv2R, Variable::phiT, Variable::zT}, // Process::tm + {Variable::inv2R, Variable::phiT, Variable::zT}, // Process::dr + {Variable::inv2R, Variable::phiT, Variable::cot, Variable::zT}, // Process::kf + {} // Process::tfp + }}; + + public: + DataFormats(); + DataFormats(const ChannelAssignment* ca); + ~DataFormats() = default; + // converts bits to ntuple of variables + template + void convertStub(Process p, const tt::Frame& bv, std::tuple& data) const { + TTBV ttBV(bv); + extractStub(p, ttBV, data); + } + // converts ntuple of variables to bits + template + void convertStub(Process p, const std::tuple& data, tt::Frame& bv) const { + TTBV ttBV(1, numUnusedBitsStubs_[+p]); + attachStub(p, data, ttBV); + bv = ttBV.bs(); + } + // converts bits to ntuple of variables + template + void convertTrack(Process p, const tt::Frame& bv, std::tuple& data) const { + TTBV ttBV(bv); + extractTrack(p, ttBV, data); + } + // converts ntuple of variables to bits + template + void convertTrack(Process p, const std::tuple& data, tt::Frame& bv) const { + TTBV ttBV(1, numUnusedBitsTracks_[+p]); + attachTrack(p, data, ttBV); + bv = ttBV.bs(); + } + // access to run-time constants + const tt::Setup* setup() const { return channelAssignment_->setup(); } + // number of bits being used for specific variable flavour + int width(Variable v, Process p) const { return formats_[+v][+p]->width(); } + // precision being used for specific variable flavour + double base(Variable v, Process p) const { return formats_[+v][+p]->base(); } + // covered range for specific variable flavour + double range(Variable v, Process p) const { return formats_[+v][+p]->range(); } + // access to spedific format + const DataFormat& format(Variable v, Process p) const { return *formats_[+v][+p]; } + + private: + // number of unique data formats + int numDataFormats_; + // method to count number of unique data formats + template + void countFormats(); + // constructs data formats of all unique used variables and flavours + template + void fillDataFormats(); + // helper (loop) data formats of all unique used variables and flavours + template + void fillFormats(); + // helper (loop) to convert bits to ntuple of variables + template + void extractStub(Process p, TTBV& ttBV, std::tuple& data) const { + Variable v = *std::next(stubs_[+p].begin(), sizeof...(Ts) - 1 - it); + formats_[+v][+p]->extract(ttBV, std::get(data)); + if constexpr (it + 1 != sizeof...(Ts)) + extractStub(p, ttBV, data); + } + // helper (loop) to convert bits to ntuple of variables + template + void extractTrack(Process p, TTBV& ttBV, std::tuple& data) const { + Variable v = *std::next(tracks_[+p].begin(), sizeof...(Ts) - 1 - it); + formats_[+v][+p]->extract(ttBV, std::get(data)); + if constexpr (it + 1 != sizeof...(Ts)) + extractTrack(p, ttBV, data); + } + // helper (loop) to convert ntuple of variables to bits + template + void attachStub(Process p, const std::tuple& data, TTBV& ttBV) const { + Variable v = *std::next(stubs_[+p].begin(), it); + formats_[+v][+p]->attach(std::get(data), ttBV); + if constexpr (it + 1 != sizeof...(Ts)) + attachStub(p, data, ttBV); + } + // helper (loop) to convert ntuple of variables to bits + template + void attachTrack(Process p, const std::tuple& data, TTBV& ttBV) const { + Variable v = *std::next(tracks_[+p].begin(), it); + formats_[+v][+p]->attach(std::get(data), ttBV); + if constexpr (it + 1 != sizeof...(Ts)) + attachTrack(p, data, ttBV); + } + // stored run-time constants + const ChannelAssignment* channelAssignment_; + // collection of unique formats + std::vector dataFormats_; + // variable flavour mapping + std::vector> formats_; + // number of unused frame bits for a all Stub flavours + std::vector numUnusedBitsStubs_; + // number of unused frame bits for a all Track flavours + std::vector numUnusedBitsTracks_; + }; + + // base class to represent stubs + template + class Stub { + public: + // construct Stub from Frame + Stub(const tt::FrameStub& fs, const DataFormats* df, Process p) : dataFormats_(df), p_(p), frame_(fs) { + dataFormats_->convertStub(p_, frame_.second, data_); + } + template + // construct Stub from other Stub + Stub(const Stub& stub, Ts... data) + : dataFormats_(stub.dataFormats()), p_(++stub.p()), frame_(stub.frame()), data_(data...) { + dataFormats_->convertStub(p_, data_, frame_.second); + } + // construct Stub from TTStubRef + Stub(const TTStubRef& ttStubRef, const DataFormats* df, Process p, Ts... data) + : dataFormats_(df), p_(p), frame_(ttStubRef, tt::Frame()), data_(data...) { + dataFormats_->convertStub(p_, data_, frame_.second); + } + Stub() {} + ~Stub() {} + // true if frame valid, false if gap in data stream + explicit operator bool() const { return frame_.first.isNonnull(); } + // access to DataFormats + const DataFormats* dataFormats() const { return dataFormats_; } + // stub flavour + Process p() const { return p_; } + // acess to frame + const tt::FrameStub& frame() const { return frame_; } + + protected: + // all dataformats + const DataFormats* dataFormats_; + // stub flavour + Process p_; + // underlying TTStubRef and bitvector + tt::FrameStub frame_; + // ntuple of variables this stub is assemled of + std::tuple data_; + }; + + // class to represent stubs generated by process TrackMulitplexer + class StubTM : public Stub { + public: + // construct StubTM from Frame + StubTM(const tt::FrameStub& fs, const DataFormats* df) : Stub(fs, df, Process::tm) {} + // construct StubTM from TTStubRef + StubTM(const TTStubRef& ttStubRef, const DataFormats* df, int stubId, double r, double phi, double z) + : Stub(ttStubRef, df, Process::tm, stubId, r, phi, z) {} + ~StubTM() {} + // stub Id + int stubId() const { return std::get<0>(data_); } + // stub radius wrt chosenRofPhi + double r() const { return std::get<1>(data_); } + // stub phi wrt processing nonant centre + double phi() const { return std::get<2>(data_); } + // stub z + double z() const { return std::get<3>(data_); } + }; + + // class to represent stubs generated by process DuplicateRemoval + class StubDR : public Stub { + public: + // construct StubDR from Frame + StubDR(const tt::FrameStub& fs, const DataFormats* df) : Stub(fs, df, Process::dr) {} + // construct StubDR from StubTM + StubDR(const StubTM& stub, double r, double phi, double z, double dPhi, double dZ) + : Stub(stub, r, phi, z, dPhi, dZ) {} + ~StubDR() {} + // stub radius wrt chosenRofPhi + double r() const { return std::get<0>(data_); } + // stub phi wrt phi sector centre + double phi() const { return std::get<1>(data_); } + // stub z residual wrt eta sector + double z() const { return std::get<2>(data_); } + // stub phi uncertainty + double dPhi() const { return std::get<3>(data_); } + // stub z uncertainty + double dZ() const { return std::get<4>(data_); } + }; + + // class to represent stubs generated by process KalmanFilter + class StubKF : public Stub { + public: + // construct StubKF from Frame + StubKF(const tt::FrameStub& fs, const DataFormats* df) : Stub(fs, df, Process::kf) {} + // construct StubKF from StubDR + StubKF(const StubDR& stub, double r, double phi, double z, double dPhi, double dZ) + : Stub(stub, r, phi, z, dPhi, dZ) {} + ~StubKF() {} + // stub radius wrt chosenRofPhi + double r() const { return std::get<0>(data_); }; + // stub phi residual wrt track parameter + double phi() const { return std::get<1>(data_); }; + // stub z residual wrt eta sector + double z() const { return std::get<2>(data_); }; + // stub phi uncertainty + double dPhi() const { return std::get<3>(data_); } + // stub z uncertainty + double dZ() const { return std::get<4>(data_); } + }; + + // base class to represent tracks + template + class Track { + public: + // construct Track from Frame + Track(const tt::FrameTrack& ft, const DataFormats* df, Process p) : dataFormats_(df), p_(p), frame_(ft) { + dataFormats_->convertTrack(p_, frame_.second, data_); + } + // construct Track from TTTrackRef + Track(const TTTrackRef& ttTrackRef, const DataFormats* df, Process p, Ts... data) + : dataFormats_(df), p_(p), frame_(ttTrackRef, tt::Frame()), data_(data...) { + dataFormats_->convertTrack(p_, data_, frame_.second); + } + // construct Track from other Track + template + Track(const Track& track, Ts... data) + : dataFormats_(track.dataFormats()), p_(++track.p()), frame_(track.frame()), data_(data...) { + dataFormats_->convertTrack(p_, data_, frame_.second); + } + Track() {} + ~Track() {} + // true if frame valid, false if gap in data stream + explicit operator bool() const { return frame_.first.isNonnull(); } + // access to DataFormats + const DataFormats* dataFormats() const { return dataFormats_; } + // track flavour + Process p() const { return p_; } + // acces to frame + const tt::FrameTrack& frame() const { return frame_; } + + protected: + // all data formats + const DataFormats* dataFormats_; + // track flavour + Process p_; + // underlying TTTrackRef and bitvector + tt::FrameTrack frame_; + // ntuple of variables this track is assemled of + std::tuple data_; + }; + + // class to represent tracks generated by process TrackMultiplexer + class TrackTM : public Track { + public: + // construct TrackTM from Frame + TrackTM(const tt::FrameTrack& ft, const DataFormats* df) : Track(ft, df, Process::tm) {} + // construct TrackTM from TTTrack + TrackTM(const TTTrackRef& tTTrackRef, const DataFormats* df, double inv2R, double phiT, double zT) + : Track(tTTrackRef, df, Process::tm, inv2R, phiT, zT) {} + ~TrackTM() {} + // track inv2R + double inv2R() const { return std::get<0>(data_); } + // track phi at radius chosenRofPhi wrt pprocessing centre + double phiT() const { return std::get<1>(data_); } + // track z at radius chosenRofZ + double zT() const { return std::get<2>(data_); } + }; + + // class to represent tracks generated by process DuplicateRemoval + class TrackDR : public Track { + public: + // construct TrackDR from Frame + TrackDR(const tt::FrameTrack& ft, const DataFormats* df) : Track(ft, df, Process::dr) {} + // construct TrackDR from TrackTM + TrackDR(const TrackTM& track) : Track(track, track.inv2R(), track.phiT(), track.zT()) {} + ~TrackDR() {} + // track qOver pt + double inv2R() const { return std::get<0>(data_); } + // track phi at radius chosenRofPhi wrt processing nonant centre + double phiT() const { return std::get<1>(data_); } + // track z at radius chosenRofZ + double zT() const { return std::get<2>(data_); } + }; + + // class to represent tracks generated by process KalmanFilter + class TrackKF : public Track { + public: + // construct TrackKF from Frame + TrackKF(const tt::FrameTrack& ft, const DataFormats* df) : Track(ft, df, Process::kf) {} + // construct TrackKF from TrackDR + TrackKF(const TrackDR& track, double inv2R, double phiT, double cot, double zT) + : Track(track, inv2R, phiT, cot, zT) {} + TrackKF() {} + ~TrackKF() {} + // track inv2R + double inv2R() const { return std::get<0>(data_); } + // track phi at radius 0 wrt processing nonant centre + double phiT() const { return std::get<1>(data_); } + // track cotThea + double cot() const { return std::get<2>(data_); } + // track z at radius 0 + double zT() const { return std::get<3>(data_); } + }; + +} // namespace trklet + +EVENTSETUP_DATA_DEFAULT_RECORD(trklet::DataFormats, trklet::ChannelAssignmentRcd); + +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/DR.h b/L1Trigger/TrackFindingTracklet/interface/DuplicateRemoval.h similarity index 55% rename from L1Trigger/TrackFindingTracklet/interface/DR.h rename to L1Trigger/TrackFindingTracklet/interface/DuplicateRemoval.h index b3956fb0744ec..d7efe5314c2e7 100644 --- a/L1Trigger/TrackFindingTracklet/interface/DR.h +++ b/L1Trigger/TrackFindingTracklet/interface/DuplicateRemoval.h @@ -1,50 +1,49 @@ -#ifndef L1Trigger_TrackFindingTracklet_DR_h -#define L1Trigger_TrackFindingTracklet_DR_h +#ifndef L1Trigger_TrackFindingTracklet_DuplicateRemoval_h +#define L1Trigger_TrackFindingTracklet_DuplicateRemoval_h #include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" +#include "L1Trigger/TrackerTFP/interface/LayerEncoding.h" +#include "L1Trigger/TrackFindingTracklet/interface/DataFormats.h" #include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h" #include namespace trklet { - /*! \class trklet::DR + /*! \class trklet::DuplicateRemoval * \brief Class to bit- and clock-accurate emulate duplicate removal * DR identifies duplicates based on pairs of tracks that share stubs in at least 3 layers. - * It keeps the first such track in each pair. + * It keeps the first such track in each pair. The Track order is determined by TrackMultiplexer, + * provided by ProducerTM. * \author Thomas Schuh * \date 2023, Feb */ - class DR { + class DuplicateRemoval { public: - DR(const edm::ParameterSet& iConfig, - const tt::Setup* setup_, - const trackerTFP::DataFormats* dataFormats, - const ChannelAssignment* channelAssignment, - int region); - ~DR() {} + DuplicateRemoval(const tt::Setup* setup_, + const trackerTFP::LayerEncoding* layerEncoding, + const DataFormats* dataFormats, + const ChannelAssignment* channelAssignment, + int region); + ~DuplicateRemoval() {} // read in and organize input tracks and stubs void consume(const tt::StreamsTrack& streamsTrack, const tt::StreamsStub& streamsStub); // fill output products - void produce(tt::StreamsStub& accpetedStubs, - tt::StreamsTrack& acceptedTracks, - tt::StreamsStub& lostStubs, - tt::StreamsTrack& lostTracks); + void produce(tt::StreamsTrack& acceptedTracks, tt::StreamsStub& accpetedStubs); private: struct Stub { - Stub(const tt::FrameStub& frame, int stubId, int channel) : frame_(frame), stubId_(stubId), channel_(channel) {} - bool operator==(const Stub& s) const { return s.stubId_ == stubId_; } + Stub(const tt::FrameStub& frame, int stubId, int layer) : frame_(frame), stubId_(stubId), layer_(layer) {} + // output frame tt::FrameStub frame_; // all stubs id int stubId_; // kf layer id - int channel_; + int layer_; }; struct Track { // max number of stubs a track may formed of (we allow only one stub per layer) - static constexpr int max_ = 7; + static constexpr int max_ = 11; Track() { stubs_.reserve(max_); } Track(const tt::FrameTrack& frame, const std::vector& stubs) : frame_(frame), stubs_(stubs) {} tt::FrameTrack frame_; @@ -56,8 +55,10 @@ namespace trklet { bool enableTruncation_; // provides run-time constants const tt::Setup* setup_; + // helper class to encode layer + const trackerTFP::LayerEncoding* layerEncoding_; // provides dataformats - const trackerTFP::DataFormats* dataFormats_; + const DataFormats* dataFormats_; // helper class to assign tracks to channel const ChannelAssignment* channelAssignment_; // processing region (0 - 8) aka processing phi nonant @@ -67,7 +68,13 @@ namespace trklet { // storage of input stubs std::vector stubs_; // h/w liked organized pointer to input tracks - std::vector> input_; + std::vector input_; + // dataformat used to calculate pitch over stubs radius + DataFormat r_; + // number of TM layers + int tmNumLayers_; + // phi data format + DataFormat phi_; }; } // namespace trklet diff --git a/L1Trigger/TrackFindingTracklet/interface/HitPatternHelper.h b/L1Trigger/TrackFindingTracklet/interface/HitPatternHelper.h index 6b1c81db4f342..7d142cc7dbbd9 100644 --- a/L1Trigger/TrackFindingTracklet/interface/HitPatternHelper.h +++ b/L1Trigger/TrackFindingTracklet/interface/HitPatternHelper.h @@ -44,7 +44,14 @@ namespace hph { //Class that stores configuration for HitPatternHelper class Setup { public: - Setup(const edm::ParameterSet& iConfig, + // Configuration + struct Config { + bool hphDebug_; + bool useNewKF_; + double chosenRofZ_; + std::vector etaRegions_; + }; + Setup(const Config& iConfig, const tt::Setup& setupTT, const trackerTFP::DataFormats& dataFormats, const trackerTFP::LayerEncoding& layerEncoding); @@ -53,27 +60,20 @@ namespace hph { bool hphDebug() const { return hphDebug_; } bool useNewKF() const { return useNewKF_; } double chosenRofZ() const { return chosenRofZ_; } - std::vector etaRegions() const { return etaRegions_; } - std::map>> layermap() const { return layermap_; } + const std::vector& etaRegions() const { return etaRegions_; } + const std::map>>& layermap() const { return layermap_; } int nKalmanLayers() const { return nKalmanLayers_; } int etaRegion(double z0, double cot, bool useNewKF) const; - int digiCot(double cot, int binEta) const; - int digiZT(double z0, double cot, int binEta) const; - const std::vector& layerEncoding(int binEta, int binZT, int binCot) const { - return layerEncoding_.layerEncoding(binEta, binZT, binCot); - } - const std::map& layerEncodingMap(int binEta, int binZT, int binCot) const { - return layerEncoding_.layerEncodingMap(binEta, binZT, binCot); + const std::vector& layerEncoding(double zT) const { return layerEncoding_->layerEncoding(zT); } + // LayerEncoding call filling numPS, num2S, numMissingPS and numMissingPS for given hitPattern and trajectory + void analyze( + int hitpattern, double cot, double z0, int& numPS, int& num2S, int& numMissingPS, int& numMissing2S) const { + layerEncoding_->analyze(hitpattern, cot, z0, numPS, num2S, numMissingPS, numMissing2S); } private: - edm::ParameterSet iConfig_; - edm::ParameterSet oldKFPSet_; - const tt::Setup setupTT_; // Helper class to store TrackTrigger configuration - const trackerTFP::DataFormats dataFormats_; - const trackerTFP::DataFormat dfcot_; - const trackerTFP::DataFormat dfzT_; - const trackerTFP::LayerEncoding layerEncoding_; + const tt::Setup* setupTT_; // Helper class to store TrackTrigger configuration + const trackerTFP::LayerEncoding* layerEncoding_; bool hphDebug_; bool useNewKF_; double chosenRofZNewKF_; @@ -109,8 +109,10 @@ namespace hph { int numMissingInterior2() { return numMissingInterior2_; } //The number of missing interior layers (using hitpattern, layermap from Old KF and sensor modules) - std::vector binary() { return binary_; } //11-bit hitmask needed by TrackQuality.cc (0~5->L1~L6;6~10->D1~D5) - std::vector bonusFeatures() { return bonusFeatures_; } //bonus features for track quality + const std::vector& binary() { + return binary_; + } //11-bit hitmask needed by TrackQuality.cc (0~5->L1~L6;6~10->D1~D5) + const std::vector& bonusFeatures() { return bonusFeatures_; } //bonus features for track quality int reducedId( int layerId); //Converts layer ID (1~6->L1~L6;11~15->D1~D5) to reduced layer ID (0~5->L1~L6;6~10->D1~D5) @@ -123,11 +125,8 @@ namespace hph { std::vector etaRegions_; std::map>> layermap_; int nKalmanLayers_; - int etaBin_; - int cotBin_; - int zTBin_; + double zT_; std::vector layerEncoding_; - std::map layerEncodingMap_; int numExpLayer_; int hitpattern_; int etaSector_; diff --git a/L1Trigger/TrackFindingTracklet/interface/HitPatternHelperRcd.h b/L1Trigger/TrackFindingTracklet/interface/HitPatternHelperRcd.h index 0e74761f2ddaa..112a5c619dabe 100644 --- a/L1Trigger/TrackFindingTracklet/interface/HitPatternHelperRcd.h +++ b/L1Trigger/TrackFindingTracklet/interface/HitPatternHelperRcd.h @@ -8,12 +8,11 @@ #include "FWCore/Framework/interface/DependentRecordImplementation.h" #include "L1Trigger/TrackTrigger/interface/SetupRcd.h" #include "L1Trigger/TrackerTFP/interface/DataFormatsRcd.h" -#include "L1Trigger/TrackerTFP/interface/LayerEncodingRcd.h" #include "FWCore/Utilities/interface/mplVector.h" namespace hph { - typedef edm::mpl::Vector Rcds; + typedef edm::mpl::Vector Rcds; // record of hph::SetupRcd class SetupRcd : public edm::eventsetup::DependentRecordImplementation {}; diff --git a/L1Trigger/TrackFindingTracklet/interface/KFin.h b/L1Trigger/TrackFindingTracklet/interface/KFin.h deleted file mode 100644 index 9408c83e23a38..0000000000000 --- a/L1Trigger/TrackFindingTracklet/interface/KFin.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef L1Trigger_TrackFindingTracklet_KFin_h -#define L1Trigger_TrackFindingTracklet_KFin_h - -#include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" -#include "L1Trigger/TrackerTFP/interface/LayerEncoding.h" -#include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h" - -#include - -namespace trklet { - - /*! \class trklet::KFin - * \brief Class to emulate the data transformation happening betwwen DR and KF - * \author Thomas Schuh - * \date 2023, Feb - */ - class KFin { - public: - KFin(const edm::ParameterSet& iConfig, - const tt::Setup* setup_, - const trackerTFP::DataFormats* dataFormats, - const trackerTFP::LayerEncoding* layerEncoding, - const ChannelAssignment* channelAssignment, - int region); - ~KFin() {} - // read in and organize input tracks and stubs - void consume(const tt::StreamsTrack& streamsTrack, const tt::StreamsStub& streamsStub); - // fill output products - void produce(tt::StreamsStub& accpetedStubs, - tt::StreamsTrack& acceptedTracks, - tt::StreamsStub& lostStubs, - tt::StreamsTrack& lostTracks); - - private: - // truncates double precision of val into base precision, +1.e-12 restores robustness of addition of 2 digitised values - double digi(double val, double base) const { return (floor(val / base + 1.e-12) + .5) * base; } - struct Stub { - Stub(const TTStubRef& ttStubRef, double r, double phi, double z, int layerId, bool psTilt, int channel) - : ttStubRef_(ttStubRef), r_(r), phi_(phi), z_(z), layerId_(layerId), psTilt_(psTilt), channel_(channel) {} - TTStubRef ttStubRef_; - double r_; - double phi_; - double z_; - int layerId_; - bool psTilt_; - int channel_; - // phi uncertainty * sqrt(12) + additional terms in rad - double dPhi_; - // z uncertainty * sqrt(12) + additional terms in cm - double dZ_; - }; - struct Track { - static constexpr int max_ = 7; - Track() { stubs_.reserve(max_); } - Track(const tt::FrameTrack& frame, - const std::vector& stubs, - double cot, - double zT, - double inv2R, - int sectorEta) - : frame_(frame), stubs_(stubs), cot_(cot), zT_(zT), inv2R_(inv2R), sectorEta_(sectorEta) {} - tt::FrameTrack frame_; - std::vector stubs_; - double cot_; - double zT_; - double inv2R_; - int sectorEta_; - }; - // remove and return first element of deque, returns nullptr if empty - template - T* pop_front(std::deque& ts) const; - // true if truncation is enbaled - bool enableTruncation_; - // provides run-time constants - const tt::Setup* setup_; - // provides dataformats - const trackerTFP::DataFormats* dataFormats_; - // helper class to encode layer - const trackerTFP::LayerEncoding* layerEncoding_; - // helper class to assign tracks to channel - const ChannelAssignment* channelAssignment_; - // processing region (0 - 8) aka processing phi nonant - const int region_; - // storage of input tracks - std::vector tracks_; - // storage of input stubs - std::vector stubs_; - // h/w liked organized pointer to input tracks - std::vector> input_; - }; - -} // namespace trklet - -#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/KalmanFilter.h b/L1Trigger/TrackFindingTracklet/interface/KalmanFilter.h new file mode 100644 index 0000000000000..66c49c5c5e593 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/KalmanFilter.h @@ -0,0 +1,151 @@ +#ifndef L1Trigger_TrackFindingTracklet_KalmanFilter_h +#define L1Trigger_TrackFindingTracklet_KalmanFilter_h + +#include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackFindingTracklet/interface/DataFormats.h" +#include "L1Trigger/TrackFindingTracklet/interface/KalmanFilterFormats.h" +#include "L1Trigger/TrackFindingTracklet/interface/State.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "L1Trigger/TrackFindingTMTT/interface/Settings.h" +#include "L1Trigger/TrackFindingTMTT/interface/KFParamsComb.h" + +#include +#include + +namespace trklet { + + /*! \class trklet::KalmanFilter + * \brief Class to do helix fit to all tracks in a region. + * All variable names & equations come from Fruhwirth KF paper + * http://dx.doi.org/10.1016/0168-9002%2887%2990887-4 + * Summary of variables: + * m = hit position (phi,z) + * V = hit position 2x2 covariance matrix in (phi,z). + * x = helix params + * C = helix params 4x4 covariance matrix + * r = residuals + * H = 2x4 derivative matrix (expected stub position w.r.t. helix params) + * K = KF gain 2x2 matrix + * x' & C': Updated values of x & C after KF iteration + * Boring: F = unit matrix; pxcov = C + * Summary of equations: + * S = H*C (2x4 matrix); St = Transpose S + * R = V + H*C*Ht (KF paper) = V + H*St (used here at simpler): 2x2 matrix + * Rinv = Inverse R + * K = St * Rinv : 2x2 Kalman gain matrix * det(R) + * r = m - H*x + * x' = x + K*r + * C' = C - K*H*C (KF paper) = C - K*S (used here as simpler) + * \author Thomas Schuh + * \date 2024, Sep + */ + class KalmanFilter { + public: + typedef State::Stub Stub; + KalmanFilter(const tt::Setup* setup, + const DataFormats* dataFormats, + KalmanFilterFormats* kalmanFilterFormats, + tmtt::Settings* settings, + tmtt::KFParamsComb* tmtt, + int region, + tt::TTTracks& ttTracks); + ~KalmanFilter() {} + // read in and organize input tracks and stubs + void consume(const tt::StreamsTrack& streamsTrack, const tt::StreamsStub& streamsStub); + // fill output products + void produce(tt::StreamsStub& streamsStub, + tt::StreamsTrack& streamsTrack, + int& numAcceptedStates, + int& numLostStates); + + private: + // + struct Track { + Track() {} + Track(int trackId, + int numConsistent, + int numConsistentPS, + double d0, + const TTBV& hitPattern, + const TrackKF& trackKF, + const std::vector& stubsKF) + : trackId_(trackId), + numConsistent_(numConsistent), + numConsistentPS_(numConsistentPS), + d0_(d0), + hitPattern_(hitPattern), + trackKF_(trackKF), + stubsKF_(stubsKF) {} + int trackId_; + int numConsistent_; + int numConsistentPS_; + double d0_; + TTBV hitPattern_; + TrackKF trackKF_; + std::vector stubsKF_; + }; + // call old KF + void simulate(tt::StreamsStub& streamsStub, tt::StreamsTrack& streamsTrack); + // constraints double precision + double digi(VariableKF var, double val) { return kalmanFilterFormats_->format(var).digi(val); } + // + int integer(VariableKF var, double val) { return kalmanFilterFormats_->format(var).integer(val); } + // + void updateRangeActual(VariableKF var, double val) { + return kalmanFilterFormats_->format(var).updateRangeActual(val); + } + // + double base(VariableKF var) { return kalmanFilterFormats_->format(var).base(); } + // + int width(VariableKF var) { return kalmanFilterFormats_->format(var).width(); } + // remove and return first element of deque, returns nullptr if empty + template + T* pop_front(std::deque& ts) const; + // calculates the helix params & their cov. matrix from a pair of stubs + void calcSeeds(); + // Transform States into output products + void conv(tt::StreamsStub& streamsStub, tt::StreamsTrack& streamsTrack); + // adds a layer to states, bool indicating if in seeding process + void addLayer(bool seed = false); + // apply final cuts + void finalize(); + // best state selection + void accumulator(); + // updates state using 4 paramter fit + void update4(State*& state); + // updates state using 5 parameter fit + void update5(State*& state); + + // provides run-time constants + const tt::Setup* setup_; + // provides dataformats + const DataFormats* dataFormats_; + // provides dataformats of Kalman filter internals + KalmanFilterFormats* kalmanFilterFormats_; + // + tmtt::Settings* settings_; + // + tmtt::KFParamsComb* tmtt_; + // processing region + int region_; + // + tt::TTTracks& ttTracks_; + // container of tracks + std::vector tracks_; + // container of stubs + std::vector stubs_; + // container of all Kalman Filter states + std::deque states_; + // processing stream + std::deque stream_; + // + std::vector finals_; + // current layer used during state propagation + int layer_; + // + std::vector zTs_; + }; + +} // namespace trklet + +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/KalmanFilterFormats.h b/L1Trigger/TrackFindingTracklet/interface/KalmanFilterFormats.h new file mode 100644 index 0000000000000..1972547382756 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/KalmanFilterFormats.h @@ -0,0 +1,303 @@ +#ifndef L1Trigger_TrackFindingTracklet_KalmanFilterFormats_h +#define L1Trigger_TrackFindingTracklet_KalmanFilterFormats_h + +/*---------------------------------------------------------------------- +Classes to calculate and provide dataformats used by Kalman Filter emulator +enabling tuning of bit widths +----------------------------------------------------------------------*/ + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "L1Trigger/TrackFindingTracklet/interface/DataFormats.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace trklet { + + /* + * All variable names & equations come from Fruhwirth KF paper + * http://dx.doi.org/10.1016/0168-9002%2887%2990887-4 + * Summary of variables: + * m = hit position (phi,z) + * V = hit position 2x2 covariance matrix in (phi,z). + * x = helix params + * C = helix params 4x4 covariance matrix + * r = residuals + * H = 2x4 derivative matrix (expected stub position w.r.t. helix params) + * K = KF gain 2x2 matrix + * x' & C': Updated values of x & C after KF iteration + * Boring: F = unit matrix; pxcov = C + * Summary of equations: + * S = H*C (2x4 matrix); St = Transpose S + * R = V + H*C*Ht (KF paper) = V + H*St (used here at simpler): 2x2 matrix + * Rinv = Inverse R + * K = St * Rinv : 2x2 Kalman gain matrix * det(R) + * r = m - H*x + * x' = x + K*r + * C' = C - K*H*C (KF paper) = C - K*S (used here as simpler) + */ + enum class VariableKF { + begin, + x0 = begin, + x1, + x2, + x3, + H00, + H12, + m0, + m1, + v0, + v1, + r0, + r1, + S00, + S01, + S12, + S13, + S00Shifted, + S01Shifted, + S12Shifted, + S13Shifted, + K00, + K10, + K21, + K31, + R00, + R11, + R00Rough, + R11Rough, + invR00Approx, + invR11Approx, + invR00Cor, + invR11Cor, + invR00, + invR11, + C00, + C01, + C11, + C22, + C23, + C33, + dH, + invdH, + invdH2, + H2, + Hm0, + Hm1, + Hv0, + Hv1, + H2v0, + H2v1, + end + }; + inline constexpr int operator+(VariableKF v) { return static_cast(v); } + inline constexpr VariableKF operator+(VariableKF v, int i) { return VariableKF(+v + i); } + + // Configuration + struct ConfigKF { + bool enableIntegerEmulation_; + int widthR00_; + int widthR11_; + int widthC00_; + int widthC01_; + int widthC11_; + int widthC22_; + int widthC23_; + int widthC33_; + int baseShiftx0_; + int baseShiftx1_; + int baseShiftx2_; + int baseShiftx3_; + int baseShiftr0_; + int baseShiftr1_; + int baseShiftS00_; + int baseShiftS01_; + int baseShiftS12_; + int baseShiftS13_; + int baseShiftR00_; + int baseShiftR11_; + int baseShiftInvR00Approx_; + int baseShiftInvR11Approx_; + int baseShiftInvR00Cor_; + int baseShiftInvR11Cor_; + int baseShiftInvR00_; + int baseShiftInvR11_; + int baseShiftS00Shifted_; + int baseShiftS01Shifted_; + int baseShiftS12Shifted_; + int baseShiftS13Shifted_; + int baseShiftK00_; + int baseShiftK10_; + int baseShiftK21_; + int baseShiftK31_; + int baseShiftC00_; + int baseShiftC01_; + int baseShiftC11_; + int baseShiftC22_; + int baseShiftC23_; + int baseShiftC33_; + }; + + class DataFormatKF { + public: + DataFormatKF(const VariableKF& v, bool twos, bool enableIntegerEmulation, int width, double base, double range); + virtual ~DataFormatKF() {} + double digi(double val) const { + return enableIntegerEmulation_ ? (std::floor(val / base_ + 1.e-11) + .5) * base_ : val; + } + bool twos() const { return twos_; } + int width() const { return width_; } + double base() const { return base_; } + double range() const { return range_; } + double min() const { return min_; } + double abs() const { return abs_; } + double max() const { return max_; } + // returns false if data format would oferflow for this double value + bool inRange(double d) const; + void updateRangeActual(double d); + int integer(double d) const { return floor(d / base_ + 1.e-11); } + + protected: + VariableKF v_; + bool twos_; + bool enableIntegerEmulation_; + int width_; + double base_; + double range_; + double min_; + double abs_; + double max_; + }; + + class KalmanFilterFormats { + public: + KalmanFilterFormats(); + ~KalmanFilterFormats() {} + DataFormatKF& format(VariableKF v) { return formats_[+v]; } + const tt::Setup* setup() const { return dataFormats_->setup(); } + const DataFormats* dataFormats() const { return dataFormats_; } + void consume(const DataFormats* dataFormats, const ConfigKF& iConfig); + void endJob(std::stringstream& ss); + + private: + template + void fillFormats(); + ConfigKF iConfig_; + const DataFormats* dataFormats_; + std::vector formats_; + }; + + // function template for DataFormat generation + template + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + +} // namespace trklet + +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/Settings.h b/L1Trigger/TrackFindingTracklet/interface/Settings.h index ad113a8c8336b..22bd087ab5000 100644 --- a/L1Trigger/TrackFindingTracklet/interface/Settings.h +++ b/L1Trigger/TrackFindingTracklet/interface/Settings.h @@ -147,6 +147,7 @@ namespace trklet { } unsigned int teunits(unsigned int iSeed) const { return teunits_[iSeed]; } + unsigned int trpunits(unsigned int iSeed) const { return trpunits_[iSeed]; } unsigned int NTC(int seed) const { return ntc_[seed]; } @@ -655,7 +656,8 @@ namespace trklet { int chisqphifactbits_{14}; int chisqzfactbits_{14}; - std::array teunits_{{5, 2, 5, 3, 3, 2, 3, 2, 0, 0, 0, 0}}; //teunits used by seed + std::array teunits_{{5, 2, 5, 3, 3, 2, 3, 2, 0, 0, 0, 0}}; //teunits used by seed + std::array trpunits_{{0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10}}; //trpunits used by seed std::array vmrlutzbits_{ {7, 7, 7, 7, 7, 7, 3, 3, 3, 3, 3}}; // zbits used by LUT in VMR diff --git a/L1Trigger/TrackFindingTracklet/interface/State.h b/L1Trigger/TrackFindingTracklet/interface/State.h new file mode 100644 index 0000000000000..d8434745e3927 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/State.h @@ -0,0 +1,143 @@ +#ifndef L1Trigger_TrackFindingTracklet_State_h +#define L1Trigger_TrackFindingTracklet_State_h + +#include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackFindingTracklet/interface/DataFormats.h" +#include "L1Trigger/TrackFindingTracklet/interface/KalmanFilterFormats.h" + +#include +#include + +namespace trklet { + + // Class to represent a Kalman Filter helix State + class State { + public: + // + struct Stub { + Stub(KalmanFilterFormats* kff, const tt::FrameStub& frame); + StubDR stubDR_; + double H12_; + double H04_; + double v0_; + double v1_; + }; + // copy constructor + State(State* state); + // proto state constructor + State(KalmanFilterFormats* kff, TrackDR* track, const std::vector& stubs, int trackId); + // updated state constructor + State(State* state, const std::vector& doubles); + // combinatoric and seed building state constructor + State(State* state, State* parent, int layer); + ~State() {} + // + State* comb(std::deque& states, int layer); + // + State* combSeed(std::deque& states, int layer); + // + State* update(std::deque& states, int layer); + // input track + TrackDR* track() const { return track_; } + // parent state (nullpointer if no parent available) + State* parent() const { return parent_; } + // stub to add to state + Stub* stub() const { return stub_; } + // hitPattern of so far added stubs + const TTBV& hitPattern() const { return hitPattern_; } + // shows which layer the found track has stubs on + const TTBV& trackPattern() const { return trackPattern_; } + // track id of input track + int trackId() const { return trackId_; } + // helix inv2R wrt input helix + double x0() const { return x0_; } + // helix phi at radius ChosenRofPhi wrt input helix + double x1() const { return x1_; } + // helix cot(Theta) wrt input helix + double x2() const { return x2_; } + // helix z at radius chosenRofZ wrt input helix + double x3() const { return x3_; } + // + double x4() const { return x4_; } + // cov. matrix element + double C00() const { return C00_; } + // cov. matrix element + double C01() const { return C01_; } + // cov. matrix element + double C11() const { return C11_; } + // cov. matrix element + double C22() const { return C22_; } + // cov. matrix element + double C23() const { return C23_; } + // cov. matrix element + double C33() const { return C33_; } + double C44() const { return C44_; } + double C40() const { return C40_; } + double C41() const { return C41_; } + // Derivative of predicted stub coords wrt helix params: stub radius minus chosenRofPhi + double H00() const { return stub_->stubDR_.r(); } + // Derivative of predicted stub coords wrt helix params: stub radius minus chosenRofZ + double H12() const { return stub_->H12_; } + // + double H04() const { return stub_->H04_; } + // stub phi residual wrt input helix + double m0() const { return stub_->stubDR_.phi(); } + // stub z residual wrt input helix + double m1() const { return stub_->stubDR_.z(); } + // stub projected phi uncertainty + double d0() const { return stub_->stubDR_.dPhi(); } + // stub projected z uncertainty + double d1() const { return stub_->stubDR_.dZ(); } + // squared stub projected phi uncertainty instead of wheight (wrong but simpler) + double v0() const { return stub_->v0_; } + // squared stub projected z uncertainty instead of wheight (wrong but simpler) + double v1() const { return stub_->v1_; } + // layer of current to add stub + int layer() const { return std::distance(stubs_.begin(), std::find(stubs_.begin(), stubs_.end(), stub_)); } + // + std::vector stubs() const { return stubs_; } + + private: + // provides data fomats + KalmanFilterFormats* kff_; + // provides run-time constants + const tt::Setup* setup_; + // input track + TrackDR* track_; + // input track stubs + std::vector stubs_; + // track id + int trackId_; + // previous state, nullptr for first states + State* parent_; + // stub to add + Stub* stub_; + // shows which layer has been added so far + TTBV hitPattern_; + // shows which layer the found track has stubs on + TTBV trackPattern_; + // helix inv2R wrt input helix + double x0_; + // helix phi at radius ChosenRofPhi wrt input helix + double x1_; + // helix cot(Theta) wrt input helix + double x2_; + // helix z at radius chosenRofZ wrt input helix + double x3_; + // impact parameter in 1/cm + double x4_; + // cov. matrix + double C00_; + double C01_; + double C11_; + double C22_; + double C23_; + double C33_; + double C44_; + double C40_; + double C41_; + }; + +} // namespace trklet + +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/TrackFindingProcessor.h b/L1Trigger/TrackFindingTracklet/interface/TrackFindingProcessor.h new file mode 100644 index 0000000000000..4ece690006217 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/TrackFindingProcessor.h @@ -0,0 +1,95 @@ +#ifndef L1Trigger_TrackFindingTracklet_TrackFindingProcessor_h +#define L1Trigger_TrackFindingTracklet_TrackFindingProcessor_h + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackFindingTracklet/interface/DataFormats.h" +#include "L1Trigger/TrackerTFP/interface/TrackQuality.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" + +#include +#include +#include + +namespace trklet { + + /*! \class trklet::TrackFindingProcessor + * \brief Class to format final tfp output and to prodcue final TTTrackCollection + * \author Thomas Schuh + * \date 2025, Apr + */ + class TrackFindingProcessor { + public: + TrackFindingProcessor(const tt::Setup* setup_, + const DataFormats* dataFormats, + const trackerTFP::TrackQuality* trackQuality); + ~TrackFindingProcessor() {} + + // produce TTTracks + void produce(const tt::StreamsTrack& inputs, + const tt::Streams& inputsAdd, + const tt::StreamsStub& stubs, + tt::TTTracks& ttTracks, + tt::StreamsTrack& outputs); + // produce StreamsTrack + void produce(const std::vector& inputs, tt::StreamsTrack& outputs) const; + + private: + // number of bits used to describe one part of a track (96 bit) + static constexpr int partial_width = 32; + // number of track parts arriving per clock tick (1 track per tick) + static constexpr int partial_in = 3; + // number of track parts leaving per clock tick (TFP sends 2/3 tracks per clock and link) + static constexpr int partial_out = 2; + // type describing one part of a track + typedef std::bitset PartialFrame; + // type describing one part of a track together with its edm ref + typedef std::pair PartialFrameTrack; + // type representing a track + struct Track { + Track(const tt::FrameTrack& frameTrack, + const tt::Frame& frameTQ, + const std::vector& ttStubRefs, + const DataFormats* df, + const trackerTFP::TrackQuality* tq); + const TTTrackRef& ttTrackRef_; + const std::vector ttStubRefs_; + bool valid_; + std::vector partials_; + TTBV hitPattern_; + int channel_; + int mva_; + double inv2R_; + double phiT_; + double cot_; + double zT_; + double chi2rphi_; + double chi2rz_; + }; + // remove and return first element of deque, returns nullptr if empty + template + T* pop_front(std::deque& ts) const; + // + void consume(const tt::StreamsTrack& inputs, + const tt::Streams& inputsAdd, + const tt::StreamsStub& stubs, + std::vector>& outputs); + // emualte data format f/w + void produce(std::vector>& inputs, tt::StreamsTrack& outputs) const; + // produce TTTracks + void produce(const tt::StreamsTrack& inputs, tt::TTTracks& ouputs) const; + // provides run-time constants + const tt::Setup* setup_; + // provides data formats + const DataFormats* dataFormats_; + // provides Track Quality algo and formats + const trackerTFP::TrackQuality* trackQuality_; + // storage of tracks + std::vector tracks_; + // b field + double bfield_; + }; + +} // namespace trklet + +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/DRin.h b/L1Trigger/TrackFindingTracklet/interface/TrackMultiplexer.h similarity index 64% rename from L1Trigger/TrackFindingTracklet/interface/DRin.h rename to L1Trigger/TrackFindingTracklet/interface/TrackMultiplexer.h index f18d985405823..1b592a1c5ac19 100644 --- a/L1Trigger/TrackFindingTracklet/interface/DRin.h +++ b/L1Trigger/TrackFindingTracklet/interface/TrackMultiplexer.h @@ -1,10 +1,9 @@ -#ifndef L1Trigger_TrackFindingTracklet_DRin_h -#define L1Trigger_TrackFindingTracklet_DRin_h +#ifndef L1Trigger_TrackFindingTracklet_TrackMultiplexer_h +#define L1Trigger_TrackFindingTracklet_TrackMultiplexer_h #include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" -#include "L1Trigger/TrackerTFP/interface/LayerEncoding.h" #include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h" +#include "L1Trigger/TrackFindingTracklet/interface/DataFormats.h" #include "L1Trigger/TrackFindingTracklet/interface/Settings.h" #include @@ -12,29 +11,24 @@ namespace trklet { - /*! \class trklet::DRin + /*! \class trklet::TrackMultiplexer * \brief Class to emulate transformation of tracklet tracks and stubs into TMTT format - * and routing of seed type streams into inv2R streams + * and routing of seed type streams into single stream * \author Thomas Schuh * \date 2023, Jan */ - class DRin { + class TrackMultiplexer { public: - DRin(const edm::ParameterSet& iConfig, - const tt::Setup* setup_, - const trackerTFP::DataFormats* dataFormats, - const trackerTFP::LayerEncoding* layerEncoding, - const ChannelAssignment* channelAssignment, - const Settings* settings, - int region); - ~DRin() {} + TrackMultiplexer(const tt::Setup* setup_, + const DataFormats* dataFormats, + const ChannelAssignment* channelAssignment, + const Settings* settings, + int region); + ~TrackMultiplexer() {} // read in and organize input tracks and stubs void consume(const tt::StreamsTrack& streamsTrack, const tt::StreamsStub& streamsStub); // fill output products - void produce(tt::StreamsStub& accpetedStubs, - tt::StreamsTrack& acceptedTracks, - tt::StreamsStub& lostStubs, - tt::StreamsTrack& lostTracks); + void produce(tt::StreamsTrack& streamsTrack, tt::StreamsStub& streamsStub); private: // truncates double precision of val into base precision, +1.e-12 restores robustness of addition of 2 digitised values @@ -42,37 +36,16 @@ namespace trklet { // basetransformation of val from baseLow into baseHigh using widthMultiplier bit multiplication double redigi(double val, double baseLow, double baseHigh, int widthMultiplier) const; struct Stub { - Stub(const TTStubRef& ttStubRef, - int layer, - int layerDet, - bool seed, - int stubId, - double r, - double phi, - double z, - bool psTilt) - : valid_(true), - ttStubRef_(ttStubRef), - layer_(layer), - layerDet_(layerDet), - layerKF_(-1), - seed_(seed), - stubId_(stubId), - r_(r), - phi_(phi), - z_(z), - psTilt_(psTilt) {} + Stub(const TTStubRef& ttStubRef, int layer, int stubId, double r, double phi, double z, bool psTilt) + : valid_(true), ttStubRef_(ttStubRef), layer_(layer), stubId_(stubId), r_(r), phi_(phi), z_(z) { + stubId_ = 2 * stubId_ + (psTilt ? 1 : 0); + } + tt::FrameStub frame(const DataFormats* df) const { return StubTM(ttStubRef_, df, stubId_, r_, phi_, z_).frame(); } bool valid_; TTStubRef ttStubRef_; - // layers a seed types can project to using default layer id [barrel: 1-6, discs: 11-15] + // kf layer id int layer_; - // layer id [0-5] barrel [6-10] end cap discs - int layerDet_; - // layer id [0-6] counted from inside-out along track - int layerKF_; - // true if stub was part of the seed - bool seed_; - // traclet stub id + // tracklet stub id, used to identify duplicates int stubId_; // radius w.r.t. chosenRofPhi in cm double r_; @@ -80,14 +53,13 @@ namespace trklet { double phi_; // z residual in cm double z_; - // true if barrel tilted module or encap PS module - bool psTilt_; }; struct Track { - static constexpr int max_ = 8; + static constexpr int max_ = 11; Track() { stubs_.reserve(max_); } Track(const TTTrackRef& ttTrackRef, bool valid, + int seedType, double inv2R, double phiT, double cot, @@ -95,16 +67,16 @@ namespace trklet { const std::vector& stubs) : ttTrackRef_(ttTrackRef), valid_(valid), - sector_(-1), + seedType_(seedType), inv2R_(inv2R), phiT_(phiT), cot_(cot), zT_(zT), stubs_(stubs) {} + tt::FrameTrack frame(const DataFormats* df) const { return TrackTM(ttTrackRef_, df, inv2R_, phiT_, zT_).frame(); } TTTrackRef ttTrackRef_; bool valid_; - TTBV maybe_; - int sector_; + int seedType_; double inv2R_; double phiT_; double cot_; @@ -118,12 +90,14 @@ namespace trklet { bool enableTruncation_; // stub residuals are recalculated from seed parameter and TTStub position bool useTTStubResiduals_; + // track parameter are recalculated from seed TTStub positions + bool useTTStubParameters_; + // + bool applyNonLinearCorrection_; // provides run-time constants const tt::Setup* setup_; // provides dataformats - const trackerTFP::DataFormats* dataFormats_; - // helper class to encode layer - const trackerTFP::LayerEncoding* layerEncoding_; + const DataFormats* dataFormats_; // helper class to assign tracks to channel const ChannelAssignment* channelAssignment_; // provides tracklet constants @@ -147,21 +121,22 @@ namespace trklet { // KF input format digitisation granularity (identical to TMTT) double baseLinv2R_; double baseLphiT_; - double baseLcot_; double baseLzT_; double baseLr_; double baseLphi_; double baseLz_; + double baseLcot_; // Finer granularity (by powers of 2) than the TMTT one. Used to transform from Tracklet to TMTT base. double baseHinv2R_; double baseHphiT_; - double baseHcot_; double baseHzT_; double baseHr_; double baseHphi_; double baseHz_; + double baseHcot_; // digitisation granularity used for inverted cot(theta) double baseInvCot_; + double baseScot_; }; } // namespace trklet diff --git a/L1Trigger/TrackFindingTracklet/interface/TrackletProcessorDisplaced.h b/L1Trigger/TrackFindingTracklet/interface/TrackletProcessorDisplaced.h index 6cf8abd6e714a..7f0f3a38c647c 100644 --- a/L1Trigger/TrackFindingTracklet/interface/TrackletProcessorDisplaced.h +++ b/L1Trigger/TrackFindingTracklet/interface/TrackletProcessorDisplaced.h @@ -6,9 +6,9 @@ #include "L1Trigger/TrackFindingTracklet/interface/TrackletCalculatorDisplaced.h" #include "L1Trigger/TrackFindingTracklet/interface/TrackletLUT.h" #include "L1Trigger/TrackFindingTracklet/interface/CircularBuffer.h" -#include "L1Trigger/TrackFindingTracklet/interface/TrackletEngineUnit.h" #include "L1Trigger/TrackFindingTracklet/interface/TrackletParametersMemory.h" #include "L1Trigger/TrackFindingTracklet/interface/TrackletProjectionsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/TripletEngineUnit.h" #include #include @@ -40,6 +40,10 @@ namespace trklet { private: int iTC_; + unsigned int maxStep_; + + std::tuple, unsigned int, unsigned int, unsigned int, unsigned int> trpbuffer_; + std::vector trpunits_; unsigned int layerdisk1_; unsigned int layerdisk2_; diff --git a/L1Trigger/TrackFindingTracklet/interface/TripletEngineUnit.h b/L1Trigger/TrackFindingTracklet/interface/TripletEngineUnit.h new file mode 100644 index 0000000000000..4f75a3a39bc3c --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/TripletEngineUnit.h @@ -0,0 +1,94 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_TripletEngineUnit_h +#define L1Trigger_TrackFindingTracklet_interface_TripletEngineUnit_h + +#include "L1Trigger/TrackFindingTracklet/interface/VMStubsTEMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/CircularBuffer.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackletLUT.h" + +#include +#include + +namespace trklet { + + class Settings; + class Stub; + class L1TStub; + + struct TrpEData { + const Stub* stub_; + int start_out_; + int start_in_; + int rzbinfirst_out_; + int rzdiffmax_out_; + std::vector > projbin_out_; // next z/r bin; outer stub mem; nstub + std::vector > projbin_in_; // next z/r bin; inner stub mem; nstub + }; + + class TripletEngineUnit { + public: + TripletEngineUnit(const Settings* const settings, + unsigned int layerdisk1, + unsigned int layerdisk2, + unsigned int layerdisk3, + unsigned int iSeed, + std::vector innervmstubs, + std::vector outervmstubs); + + ~TripletEngineUnit() = default; + + void init(const TrpEData& trpdata); + + bool getGoodTriplet() { return goodtriplet__; } + + bool empty() const { return candtriplets_.empty(); } + + const std::tuple& read() { return candtriplets_.read(); } + + const std::tuple& peek() const { return candtriplets_.peek(); } + + bool idle() const { return idle_; } + + void setNearFull() { nearfull_ = candtriplets_.nearfull(); } + + void reset(); + + void step(); + + const Stub* innerStub() const { return trpdata_.stub_; } + + private: + std::vector innervmstubs_; + std::vector outervmstubs_; + TrpEData trpdata_; + const Settings* settings_; + unsigned int layerdisk1_; + unsigned int layerdisk2_; + unsigned int layerdisk3_; + unsigned int iSeed_; + bool nearfull_; //initialized at start of each processing step + + //unsigned int memory slot + unsigned int nmem_out_; + unsigned int nmem_in_; + unsigned int istub_out_; + unsigned int istub_in_; + unsigned int next_out_; + unsigned int next_in_; + unsigned int nstub_out_; + unsigned int nstub_in_; + unsigned int outmem_; + unsigned int inmem_; + unsigned int nproj_out_; + unsigned int nproj_in_; + + bool idle_; + + std::tuple candtriplet_, candtriplet__; + bool goodtriplet_, goodtriplet__; + + //save the candidate matches + CircularBuffer > candtriplets_; + }; // TripletEngineUnit + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/plugins/L1FPGATrackProducer.cc b/L1Trigger/TrackFindingTracklet/plugins/L1FPGATrackProducer.cc index 6bc9104b41764..7bf8133418866 100644 --- a/L1Trigger/TrackFindingTracklet/plugins/L1FPGATrackProducer.cc +++ b/L1Trigger/TrackFindingTracklet/plugins/L1FPGATrackProducer.cc @@ -24,6 +24,7 @@ // DATA FORMATS HEADERS #include "DataFormats/Common/interface/Handle.h" #include "DataFormats/Common/interface/Ref.h" +#include "DataFormats/Common/interface/OrphanHandle.h" // #include "DataFormats/DetId/interface/DetId.h" #include "DataFormats/SiPixelDetId/interface/PXBDetId.h" @@ -53,6 +54,7 @@ #include "DataFormats/L1TrackTrigger/interface/TTTypes.h" #include "DataFormats/L1TrackTrigger/interface/TTDTC.h" #include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackerTFP/interface/TrackQuality.h" // #include "DataFormats/HepMCCandidate/interface/GenParticle.h" #include "DataFormats/Candidate/interface/Candidate.h" @@ -99,7 +101,6 @@ #include "DataFormats/GeometrySurface/interface/BoundPlane.h" #include "L1Trigger/TrackTrigger/interface/StubPtConsistency.h" -#include "L1Trigger/TrackTrigger/interface/L1TrackQuality.h" ////////////// // STD HEADERS @@ -108,13 +109,6 @@ #include #include -////////////// -// NAMESPACES -using namespace edm; -using namespace std; -using namespace tt; -using namespace trklet; - ////////////////////////////// // // // CLASS DEFINITION // @@ -163,7 +157,7 @@ class L1FPGATrackProducer : public edm::one::EDProducer { edm::FileInPath tableTEDFile; edm::FileInPath tableTREFile; - string asciiEventOutName_; + std::string asciiEventOutName_; std::ofstream asciiEventOut_; // settings containing various constants for the tracklet processing @@ -180,10 +174,7 @@ class L1FPGATrackProducer : public edm::one::EDProducer { bool extended_; bool reduced_; - bool trackQuality_; - std::unique_ptr trackQualityModel_; - - std::map> dtclayerdisk; + std::map> dtclayerdisk; edm::InputTag MCTruthClusterInputTag; edm::InputTag MCTruthStubInputTag; @@ -194,25 +185,29 @@ class L1FPGATrackProducer : public edm::one::EDProducer { edm::EDGetTokenT> getTokenTTClusterMCTruth_; edm::EDGetTokenT> getTokenTrackingParticle_; + // ED output token for TTTracks + const edm::EDPutTokenT putTokenTTTracks_; // ED output token for clock and bit accurate tracks - const edm::EDPutTokenT putTokenTracks_; + edm::EDPutTokenT putTokenTracks_; // ED output token for clock and bit accurate stubs - const edm::EDPutTokenT putTokenStubs_; - // ChannelAssignment token - const ESGetToken esGetTokenChannelAssignment_; - // helper class to assign tracks to channel - const ChannelAssignment* channelAssignment_; - - // helper class to store DTC configuration - const Setup* setup_; + edm::EDPutTokenT putTokenStubs_; + + // helper class to store Track Trigger configuration + const tt::Setup* setup_ = nullptr; + // helper class to store Tracklet specific configuration + const trklet::ChannelAssignment* channelAssignment_ = nullptr; + // helper class to determine track quality + const trackerTFP::TrackQuality* trackQuality_ = nullptr; // helper class to store configuration needed by HitPatternHelper - const hph::Setup* setupHPH_; + const hph::Setup* setupHPH_ = nullptr; // Setup token const edm::ESGetToken esGetTokenBfield_; const edm::ESGetToken esGetTokenTGeom_; const edm::ESGetToken esGetTokenTTopo_; - const edm::ESGetToken esGetToken_; + const edm::ESGetToken esGetTokenSetup_; + const edm::ESGetToken esGetTokenChannelAssignment_; + const edm::ESGetToken esGetTokenTrackQuality_; const edm::ESGetToken esGetTokenHPH_; /// ///////////////// /// @@ -236,25 +231,28 @@ L1FPGATrackProducer::L1FPGATrackProducer(edm::ParameterSet const& iConfig) // book ED products getTokenBS_(consumes(config.getParameter("BeamSpotSource"))), getTokenDTC_(consumes(edm::InputTag(iConfig.getParameter("InputTagTTDTC")))), - // book ED output token for clock and bit accurate tracks - putTokenTracks_(produces("Level1TTTracks")), - // book ED output token for clock and bit accurate stubs - putTokenStubs_(produces("Level1TTTracks")), + // book ED output token for TTTracks + putTokenTTTracks_(produces("Level1TTTracks")), // book ES products - esGetTokenChannelAssignment_(esConsumes()), esGetTokenBfield_(esConsumes()), esGetTokenTGeom_(esConsumes()), esGetTokenTTopo_(esConsumes()), - esGetToken_(esConsumes()), - esGetTokenHPH_(esConsumes()) { + esGetTokenSetup_(esConsumes()), + esGetTokenChannelAssignment_(esConsumes()), + esGetTokenTrackQuality_(esConsumes()), + esGetTokenHPH_(esConsumes()) { if (readMoreMcTruth_) { getTokenTTClusterMCTruth_ = consumes>(MCTruthClusterInputTag); getTokenTrackingParticle_ = consumes>(TrackingParticleInputTag); } + const std::string& branchStubs = iConfig.getParameter("BranchStubs"); + const std::string& branchTracks = iConfig.getParameter("BranchTracks"); + // book ED output token for clock and bit accurate tracks + putTokenTracks_ = produces(branchTracks); + // book ED output token for clock and bit accurate stubs + putTokenStubs_ = produces(branchStubs); - produces>>("Level1TTTracks").setBranchAlias("Level1TTTracks"); - - asciiEventOutName_ = iConfig.getUntrackedParameter("asciiFileName", ""); + asciiEventOutName_ = iConfig.getUntrackedParameter("asciiFileName", ""); processingModulesFile = iConfig.getParameter("processingModulesFile"); memoryModulesFile = iConfig.getParameter("memoryModulesFile"); @@ -271,10 +269,6 @@ L1FPGATrackProducer::L1FPGATrackProducer(edm::ParameterSet const& iConfig) tableTREFile = iConfig.getParameter("tableTREFile"); } - // initial ES products - channelAssignment_ = nullptr; - setup_ = nullptr; - // -------------------------------------------------------------------------------- // set options in Settings based on inputs from configuration files // -------------------------------------------------------------------------------- @@ -293,7 +287,7 @@ L1FPGATrackProducer::L1FPGATrackProducer(edm::ParameterSet const& iConfig) settings_.setFakefit(iConfig.getParameter("Fakefit")); settings_.setStoreTrackBuilderOutput(iConfig.getParameter("StoreTrackBuilderOutput")); - settings_.setRemovalType(iConfig.getParameter("RemovalType")); + settings_.setRemovalType(iConfig.getParameter("RemovalType")); settings_.setDoMultipleMatches(iConfig.getParameter("DoMultipleMatches")); if (extended_) { @@ -323,11 +317,6 @@ L1FPGATrackProducer::L1FPGATrackProducer(edm::ParameterSet const& iConfig) << "\n table_TRE : " << tableTREFile.fullPath(); } } - - trackQuality_ = iConfig.getParameter("TrackQuality"); - if (trackQuality_) { - trackQualityModel_ = std::make_unique(iConfig.getParameter("TrackQualityPSet")); - } if (settings_.storeTrackBuilderOutput() && (settings_.doMultipleMatches() || !settings_.removalType().empty())) { cms::Exception exception("ConfigurationNotSupported."); exception.addContext("L1FPGATrackProducer::produce"); @@ -360,13 +349,16 @@ void L1FPGATrackProducer::beginRun(const edm::Run& run, const edm::EventSetup& i double mMagneticFieldStrength = theMagneticField->inTesla(GlobalPoint(0, 0, 0)).z(); settings_.setBfield(mMagneticFieldStrength); - setup_ = &iSetup.getData(esGetToken_); + // helper class to store Track Trigger configuration + setup_ = &iSetup.getData(esGetTokenSetup_); + // helper class to store Tracklet spezific configuration + channelAssignment_ = &iSetup.getData(esGetTokenChannelAssignment_); + // helper class to determine track quality + trackQuality_ = &iSetup.getData(esGetTokenTrackQuality_); settings_.passSetup(setup_); setupHPH_ = &iSetup.getData(esGetTokenHPH_); - // Tracklet pattern reco output channel info. - channelAssignment_ = &iSetup.getData(esGetTokenChannelAssignment_); // initialize the tracklet event processing (this sets all the processing & memory modules, wiring, etc) eventProcessor.init(settings_, setup_); } @@ -427,7 +419,7 @@ void L1FPGATrackProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSe iEvent.getByToken(getTokenDTC_, handleDTC); // must be defined for code to compile, even if it's not used unless readMoreMcTruth_ is true - map, int> translateTP; + std::map, int> translateTP; // MC truth association maps edm::Handle> MCTruthTTClusterHandle; @@ -486,7 +478,7 @@ void L1FPGATrackProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSe for (const int& channel : handleDTC->tfpChannels()) { // Get the DTC name & ID from the channel unsigned int atcaSlot = channel % 12; - string dtcname = settings_.slotToDTCname(atcaSlot); + std::string dtcname = settings_.slotToDTCname(atcaSlot); if (channel % 24 >= 12) dtcname = "neg" + dtcname; dtcname += (channel < 24) ? "_A" : "_B"; // which detector region @@ -506,7 +498,7 @@ void L1FPGATrackProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSe const GlobalPoint& ttPos = setup_->stubPos(stubRef); //Get the 2 bits for the layercode - string layerword = stub.second.to_string().substr(61, 2); + std::string layerword = stub.second.to_string().substr(61, 2); unsigned int layercode = 2 * (layerword[0] - '0') + layerword[1] - '0'; assert(layercode < 4); @@ -533,13 +525,13 @@ void L1FPGATrackProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSe constexpr int DTCLinkWordSize = 64; constexpr int StubWordSize = 36; constexpr int LayerandStatusCodeSize = 3; - string stubword = + std::string stubword = stub.second.to_string().substr(DTCLinkWordSize - StubWordSize - LayerandStatusCodeSize, StubWordSize); - string stubwordhex = ""; + std::string stubwordhex = ""; //Loop over the 9 words in the 36 bit stub word for (unsigned int i = 0; i < 9; i++) { - bitset<4> bits(stubword.substr(i * 4, 4)); + std::bitset<4> bits(stubword.substr(i * 4, 4)); ulong val = bits.to_ulong(); stubwordhex += ((val < 10) ? ('0' + val) : ('A' + val - 10)); } @@ -574,7 +566,7 @@ void L1FPGATrackProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSe bool isFlipped = (posStub_outer.mag() < posStub_inner.mag()); - vector assocTPs; + std::vector assocTPs; for (unsigned int iClus = 0; iClus <= 1; iClus++) { // Loop over both clusters that make up stub. @@ -582,7 +574,7 @@ void L1FPGATrackProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSe // Now identify all TP's contributing to either cluster in stub. if (readMoreMcTruth_) { - vector> vecTpPtr = + std::vector> vecTpPtr = MCTruthTTClusterHandle->findTrackingParticlePtrs(ttClusterRef); for (const edm::Ptr& tpPtr : vecTpPtr) { @@ -605,7 +597,7 @@ void L1FPGATrackProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSe stubbend = -stubbend; } - bool barrel = (layerdisk < N_LAYER); + bool barrel = (layerdisk < trklet::N_LAYER); // See https://github.com/cms-sw/cmssw/tree/master/Geometry/TrackerNumberingBuilder enum TypeBarrel { nonBarrel = 0, tiltedMinus = 1, tiltedPlus = 2, flat = 3 }; const TypeBarrel type = static_cast(tTopo->tobSide(innerDetId)); @@ -668,9 +660,9 @@ void L1FPGATrackProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSe // max number of projection layers const unsigned int maxNumProjectionLayers = channelAssignment_->maxNumProjectionLayers(); // number of track channels - const unsigned int numStreamsTrack = N_SECTOR * channelAssignment_->numChannelsTrack(); + const unsigned int numStreamsTrack = trklet::N_SECTOR * channelAssignment_->numChannelsTrack(); // number of stub channels - const unsigned int numStreamsStub = N_SECTOR * channelAssignment_->numChannelsStub(); + const unsigned int numStreamsStub = trklet::N_SECTOR * channelAssignment_->numChannelsStub(); // number of seeding layers const unsigned int numSeedingLayers = channelAssignment_->numSeedingLayers(); // max number of stub channel per track @@ -679,8 +671,8 @@ void L1FPGATrackProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSe const unsigned int numStreamsStubRaw = numStreamsTrack * numStubChannel; // Streams formatted to allow this code to run outside CMSSW. - vector> streamsTrackRaw(numStreamsTrack); - vector> streamsStubRaw(numStreamsStubRaw); + std::vector> streamsTrackRaw(numStreamsTrack); + std::vector> streamsStubRaw(numStreamsStubRaw); // this performs the actual tracklet event processing eventProcessor.event(ev, streamsTrackRaw, streamsStubRaw); @@ -719,8 +711,8 @@ void L1FPGATrackProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSe aTrack.setPhiSector(trksector); aTrack.setTrackSeedType(trkseed); - const vector& stubptrs = track.stubs(); - vector stubs; + const std::vector& stubptrs = track.stubs(); + std::vector stubs; stubs.reserve(stubptrs.size()); for (const auto& stubptr : stubptrs) { @@ -748,7 +740,7 @@ void L1FPGATrackProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSe aTrack.setTrackWordBits(); if (trackQuality_) { - trackQualityModel_->setL1TrackQuality(aTrack); + trackQuality_->setL1TrackQuality(aTrack); } // hph::HitPatternHelper hph(setupHPH_, tmp_hit, tmp_tanL, tmp_z0); @@ -761,48 +753,55 @@ void L1FPGATrackProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSe // test track word //aTrack.testTrackWordBits(); + // set track word again to set MVA variable from TTTrack into track word + aTrack.setTrackWordBits(); + L1TkTracksForOutput->push_back(aTrack); } - iEvent.put(std::move(L1TkTracksForOutput), "Level1TTTracks"); + const edm::OrphanHandle oh = iEvent.emplace(putTokenTTTracks_, std::move(*L1TkTracksForOutput)); // produce clock and bit accurate stream output tracks and stubs. // from end of tracklet pattern recognition. // Convertion here is from stream format that allows this code to run // outside CMSSW to the EDProduct one. - Streams streamsTrack(numStreamsTrack); - StreamsStub streamsStub(numStreamsStub); - - for (unsigned int chanTrk = 0; chanTrk < numStreamsTrack; chanTrk++) { - for (unsigned int itk = 0; itk < streamsTrackRaw[chanTrk].size(); itk++) { - std::string bitsTrk = streamsTrackRaw[chanTrk][itk]; - int iSeed = chanTrk % channelAssignment_->numChannelsTrack(); // seed type - streamsTrack[chanTrk].emplace_back(bitsTrk); - - const unsigned int chanStubOffsetIn = chanTrk * numStubChannel; - const unsigned int chanStubOffsetOut = channelAssignment_->offsetStub(chanTrk); - const unsigned int numProjLayers = channelAssignment_->numProjectionLayers(iSeed); - TTBV hitMap(0, numProjLayers + numSeedingLayers); - // remove padding from stub stream - for (unsigned int iproj = 0; iproj < numStubChannel; iproj++) { - // FW current has one (perhaps invalid) stub per layer per track. - const StubStreamData& stubdata = streamsStubRaw[chanStubOffsetIn + iproj][itk]; - const L1TStub& stub = stubdata.stub(); - if (!stubdata.valid()) - continue; - const TTStubRef& ttStubRef = stubMap[stub]; - const int seedType = stubdata.iSeed(); - const int layerId = setup_->layerId(ttStubRef); - const int channelId = channelAssignment_->channelId(seedType, layerId); - hitMap.set(channelId); - streamsStub[chanStubOffsetOut + channelId].emplace_back(ttStubRef, stubdata.dataBits()); + int iTrk(0); + tt::StreamsTrack streamsTrack(numStreamsTrack); + tt::StreamsStub streamsStub(numStreamsStub); + for (int channel = 0; channel < (int)numStreamsTrack; channel++) { + const int seedType = channel % channelAssignment_->numChannelsTrack(); + const int numLayers = channelAssignment_->numProjectionLayers(seedType) + channelAssignment_->numSeedingLayers(); + const int offsetIn = channel * numStubChannel; + const int offsetOut = channelAssignment_->offsetStub(channel); + const std::vector& tracks = streamsTrackRaw[channel]; + tt::StreamTrack& streamTrack = streamsTrack[channel]; + streamTrack.reserve(tracks.size()); + for (int layer = 0; layer < numLayers; layer++) + streamsStub[offsetOut + layer].reserve(tracks.size()); + for (int frame = 0; frame < (int)tracks.size(); frame++) { + const tt::Frame bitsTrk(tracks[frame]); + if (bitsTrk.none()) { + streamTrack.emplace_back(tt::FrameTrack()); + for (int layer = 0; layer < numLayers; layer++) + streamsStub[offsetOut + layer].emplace_back(tt::FrameStub()); + continue; } - for (int layerId : hitMap.ids(false)) { // invalid stubs - streamsStub[chanStubOffsetOut + layerId].emplace_back(tt::FrameStub()); + const TTTrackRef ttTrackRef(oh, iTrk++); + streamTrack.emplace_back(ttTrackRef, bitsTrk); + tt::StreamStub stubs(numLayers, tt::FrameStub()); + for (int layer = 0; layer < numLayers; layer++) { + const trklet::StubStreamData& stub = streamsStubRaw[offsetIn + layer][frame]; + if (!stub.valid()) + continue; + const TTStubRef& ttStubRef = stubMap[stub.stub()]; + const int index = channelAssignment_->channelId(seedType, setup_->layerId(ttStubRef)); + stubs[index] = tt::FrameStub(ttStubRef, stub.dataBits()); } + int layer(0); + for (const tt::FrameStub& fs : stubs) + streamsStub[offsetOut + layer++].push_back(fs); } } - iEvent.emplace(putTokenTracks_, std::move(streamsTrack)); iEvent.emplace(putTokenStubs_, std::move(streamsStub)); diff --git a/L1Trigger/TrackFindingTracklet/plugins/ProducerChannelAssignment.cc b/L1Trigger/TrackFindingTracklet/plugins/ProducerChannelAssignment.cc index 474c485d09dcb..897e0529fda69 100644 --- a/L1Trigger/TrackFindingTracklet/plugins/ProducerChannelAssignment.cc +++ b/L1Trigger/TrackFindingTracklet/plugins/ProducerChannelAssignment.cc @@ -7,10 +7,6 @@ #include -using namespace std; -using namespace edm; -using namespace tt; - namespace trklet { /*! \class trklet::ProducerChannelAssignment @@ -19,25 +15,48 @@ namespace trklet { * \author Thomas Schuh * \date 2020, Nov */ - class ProducerChannelAssignment : public ESProducer { + class ProducerChannelAssignment : public edm::ESProducer { public: - ProducerChannelAssignment(const ParameterSet& iConfig); + ProducerChannelAssignment(const edm::ParameterSet& iConfig); ~ProducerChannelAssignment() override {} - unique_ptr produce(const ChannelAssignmentRcd& rcd); + std::unique_ptr produce(const ChannelAssignmentRcd& rcd); private: - const ParameterSet iConfig_; - ESGetToken esGetToken_; + ChannelAssignment::Config iConfig_; + edm::ESGetToken esGetToken_; }; - ProducerChannelAssignment::ProducerChannelAssignment(const ParameterSet& iConfig) : iConfig_(iConfig) { + ProducerChannelAssignment::ProducerChannelAssignment(const edm::ParameterSet& iConfig) { auto cc = setWhatProduced(this); esGetToken_ = cc.consumes(); + iConfig_.seedTypeNames_ = iConfig.getParameter>("SeedTypes"); + iConfig_.channelEncoding_ = iConfig.getParameter>("IRChannelsIn"); + const edm::ParameterSet& pSetTM = iConfig.getParameter("TM"); + iConfig_.tmMuxOrder_ = pSetTM.getParameter>("MuxOrder"); + iConfig_.tmNumLayers_ = pSetTM.getParameter("NumLayers"); + iConfig_.tmWidthStubId_ = pSetTM.getParameter("WidthStubId"); + iConfig_.tmWidthCot_ = pSetTM.getParameter("WidthCot"); + const edm::ParameterSet& pSetDR = iConfig.getParameter("DR"); + iConfig_.numComparisonModules_ = pSetDR.getParameter("NumComparisonModules"); + iConfig_.minIdenticalStubs_ = pSetDR.getParameter("MinIdenticalStubs"); + iConfig_.tmMuxOrderInt_.reserve(iConfig_.tmMuxOrder_.size()); + for (const std::string& s : iConfig_.tmMuxOrder_) + iConfig_.tmMuxOrderInt_.push_back(std::distance( + iConfig_.tmMuxOrder_.begin(), find(iConfig_.tmMuxOrder_.begin(), iConfig_.tmMuxOrder_.end(), s))); + const edm::ParameterSet& pSetSeedTypesSeedLayers = iConfig.getParameter("SeedTypesSeedLayers"); + const edm::ParameterSet& pSetSeedTypesProjectionLayers = + iConfig.getParameter("SeedTypesProjectionLayers"); + iConfig_.seedTypesSeedLayers_.reserve(iConfig_.seedTypeNames_.size()); + iConfig_.seedTypesProjectionLayers_.reserve(iConfig_.seedTypeNames_.size()); + for (const std::string& s : iConfig_.seedTypeNames_) { + iConfig_.seedTypesSeedLayers_.emplace_back(pSetSeedTypesSeedLayers.getParameter>(s)); + iConfig_.seedTypesProjectionLayers_.emplace_back(pSetSeedTypesProjectionLayers.getParameter>(s)); + } } - unique_ptr ProducerChannelAssignment::produce(const ChannelAssignmentRcd& rcd) { - const Setup* setup = &rcd.get(esGetToken_); - return make_unique(iConfig_, setup); + std::unique_ptr ProducerChannelAssignment::produce(const ChannelAssignmentRcd& rcd) { + const tt::Setup* setup = &rcd.get(esGetToken_); + return std::make_unique(iConfig_, setup); } } // namespace trklet diff --git a/L1Trigger/TrackFindingTracklet/plugins/ProducerDR.cc b/L1Trigger/TrackFindingTracklet/plugins/ProducerDR.cc index 1c8055c022282..456e08765911f 100644 --- a/L1Trigger/TrackFindingTracklet/plugins/ProducerDR.cc +++ b/L1Trigger/TrackFindingTracklet/plugins/ProducerDR.cc @@ -11,9 +11,10 @@ #include "DataFormats/Common/interface/Handle.h" #include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" +#include "L1Trigger/TrackerTFP/interface/LayerEncoding.h" +#include "L1Trigger/TrackFindingTracklet/interface/DataFormats.h" #include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h" -#include "L1Trigger/TrackFindingTracklet/interface/DR.h" +#include "L1Trigger/TrackFindingTracklet/interface/DuplicateRemoval.h" #include "SimDataFormats/Associations/interface/TTTypes.h" #include @@ -23,116 +24,81 @@ #include #include -using namespace std; -using namespace edm; -using namespace trackerTFP; -using namespace tt; - namespace trklet { /*! \class trklet::ProducerDR - * \brief Emulates removal of duplicated TTTracks f/w + * \brief Emulates removal of duplicated TTTracks f/w. + * Track order determined by TrackMultiplexer affects performance * \author Thomas Schuh * \date 2023, Feb */ - class ProducerDR : public stream::EDProducer<> { + class ProducerDR : public edm::stream::EDProducer<> { public: - explicit ProducerDR(const ParameterSet&); + explicit ProducerDR(const edm::ParameterSet&); ~ProducerDR() override {} private: - void beginRun(const Run&, const EventSetup&) override; - void produce(Event&, const EventSetup&) override; - virtual void endJob() {} + void produce(edm::Event&, const edm::EventSetup&) override; // ED input token of Tracks - EDGetTokenT edGetTokenTracks_; + edm::EDGetTokenT edGetTokenTracks_; // ED input token of Stubs - EDGetTokenT edGetTokenStubs_; + edm::EDGetTokenT edGetTokenStubs_; // ED output token for stubs - EDPutTokenT edPutTokenAcceptedStubs_; - EDPutTokenT edPutTokenLostStubs_; + edm::EDPutTokenT edPutTokenStubs_; // ED output token for tracks - EDPutTokenT edPutTokenAcceptedTracks_; - EDPutTokenT edPutTokenLostTracks_; + edm::EDPutTokenT edPutTokenTracks_; // Setup token - ESGetToken esGetTokenSetup_; + edm::ESGetToken esGetTokenSetup_; + // LayerEncoding token + edm::ESGetToken esGetTokenLayerEncoding_; // DataFormats token - ESGetToken esGetTokenDataFormats_; + edm::ESGetToken esGetTokenDataFormats_; // ChannelAssignment token - ESGetToken esGetTokenChannelAssignment_; - // configuration - ParameterSet iConfig_; - // helper class to store configurations - const Setup* setup_ = nullptr; - // helper class to extract structured data from tt::Frames - const DataFormats* dataFormats_ = nullptr; - // helper class to assign tracks to channel - const ChannelAssignment* channelAssignment_ = nullptr; + edm::ESGetToken esGetTokenChannelAssignment_; }; - ProducerDR::ProducerDR(const ParameterSet& iConfig) : iConfig_(iConfig) { - const string& label = iConfig.getParameter("LabelDRin"); - const string& branchAcceptedStubs = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchAcceptedTracks = iConfig.getParameter("BranchAcceptedTracks"); - const string& branchLostStubs = iConfig.getParameter("BranchLostStubs"); - const string& branchLostTracks = iConfig.getParameter("BranchLostTracks"); + ProducerDR::ProducerDR(const edm::ParameterSet& iConfig) { + const std::string& label = iConfig.getParameter("InputLabelDR"); + const std::string& branchStubs = iConfig.getParameter("BranchStubs"); + const std::string& branchTracks = iConfig.getParameter("BranchTracks"); // book in- and output ED products - edGetTokenTracks_ = consumes(InputTag(label, branchAcceptedTracks)); - edGetTokenStubs_ = consumes(InputTag(label, branchAcceptedStubs)); - edPutTokenAcceptedStubs_ = produces(branchAcceptedStubs); - edPutTokenAcceptedTracks_ = produces(branchAcceptedTracks); - edPutTokenLostStubs_ = produces(branchLostStubs); - edPutTokenLostTracks_ = produces(branchLostTracks); + edGetTokenTracks_ = consumes(edm::InputTag(label, branchTracks)); + edGetTokenStubs_ = consumes(edm::InputTag(label, branchStubs)); + edPutTokenTracks_ = produces(branchTracks); + edPutTokenStubs_ = produces(branchStubs); // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); - esGetTokenChannelAssignment_ = esConsumes(); + esGetTokenSetup_ = esConsumes(); + esGetTokenLayerEncoding_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + esGetTokenChannelAssignment_ = esConsumes(); } - void ProducerDR::beginRun(const Run& iRun, const EventSetup& iSetup) { + void ProducerDR::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { // helper class to store configurations - setup_ = &iSetup.getData(esGetTokenSetup_); - if (!setup_->configurationSupported()) - return; - // check process history if desired - if (iConfig_.getParameter("CheckHistory")) - setup_->checkHistory(iRun.processHistory()); + const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_); + // helper class to encode layer + const trackerTFP::LayerEncoding* layerEncoding = &iSetup.getData(esGetTokenLayerEncoding_); // helper class to extract structured data from tt::Frames - dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); + const DataFormats* dataFormats = &iSetup.getData(esGetTokenDataFormats_); // helper class to assign tracks to channel - channelAssignment_ = &iSetup.getData(esGetTokenChannelAssignment_); - } - - void ProducerDR::produce(Event& iEvent, const EventSetup& iSetup) { + const ChannelAssignment* channelAssignment = &iSetup.getData(esGetTokenChannelAssignment_); // empty DR products - const int numStreamsTracks = channelAssignment_->numNodesDR() * setup_->numRegions(); - const int numStreamsStubs = numStreamsTracks * setup_->numLayers(); - StreamsStub acceptedStubs(numStreamsStubs); - StreamsTrack acceptedTracks(numStreamsTracks); - StreamsStub lostStubs(numStreamsStubs); - StreamsTrack lostTracks(numStreamsTracks); + tt::StreamsStub streamsStub(setup->numRegions() * setup->numLayers()); + tt::StreamsTrack streamsTrack(setup->numRegions()); // read in TBout Product and produce KFin product - if (setup_->configurationSupported()) { - Handle handleStubs; - iEvent.getByToken(edGetTokenStubs_, handleStubs); - const StreamsStub& stubs = *handleStubs; - Handle handleTracks; - iEvent.getByToken(edGetTokenTracks_, handleTracks); - const StreamsTrack& tracks = *handleTracks; - for (int region = 0; region < setup_->numRegions(); region++) { - // object to remove duplicated tracks in a processing region - DR dr(iConfig_, setup_, dataFormats_, channelAssignment_, region); - // read in and organize input tracks and stubs - dr.consume(tracks, stubs); - // fill output products - dr.produce(acceptedStubs, acceptedTracks, lostStubs, lostTracks); - } + const tt::StreamsStub& stubs = iEvent.get(edGetTokenStubs_); + const tt::StreamsTrack& tracks = iEvent.get(edGetTokenTracks_); + for (int region = 0; region < setup->numRegions(); region++) { + // object to remove duplicated tracks in a processing region + DuplicateRemoval dr(setup, layerEncoding, dataFormats, channelAssignment, region); + // read in and organize input tracks and stubs + dr.consume(tracks, stubs); + // fill output products + dr.produce(streamsTrack, streamsStub); } // store products - iEvent.emplace(edPutTokenAcceptedStubs_, std::move(acceptedStubs)); - iEvent.emplace(edPutTokenAcceptedTracks_, std::move(acceptedTracks)); - iEvent.emplace(edPutTokenLostStubs_, std::move(lostStubs)); - iEvent.emplace(edPutTokenLostTracks_, std::move(lostTracks)); + iEvent.emplace(edPutTokenStubs_, std::move(streamsStub)); + iEvent.emplace(edPutTokenTracks_, std::move(streamsTrack)); } } // namespace trklet diff --git a/L1Trigger/TrackFindingTracklet/plugins/ProducerDRin.cc b/L1Trigger/TrackFindingTracklet/plugins/ProducerDRin.cc deleted file mode 100644 index 86b0dd8f3e48b..0000000000000 --- a/L1Trigger/TrackFindingTracklet/plugins/ProducerDRin.cc +++ /dev/null @@ -1,152 +0,0 @@ -#include "FWCore/Framework/interface/stream/EDProducer.h" -#include "FWCore/Framework/interface/Run.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Utilities/interface/EDGetToken.h" -#include "FWCore/Utilities/interface/EDPutToken.h" -#include "FWCore/Utilities/interface/ESGetToken.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "DataFormats/Common/interface/Handle.h" - -#include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" -#include "L1Trigger/TrackerTFP/interface/LayerEncoding.h" -#include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h" -#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" -#include "L1Trigger/TrackFindingTracklet/interface/DRin.h" -#include "SimDataFormats/Associations/interface/TTTypes.h" - -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace edm; -using namespace trackerTFP; -using namespace tt; - -namespace trklet { - - /*! \class trklet::ProducerDRin - * \brief Transforms format of TBout into that expected by DR input. - * \author Thomas Schuh - * \date 2023, Jan - */ - class ProducerDRin : public stream::EDProducer<> { - public: - explicit ProducerDRin(const ParameterSet&); - ~ProducerDRin() override {} - - private: - void beginRun(const Run&, const EventSetup&) override; - void produce(Event&, const EventSetup&) override; - virtual void endJob() {} - - // ED input token of Tracks - EDGetTokenT edGetTokenTracks_; - // ED input token of Stubs - EDGetTokenT edGetTokenStubs_; - // ED output token for stubs - EDPutTokenT edPutTokenAcceptedStubs_; - EDPutTokenT edPutTokenLostStubs_; - // ED output token for tracks - EDPutTokenT edPutTokenAcceptedTracks_; - EDPutTokenT edPutTokenLostTracks_; - // Setup token - ESGetToken esGetTokenSetup_; - // DataFormats token - ESGetToken esGetTokenDataFormats_; - // LayerEncoding token - ESGetToken esGetTokenLayerEncoding_; - // ChannelAssignment token - ESGetToken esGetTokenChannelAssignment_; - // configuration - ParameterSet iConfig_; - // helper class to store configurations - const Setup* setup_ = nullptr; - // helper class to extract structured data from tt::Frames - const DataFormats* dataFormats_ = nullptr; - // helper class to encode layer - const LayerEncoding* layerEncoding_ = nullptr; - // helper class to assign tracks to channel - const ChannelAssignment* channelAssignment_ = nullptr; - // helper class to store tracklet configurations - Settings settings_; - }; - - ProducerDRin::ProducerDRin(const ParameterSet& iConfig) : iConfig_(iConfig) { - const string& label = iConfig.getParameter("LabelTBout"); - const string& branchAcceptedStubs = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchAcceptedTracks = iConfig.getParameter("BranchAcceptedTracks"); - const string& branchLostStubs = iConfig.getParameter("BranchLostStubs"); - const string& branchLostTracks = iConfig.getParameter("BranchLostTracks"); - // book in- and output ED products - edGetTokenTracks_ = consumes(InputTag(label, branchAcceptedTracks)); - edGetTokenStubs_ = consumes(InputTag(label, branchAcceptedStubs)); - edPutTokenAcceptedStubs_ = produces(branchAcceptedStubs); - edPutTokenAcceptedTracks_ = produces(branchAcceptedTracks); - edPutTokenLostStubs_ = produces(branchLostStubs); - edPutTokenLostTracks_ = produces(branchLostTracks); - // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); - esGetTokenLayerEncoding_ = esConsumes(); - esGetTokenChannelAssignment_ = esConsumes(); - } - - void ProducerDRin::beginRun(const Run& iRun, const EventSetup& iSetup) { - // helper class to store configurations - setup_ = &iSetup.getData(esGetTokenSetup_); - if (!setup_->configurationSupported()) - return; - // check process history if desired - if (iConfig_.getParameter("CheckHistory")) - setup_->checkHistory(iRun.processHistory()); - // helper class to extract structured data from tt::Frames - dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); - // helper class to encode layer - layerEncoding_ = &iSetup.getData(esGetTokenLayerEncoding_); - // helper class to assign tracks to channel - channelAssignment_ = &iSetup.getData(esGetTokenChannelAssignment_); - } - - void ProducerDRin::produce(Event& iEvent, const EventSetup& iSetup) { - // empty KFin products - const int numStreamsTracks = channelAssignment_->numNodesDR() * setup_->numRegions(); - const int numStreamsStubs = numStreamsTracks * setup_->numLayers(); - StreamsStub acceptedStubs(numStreamsStubs); - StreamsTrack acceptedTracks(numStreamsTracks); - StreamsStub lostStubs(numStreamsStubs); - StreamsTrack lostTracks(numStreamsTracks); - // read in TBout Product and produce KFin product - if (setup_->configurationSupported()) { - Handle handleStubs; - iEvent.getByToken(edGetTokenStubs_, handleStubs); - const StreamsStub& stubs = *handleStubs; - Handle handleTracks; - iEvent.getByToken(edGetTokenTracks_, handleTracks); - const StreamsTrack& tracks = *handleTracks; - for (int region = 0; region < setup_->numRegions(); region++) { - // object to reformat tracks from tracklet fromat to TMTT format in a processing region - DRin drin(iConfig_, setup_, dataFormats_, layerEncoding_, channelAssignment_, &settings_, region); - // read in and organize input tracks and stubs - drin.consume(tracks, stubs); - // fill output products - drin.produce(acceptedStubs, acceptedTracks, lostStubs, lostTracks); - } - } - // store products - iEvent.emplace(edPutTokenAcceptedStubs_, std::move(acceptedStubs)); - iEvent.emplace(edPutTokenAcceptedTracks_, std::move(acceptedTracks)); - iEvent.emplace(edPutTokenLostStubs_, std::move(lostStubs)); - iEvent.emplace(edPutTokenLostTracks_, std::move(lostTracks)); - } - -} // namespace trklet - -DEFINE_FWK_MODULE(trklet::ProducerDRin); diff --git a/L1Trigger/TrackFindingTracklet/plugins/ProducerDataFormats.cc b/L1Trigger/TrackFindingTracklet/plugins/ProducerDataFormats.cc new file mode 100644 index 0000000000000..f2192a5e4a194 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/plugins/ProducerDataFormats.cc @@ -0,0 +1,41 @@ +#include "FWCore/Framework/interface/ESProducer.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "FWCore/Utilities/interface/ESInputTag.h" +#include "DataFormats/Provenance/interface/ParameterSetID.h" +#include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h" +#include "L1Trigger/TrackFindingTracklet/interface/DataFormats.h" + +#include + +namespace trklet { + + /*! \class trklet::ProducerDataFormats + * \brief Class to produce setup of Hybrid emulator data formats + * \author Thomas Schuh + * \date 2024, Sep + */ + class ProducerDataFormats : public edm::ESProducer { + public: + ProducerDataFormats(const edm::ParameterSet& iConfig); + ~ProducerDataFormats() override {} + std::unique_ptr produce(const ChannelAssignmentRcd& rcd); + + private: + edm::ESGetToken esGetToken_; + }; + + ProducerDataFormats::ProducerDataFormats(const edm::ParameterSet& iConfig) { + auto cc = setWhatProduced(this); + esGetToken_ = cc.consumes(); + } + + std::unique_ptr ProducerDataFormats::produce(const ChannelAssignmentRcd& rcd) { + const ChannelAssignment* ca = &rcd.get(esGetToken_); + return std::make_unique(ca); + } + +} // namespace trklet + +DEFINE_FWK_EVENTSETUP_MODULE(trklet::ProducerDataFormats); diff --git a/L1Trigger/TrackFindingTracklet/plugins/ProducerHPH.cc b/L1Trigger/TrackFindingTracklet/plugins/ProducerHPH.cc index cb308b8b628ea..8413df67e60ba 100644 --- a/L1Trigger/TrackFindingTracklet/plugins/ProducerHPH.cc +++ b/L1Trigger/TrackFindingTracklet/plugins/ProducerHPH.cc @@ -17,36 +17,38 @@ #include -using namespace std; -using namespace edm; - namespace hph { - class ProducerHPH : public ESProducer { + class ProducerHPH : public edm::ESProducer { public: - ProducerHPH(const ParameterSet& iConfig); + ProducerHPH(const edm::ParameterSet& iConfig); ~ProducerHPH() override {} - unique_ptr produce(const SetupRcd& Rcd); + std::unique_ptr produce(const SetupRcd& Rcd); private: - const ParameterSet iConfig_; - ESGetToken esGetTokenSetup_; - ESGetToken esGetTokenDataFormats_; - ESGetToken esGetTokenLayerEncoding_; + Setup::Config iConfig_; + edm::ESGetToken esGetTokenSetup_; + edm::ESGetToken esGetTokenDataFormats_; + edm::ESGetToken esGetTokenLayerEncoding_; }; - ProducerHPH::ProducerHPH(const ParameterSet& iConfig) : iConfig_(iConfig) { + ProducerHPH::ProducerHPH(const edm::ParameterSet& iConfig) { auto cc = setWhatProduced(this); esGetTokenSetup_ = cc.consumes(); esGetTokenDataFormats_ = cc.consumes(); esGetTokenLayerEncoding_ = cc.consumes(); + const edm::ParameterSet& oldKFPSet = iConfig.getParameter("oldKFPSet"); + iConfig_.hphDebug_ = iConfig.getParameter("hphDebug"); + iConfig_.useNewKF_ = iConfig.getParameter("useNewKF"); + iConfig_.chosenRofZ_ = oldKFPSet.getParameter("ChosenRofZ"); + iConfig_.etaRegions_ = oldKFPSet.getParameter>("EtaRegions"); } - unique_ptr ProducerHPH::produce(const SetupRcd& Rcd) { + std::unique_ptr ProducerHPH::produce(const SetupRcd& Rcd) { const tt::Setup& setupTT = Rcd.get(esGetTokenSetup_); const trackerTFP::DataFormats& dataFormats = Rcd.get(esGetTokenDataFormats_); const trackerTFP::LayerEncoding& layerEncoding = Rcd.get(esGetTokenLayerEncoding_); - return make_unique(iConfig_, setupTT, dataFormats, layerEncoding); + return std::make_unique(iConfig_, setupTT, dataFormats, layerEncoding); } } // namespace hph diff --git a/L1Trigger/TrackFindingTracklet/plugins/ProducerKF.cc b/L1Trigger/TrackFindingTracklet/plugins/ProducerKF.cc new file mode 100644 index 0000000000000..59f4459504f4d --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/plugins/ProducerKF.cc @@ -0,0 +1,195 @@ +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Utilities/interface/EDPutToken.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "DataFormats/Common/interface/Handle.h" + +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackFindingTracklet/interface/DataFormats.h" +#include "L1Trigger/TrackFindingTracklet/interface/KalmanFilter.h" +#include "L1Trigger/TrackFindingTMTT/interface/Settings.h" +#include "L1Trigger/TrackFindingTMTT/interface/KFParamsComb.h" + +#include +#include + +namespace trklet { + + /*! \class trklet::ProducerKF + * \brief L1TrackTrigger Kamlan Filter emulator + * \author Thomas Schuh + * \date 2020, July + */ + class ProducerKF : public edm::stream::EDProducer<> { + public: + explicit ProducerKF(const edm::ParameterSet&); + ~ProducerKF() override {} + + private: + void produce(edm::Event&, const edm::EventSetup&) override; + void endStream() override { + std::stringstream ss; + if (printDebug_) + kalmanFilterFormats_.endJob(ss); + edm::LogPrint(moduleDescription().moduleName()) << ss.str(); + } + // ED input token of sf stubs and tracks + edm::EDGetTokenT edGetTokenStubs_; + edm::EDGetTokenT edGetTokenTracks_; + // ED output token for accepted stubs and tracks + edm::EDPutTokenT edPutTokenTTTracks_; + edm::EDPutTokenT edPutTokenStubs_; + edm::EDPutTokenT edPutTokenTracks_; + // ED output token for number of accepted and lost States + edm::EDPutTokenT edPutTokenNumStatesAccepted_; + edm::EDPutTokenT edPutTokenNumStatesTruncated_; + // Setup token + edm::ESGetToken esGetTokenSetup_; + // DataFormats token + edm::ESGetToken esGetTokenDataFormats_; + // provides dataformats of Kalman filter internals + KalmanFilterFormats kalmanFilterFormats_; + // + ConfigKF iConfig_; + // + tmtt::Settings settings_; + // + tmtt::KFParamsComb tmtt4_; + // + tmtt::KFParamsComb tmtt5_; + // + tmtt::KFParamsComb* tmtt_; + // print end job internal unused MSB + bool printDebug_; + }; + + ProducerKF::ProducerKF(const edm::ParameterSet& iConfig) + : settings_(iConfig), + tmtt4_(&settings_, 4, "KF5ParamsComb"), + tmtt5_(&settings_, 5, "KF4ParamsComb"), + tmtt_(&tmtt4_) { + iConfig_.enableIntegerEmulation_ = iConfig.getParameter("EnableIntegerEmulation"); + iConfig_.widthR00_ = iConfig.getParameter("WidthR00"); + iConfig_.widthR11_ = iConfig.getParameter("WidthR11"); + iConfig_.widthC00_ = iConfig.getParameter("WidthC00"); + iConfig_.widthC01_ = iConfig.getParameter("WidthC01"); + iConfig_.widthC11_ = iConfig.getParameter("WidthC11"); + iConfig_.widthC22_ = iConfig.getParameter("WidthC22"); + iConfig_.widthC23_ = iConfig.getParameter("WidthC23"); + iConfig_.widthC33_ = iConfig.getParameter("WidthC33"); + iConfig_.baseShiftx0_ = iConfig.getParameter("BaseShiftx0"); + iConfig_.baseShiftx1_ = iConfig.getParameter("BaseShiftx1"); + iConfig_.baseShiftx2_ = iConfig.getParameter("BaseShiftx2"); + iConfig_.baseShiftx3_ = iConfig.getParameter("BaseShiftx3"); + iConfig_.baseShiftr0_ = iConfig.getParameter("BaseShiftr0"); + iConfig_.baseShiftr1_ = iConfig.getParameter("BaseShiftr1"); + iConfig_.baseShiftS00_ = iConfig.getParameter("BaseShiftS00"); + iConfig_.baseShiftS01_ = iConfig.getParameter("BaseShiftS01"); + iConfig_.baseShiftS12_ = iConfig.getParameter("BaseShiftS12"); + iConfig_.baseShiftS13_ = iConfig.getParameter("BaseShiftS13"); + iConfig_.baseShiftR00_ = iConfig.getParameter("BaseShiftR00"); + iConfig_.baseShiftR11_ = iConfig.getParameter("BaseShiftR11"); + iConfig_.baseShiftInvR00Approx_ = iConfig.getParameter("BaseShiftInvR00Approx"); + iConfig_.baseShiftInvR11Approx_ = iConfig.getParameter("BaseShiftInvR11Approx"); + iConfig_.baseShiftInvR00Cor_ = iConfig.getParameter("BaseShiftInvR00Cor"); + iConfig_.baseShiftInvR11Cor_ = iConfig.getParameter("BaseShiftInvR11Cor"); + iConfig_.baseShiftInvR00_ = iConfig.getParameter("BaseShiftInvR00"); + iConfig_.baseShiftInvR11_ = iConfig.getParameter("BaseShiftInvR11"); + iConfig_.baseShiftS00Shifted_ = iConfig.getParameter("BaseShiftS00Shifted"); + iConfig_.baseShiftS01Shifted_ = iConfig.getParameter("BaseShiftS01Shifted"); + iConfig_.baseShiftS12Shifted_ = iConfig.getParameter("BaseShiftS12Shifted"); + iConfig_.baseShiftS13Shifted_ = iConfig.getParameter("BaseShiftS13Shifted"); + iConfig_.baseShiftK00_ = iConfig.getParameter("BaseShiftK00"); + iConfig_.baseShiftK10_ = iConfig.getParameter("BaseShiftK10"); + iConfig_.baseShiftK21_ = iConfig.getParameter("BaseShiftK21"); + iConfig_.baseShiftK31_ = iConfig.getParameter("BaseShiftK31"); + iConfig_.baseShiftC00_ = iConfig.getParameter("BaseShiftC00"); + iConfig_.baseShiftC01_ = iConfig.getParameter("BaseShiftC01"); + iConfig_.baseShiftC11_ = iConfig.getParameter("BaseShiftC11"); + iConfig_.baseShiftC22_ = iConfig.getParameter("BaseShiftC22"); + iConfig_.baseShiftC23_ = iConfig.getParameter("BaseShiftC23"); + iConfig_.baseShiftC33_ = iConfig.getParameter("BaseShiftC33"); + printDebug_ = iConfig.getParameter("PrintKFDebug"); + const std::string& label = iConfig.getParameter("InputLabelKF"); + const std::string& branchStubs = iConfig.getParameter("BranchStubs"); + const std::string& branchTracks = iConfig.getParameter("BranchTracks"); + const std::string& branchTruncated = iConfig.getParameter("BranchTruncated"); + // book in- and output ED products + edGetTokenStubs_ = consumes(edm::InputTag(label, branchStubs)); + edGetTokenTracks_ = consumes(edm::InputTag(label, branchTracks)); + edPutTokenStubs_ = produces(branchStubs); + edPutTokenTracks_ = produces(branchTracks); + edPutTokenTTTracks_ = produces(branchTracks); + edPutTokenNumStatesAccepted_ = produces(branchTracks); + edPutTokenNumStatesTruncated_ = produces(branchTruncated); + // book ES products + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + } + + void ProducerKF::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + // helper class to store configurations + const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_); + settings_.setMagneticField(setup->bField()); + // helper class to extract structured data from tt::Frames + const DataFormats* dataFormats = &iSetup.getData(esGetTokenDataFormats_); + kalmanFilterFormats_.consume(dataFormats, iConfig_); + auto valid = [](int sum, const tt::FrameTrack& f) { return sum + (f.first.isNull() ? 0 : 1); }; + // empty KF products + tt::StreamsStub streamsStub(setup->numRegions() * setup->numLayers()); + tt::StreamsTrack streamsTrack(setup->numRegions()); + int numStatesAccepted(0); + int numStatesTruncated(0); + // read in DR Product and produce KF product + const tt::StreamsStub& stubs = iEvent.get(edGetTokenStubs_); + const tt::StreamsTrack& tracks = iEvent.get(edGetTokenTracks_); + // prep TTTracks + tt::TTTracks ttTracks; + std::vector ttTrackRefs; + if (setup->kfUse5ParameterFit()) { + tmtt_ = &tmtt5_; + int nTracks(0); + for (const tt::StreamTrack& stream : tracks) + nTracks += std::accumulate(stream.begin(), stream.end(), 0, valid); + ttTracks.reserve(nTracks); + ttTrackRefs.reserve(nTracks); + for (const tt::StreamTrack& stream : tracks) + for (const tt::FrameTrack& frame : stream) + if (frame.first.isNonnull()) + ttTrackRefs.push_back(frame.first); + } + for (int region = 0; region < setup->numRegions(); region++) { + // object to fit tracks in a processing region + KalmanFilter kf(setup, dataFormats, &kalmanFilterFormats_, &settings_, tmtt_, region, ttTracks); + // read in and organize input tracks and stubs + kf.consume(tracks, stubs); + // fill output products + kf.produce(streamsStub, streamsTrack, numStatesAccepted, numStatesTruncated); + } + if (setup->kfUse5ParameterFit()) { + // store ttTracks + const edm::OrphanHandle oh = iEvent.emplace(edPutTokenTTTracks_, std::move(ttTracks)); + // replace ttTrackRefs in track streams + int iTrk(0); + for (tt::StreamTrack& stream : streamsTrack) + for (tt::FrameTrack& frame : stream) + if (frame.first.isNonnull()) + frame.first = TTTrackRef(oh, iTrk++); + } + // store products + iEvent.emplace(edPutTokenStubs_, std::move(streamsStub)); + iEvent.emplace(edPutTokenTracks_, std::move(streamsTrack)); + iEvent.emplace(edPutTokenNumStatesAccepted_, numStatesAccepted); + iEvent.emplace(edPutTokenNumStatesTruncated_, numStatesTruncated); + } + +} // namespace trklet + +DEFINE_FWK_MODULE(trklet::ProducerKF); diff --git a/L1Trigger/TrackFindingTracklet/plugins/ProducerKFin.cc b/L1Trigger/TrackFindingTracklet/plugins/ProducerKFin.cc deleted file mode 100644 index 1a23f97513f01..0000000000000 --- a/L1Trigger/TrackFindingTracklet/plugins/ProducerKFin.cc +++ /dev/null @@ -1,147 +0,0 @@ -#include "FWCore/Framework/interface/stream/EDProducer.h" -#include "FWCore/Framework/interface/Run.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Utilities/interface/EDGetToken.h" -#include "FWCore/Utilities/interface/EDPutToken.h" -#include "FWCore/Utilities/interface/ESGetToken.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "DataFormats/Common/interface/Handle.h" - -#include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" -#include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h" -#include "L1Trigger/TrackFindingTracklet/interface/KFin.h" -#include "SimDataFormats/Associations/interface/TTTypes.h" - -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace edm; -using namespace trackerTFP; -using namespace tt; - -namespace trklet { - - /*! \class trklet::ProducerKFin - * \brief Transforms format of DR into that expected by KF input. - * \author Thomas Schuh - * \date 2023, Feb - */ - class ProducerKFin : public stream::EDProducer<> { - public: - explicit ProducerKFin(const ParameterSet&); - ~ProducerKFin() override {} - - private: - void beginRun(const Run&, const EventSetup&) override; - void produce(Event&, const EventSetup&) override; - virtual void endJob() {} - // ED input token of Tracks - EDGetTokenT edGetTokenTracks_; - // ED input token of Stubs - EDGetTokenT edGetTokenStubs_; - // ED output token for stubs - EDPutTokenT edPutTokenAcceptedStubs_; - EDPutTokenT edPutTokenLostStubs_; - // ED output token for tracks - EDPutTokenT edPutTokenAcceptedTracks_; - EDPutTokenT edPutTokenLostTracks_; - // Setup token - ESGetToken esGetTokenSetup_; - // DataFormats token - ESGetToken esGetTokenDataFormats_; - // LayerEncoding token - ESGetToken esGetTokenLayerEncoding_; - // ChannelAssignment token - ESGetToken esGetTokenChannelAssignment_; - // configuration - ParameterSet iConfig_; - // helper class to store configurations - const Setup* setup_ = nullptr; - // helper class to extract structured data from tt::Frames - const DataFormats* dataFormats_ = nullptr; - // helper class to encode layer - const LayerEncoding* layerEncoding_ = nullptr; - // helper class to assign tracks to channel - const ChannelAssignment* channelAssignment_ = nullptr; - }; - - ProducerKFin::ProducerKFin(const ParameterSet& iConfig) : iConfig_(iConfig) { - const string& label = iConfig.getParameter("LabelDR"); - const string& branchAcceptedStubs = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchAcceptedTracks = iConfig.getParameter("BranchAcceptedTracks"); - const string& branchLostStubs = iConfig.getParameter("BranchLostStubs"); - const string& branchLostTracks = iConfig.getParameter("BranchLostTracks"); - // book in- and output ED products - edGetTokenTracks_ = consumes(InputTag(label, branchAcceptedTracks)); - edGetTokenStubs_ = consumes(InputTag(label, branchAcceptedStubs)); - edPutTokenAcceptedStubs_ = produces(branchAcceptedStubs); - edPutTokenAcceptedTracks_ = produces(branchAcceptedTracks); - edPutTokenLostStubs_ = produces(branchLostStubs); - edPutTokenLostTracks_ = produces(branchLostTracks); - // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); - esGetTokenLayerEncoding_ = esConsumes(); - esGetTokenChannelAssignment_ = esConsumes(); - } - - void ProducerKFin::beginRun(const Run& iRun, const EventSetup& iSetup) { - // helper class to store configurations - setup_ = &iSetup.getData(esGetTokenSetup_); - if (!setup_->configurationSupported()) - return; - // check process history if desired - if (iConfig_.getParameter("CheckHistory")) - setup_->checkHistory(iRun.processHistory()); - // helper class to extract structured data from tt::Frames - dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); - // helper class to encode layer - layerEncoding_ = &iSetup.getData(esGetTokenLayerEncoding_); - // helper class to assign tracks to channel - channelAssignment_ = &iSetup.getData(esGetTokenChannelAssignment_); - } - - void ProducerKFin::produce(Event& iEvent, const EventSetup& iSetup) { - // empty KFin products - const int numStreamsTracks = setup_->kfNumWorker() * setup_->numRegions(); - const int numStreamsStubs = numStreamsTracks * setup_->numLayers(); - StreamsStub acceptedStubs(numStreamsStubs); - StreamsTrack acceptedTracks(numStreamsTracks); - StreamsStub lostStubs(numStreamsStubs); - StreamsTrack lostTracks(numStreamsTracks); - // read in TBout Product and produce KFin product - if (setup_->configurationSupported()) { - Handle handleStubs; - iEvent.getByToken(edGetTokenStubs_, handleStubs); - const StreamsStub& stubs = *handleStubs; - Handle handleTracks; - iEvent.getByToken(edGetTokenTracks_, handleTracks); - const StreamsTrack& tracks = *handleTracks; - for (int region = 0; region < setup_->numRegions(); region++) { - // object to reformat tracks from DR fromat to KF format in a processing region - KFin kfin(iConfig_, setup_, dataFormats_, layerEncoding_, channelAssignment_, region); - // read in and organize input tracks and stubs - kfin.consume(tracks, stubs); - // fill output products - kfin.produce(acceptedStubs, acceptedTracks, lostStubs, lostTracks); - } - } - // store products - iEvent.emplace(edPutTokenAcceptedStubs_, std::move(acceptedStubs)); - iEvent.emplace(edPutTokenAcceptedTracks_, std::move(acceptedTracks)); - iEvent.emplace(edPutTokenLostStubs_, std::move(lostStubs)); - iEvent.emplace(edPutTokenLostTracks_, std::move(lostTracks)); - } - -} // namespace trklet - -DEFINE_FWK_MODULE(trklet::ProducerKFin); diff --git a/L1Trigger/TrackFindingTracklet/plugins/ProducerKFout.cc b/L1Trigger/TrackFindingTracklet/plugins/ProducerKFout.cc deleted file mode 100644 index f7001add46306..0000000000000 --- a/L1Trigger/TrackFindingTracklet/plugins/ProducerKFout.cc +++ /dev/null @@ -1,381 +0,0 @@ -#include "FWCore/Framework/interface/stream/EDProducer.h" -#include "FWCore/Framework/interface/Run.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Utilities/interface/EDGetToken.h" -#include "FWCore/Utilities/interface/EDPutToken.h" -#include "FWCore/Utilities/interface/ESGetToken.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "DataFormats/Common/interface/Handle.h" - -#include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" -#include "L1Trigger/TrackTrigger/interface/L1TrackQuality.h" - -#include -#include - -using namespace std; -using namespace edm; -using namespace trackerTFP; -using namespace tt; - -namespace trklet { - - /*! \class trklet::ProducerKFout - * \brief Converts KF output into tttrack collection and TFP output - * A bit accurate emulation of the track transformation, the - * eta routing and splitting of the 96-bit track words into 64-bit - * packets. Also run is a bit accurate emulation of the track quality - * BDT, whose output is also added to the track word. - * \author Christopher Brown - * \date 2021, Aug - * \update 2024, June by Claire Savard - */ - class ProducerKFout : public stream::EDProducer<> { - public: - explicit ProducerKFout(const ParameterSet&); - ~ProducerKFout() override {} - - private: - void beginRun(const Run&, const EventSetup&) override; - void produce(Event&, const EventSetup&) override; - void endJob() {} - - // ED input token of kf stubs - EDGetTokenT edGetTokenStubs_; - // ED input token of kf tracks - EDGetTokenT edGetTokenTracks_; - // ED output token for accepted kfout tracks - EDPutTokenT edPutTokenAccepted_; - // ED output token for TTTracks - EDPutTokenT edPutTokenTTTracks_; - // ED output token for truncated kfout tracks - EDPutTokenT edPutTokenLost_; - // Setup token - ESGetToken esGetTokenSetup_; - // DataFormats token - ESGetToken esGetTokenDataFormats_; - // configuration - ParameterSet iConfig_; - // helper class to store configurations - const Setup* setup_; - // helper class to extract structured data from tt::Frames - const DataFormats* dataFormats_; - // Bins for dPhi/dZ use to create weight LUT - vector dPhiBins_; - vector dZBins_; - - std::unique_ptr trackQualityModel_; - double tqTanlScale_; - double tqZ0Scale_; - static constexpr double ap_fixed_rescale = 32.0; - - // For convenience and keeping readable code, accessed many times - int numWorkers_; - int partialTrackWordBits_; - - // Helper function to convert floating value to bin - template - unsigned int digitise(const T& bins, double value, double factor) { - unsigned int bin = 0; - for (unsigned int i = 0; i < bins.size() - 1; i++) { - if (value * factor > bins[i] && value * factor <= bins[i + 1]) - break; - bin++; - } - return bin; - } - }; - - ProducerKFout::ProducerKFout(const ParameterSet& iConfig) : iConfig_(iConfig) { - const string& labelKF = iConfig.getParameter("LabelKF"); - const string& branchStubs = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchTracks = iConfig.getParameter("BranchAcceptedTracks"); - const string& branchTTTracks = iConfig.getParameter("BranchAcceptedTTTracks"); - const string& branchLost = iConfig.getParameter("BranchLostTracks"); - // book in- and output ED products - edGetTokenStubs_ = consumes(InputTag(labelKF, branchStubs)); - edGetTokenTracks_ = consumes(InputTag(labelKF, branchTracks)); - edPutTokenAccepted_ = produces(branchTracks); - edPutTokenTTTracks_ = produces(branchTTTracks); - edPutTokenLost_ = produces(branchLost); - // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); - // initial ES products - setup_ = nullptr; - dataFormats_ = nullptr; - - trackQualityModel_ = std::make_unique(iConfig.getParameter("TrackQualityPSet")); - edm::ParameterSet trackQualityPSset = iConfig.getParameter("TrackQualityPSet"); - tqTanlScale_ = trackQualityPSset.getParameter("tqemu_TanlScale"); - tqZ0Scale_ = trackQualityPSset.getParameter("tqemu_Z0Scale"); - } - - void ProducerKFout::beginRun(const Run& iRun, const EventSetup& iSetup) { - // helper class to store configurations - setup_ = &iSetup.getData(esGetTokenSetup_); - if (!setup_->configurationSupported()) - return; - // check process history if desired - if (iConfig_.getParameter("CheckHistory")) - setup_->checkHistory(iRun.processHistory()); - // helper class to extract structured data from tt::Frames - dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); - - // Calculate 1/dz**2 and 1/dphi**2 bins for v0 and v1 weightings - float temp_dphi = 0.0; - float temp_dz = 0.0; - for (int i = 0; - i < pow(2, dataFormats_->width(Variable::dPhi, Process::kfin)) / pow(2, setup_->weightBinFraction()); - i++) { - temp_dphi = - pow(dataFormats_->base(Variable::dPhi, Process::kfin) * (i + 1) * pow(2, setup_->weightBinFraction()), -2); - temp_dphi = temp_dphi / setup_->dphiTruncation(); - temp_dphi = std::floor(temp_dphi); - dPhiBins_.push_back(temp_dphi * setup_->dphiTruncation()); - } - for (int i = 0; i < pow(2, dataFormats_->width(Variable::dZ, Process::kfin)) / pow(2, setup_->weightBinFraction()); - i++) { - temp_dz = - pow(dataFormats_->base(Variable::dZ, Process::kfin) * (i + 1) * pow(2, setup_->weightBinFraction()), -2); - temp_dz = temp_dz * setup_->dzTruncation(); - temp_dz = std::ceil(temp_dz); - dZBins_.push_back(temp_dz / setup_->dzTruncation()); - } - numWorkers_ = setup_->kfNumWorker(); - partialTrackWordBits_ = TTBV::S_ / 2; - } - - void ProducerKFout::produce(Event& iEvent, const EventSetup& iSetup) { - // empty KFout product - StreamsTrack accepted(setup_->numRegions() * setup_->tfpNumChannel()); - StreamsTrack lost(setup_->numRegions() * setup_->tfpNumChannel()); - // read in KF Product and produce KFout product - if (setup_->configurationSupported()) { - Handle handleStubs; - iEvent.getByToken(edGetTokenStubs_, handleStubs); - const StreamsStub& streamsStubs = *handleStubs.product(); - Handle handleTracks; - iEvent.getByToken(edGetTokenTracks_, handleTracks); - const StreamsTrack& streamsTracks = *handleTracks.product(); - - // Setup KFout track collection - TrackKFOutSAPtrCollection KFoutTracks; - - // Setup containers for track quality - float tempTQMVAPreSig = 0.0; - // Due to ap_fixed implementation in CMSSW this 10,5 must be specified at compile time, TODO make this a changeable parameter - std::vector> trackQuality_inputs = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; - - // calculate track quality and fill TTTracks - TTTracks ttTracks; - int nTracks(0); - for (const StreamTrack& stream : streamsTracks) - nTracks += accumulate(stream.begin(), stream.end(), 0, [](int sum, const FrameTrack& frame) { - return sum + (frame.first.isNonnull() ? 1 : 0); - }); - ttTracks.reserve(nTracks); - for (int iLink = 0; iLink < (int)streamsTracks.size(); iLink++) { - for (int iTrack = 0; iTrack < (int)streamsTracks[iLink].size(); iTrack++) { - const auto& track = streamsTracks[iLink].at(iTrack); - TrackKF inTrack(track, dataFormats_); - - double temp_z0 = inTrack.zT() - ((inTrack.cot() * setup_->chosenRofZ())); - // Correction to Phi calcuation depending if +ve/-ve phi sector - const double baseSectorCorr = inTrack.sectorPhi() ? -setup_->baseSector() : setup_->baseSector(); - double temp_phi0 = inTrack.phiT() - ((inTrack.inv2R()) * setup_->hybridChosenRofPhi()) + baseSectorCorr; - double temp_tanL = inTrack.cotGlobal(); - - TTBV hitPattern(0, setup_->numLayers()); - double tempchi2rphi = 0; - double tempchi2rz = 0; - int temp_nstub = 0; - int temp_ninterior = 0; - bool counter = false; - - vector stubs; - stubs.reserve(setup_->numLayers()); - for (int iStub = 0; iStub < setup_->numLayers(); iStub++) { - const auto& stub = streamsStubs[setup_->numLayers() * iLink + iStub].at(iTrack); - StubKF inStub(stub, dataFormats_, iStub); - if (stub.first.isNonnull()) - stubs.emplace_back(stub, dataFormats_, iStub); - - if (!stub.first.isNonnull()) { - if (counter) - temp_ninterior += 1; - continue; - } - - counter = true; - - hitPattern.set(iStub); - temp_nstub += 1; - double phiSquared = pow(inStub.phi(), 2); - double zSquared = pow(inStub.z(), 2); - - double tempv0 = dPhiBins_[(inStub.dPhi() / (dataFormats_->base(Variable::dPhi, Process::kfin) * - pow(2, setup_->weightBinFraction())))]; - double tempv1 = dZBins_[( - inStub.dZ() / (dataFormats_->base(Variable::dZ, Process::kfin) * pow(2, setup_->weightBinFraction())))]; - - double tempRphi = phiSquared * tempv0; - double tempRz = zSquared * tempv1; - - tempchi2rphi += tempRphi; - tempchi2rz += tempRz; - } // Iterate over track stubs - - // Create bit vectors for each output, including digitisation of chi2 - // TODO implement extraMVA, bendChi2, d0 - TTBV trackValid(1, TTTrack_TrackWord::TrackBitWidths::kValidSize, false); - TTBV extraMVA(0, TTTrack_TrackWord::TrackBitWidths::kMVAOtherSize, false); - TTBV bendChi2(0, TTTrack_TrackWord::TrackBitWidths::kBendChi2Size, false); - TTBV chi2rphi(digitise(TTTrack_TrackWord::chi2RPhiBins, tempchi2rphi, (double)setup_->kfoutchi2rphiConv()), - TTTrack_TrackWord::TrackBitWidths::kChi2RPhiSize, - false); - TTBV chi2rz(digitise(TTTrack_TrackWord::chi2RZBins, tempchi2rz, (double)setup_->kfoutchi2rzConv()), - TTTrack_TrackWord::TrackBitWidths::kChi2RZSize, - false); - TTBV d0(0, TTTrack_TrackWord::TrackBitWidths::kD0Size, false); - TTBV z0( - temp_z0, dataFormats_->base(Variable::zT, Process::kf), TTTrack_TrackWord::TrackBitWidths::kZ0Size, true); - TTBV tanL(temp_tanL, - dataFormats_->base(Variable::cot, Process::kf), - TTTrack_TrackWord::TrackBitWidths::kTanlSize, - true); - TTBV phi0(temp_phi0, - dataFormats_->base(Variable::phiT, Process::kf), - TTTrack_TrackWord::TrackBitWidths::kPhiSize, - true); - TTBV invR(-inTrack.inv2R(), - dataFormats_->base(Variable::inv2R, Process::kf), - TTTrack_TrackWord::TrackBitWidths::kRinvSize + 1, - true); - invR.resize(TTTrack_TrackWord::TrackBitWidths::kRinvSize); - - // conversion to tttrack to calculate bendchi2 - // temporary fix for MVA1 while bendchi2 not implemented - TTTrack temp_tttrack = inTrack.ttTrack(stubs); - double tempbendchi2 = temp_tttrack.chi2BendRed(); - - // Create input vector for BDT - trackQuality_inputs = { - (std::trunc(tanL.val() / tqTanlScale_)) / ap_fixed_rescale, - (std::trunc(z0.val() / tqZ0Scale_)) / ap_fixed_rescale, - digitise(TTTrack_TrackWord::bendChi2Bins, tempbendchi2, 1.), - temp_nstub, - temp_ninterior, - digitise(TTTrack_TrackWord::chi2RPhiBins, tempchi2rphi, (double)setup_->kfoutchi2rphiConv()), - digitise(TTTrack_TrackWord::chi2RZBins, tempchi2rz, (double)setup_->kfoutchi2rzConv())}; - - // Run BDT emulation and package output into 3 bits - // output needs sigmoid transformation applied - tempTQMVAPreSig = trackQualityModel_->runEmulatedTQ(trackQuality_inputs); - TTBV tqMVA(digitise(L1TrackQuality::getTqMVAPreSigBins(), tempTQMVAPreSig, 1.0), - TTTrack_TrackWord::TrackBitWidths::kMVAQualitySize, - false); - - // Build 32 bit partial tracks for outputting in 64 bit packets - // 12 + 3 + 7 + 3 + 6 - TTBV partialTrack3((d0 + bendChi2 + hitPattern + tqMVA + extraMVA), partialTrackWordBits_, false); - // 16 + 12 + 4 - TTBV partialTrack2((tanL + z0 + chi2rz), partialTrackWordBits_, false); - // 1 + 15 + 12 + 4 - TTBV partialTrack1((trackValid + invR + phi0 + chi2rphi), partialTrackWordBits_, false); - - int sortKey = (inTrack.sectorEta() < (int)(setup_->numSectorsEta() / 2)) ? 0 : 1; - int nonantId = iLink / setup_->kfNumWorker(); - // Set correct bit to valid for track valid - TrackKFOut temp_track(partialTrack1.set((partialTrackWordBits_ - 1)), - partialTrack2, - partialTrack3, - sortKey, - nonantId, - track, - iTrack, - iLink, - true); - KFoutTracks.push_back(std::make_shared(temp_track)); - - // add MVA to tttrack and add tttrack to collection - temp_tttrack.settrkMVA1(1. / (1. + exp(tempTQMVAPreSig))); - temp_tttrack.setTrackWordBits(); - ttTracks.emplace_back(temp_tttrack); - } // Iterate over Tracks - } // Iterate over Links - const OrphanHandle orphanHandleTTTracks = iEvent.emplace(edPutTokenTTTracks_, std::move(ttTracks)); - - // sort partial KFout tracks into 18 separate links (nonant idx * eta idx) with tttrack ref info - // 0th index order: [nonant 0 + negative eta, nonant 0 + positive eta, nonant 1 + negative eta, ...] - struct kfoTrack_info { - TTBV partialBits; - TTTrackRef trackRef; - }; - vector> sortedPartialTracks(setup_->numRegions() * setup_->tfpNumChannel(), - vector(0)); - for (int i = 0; i < (int)KFoutTracks.size(); i++) { - auto& kfoTrack = KFoutTracks.at(i); - if (kfoTrack->dataValid()) { - sortedPartialTracks[kfoTrack->nonantId() * setup_->tfpNumChannel() + kfoTrack->sortKey()].push_back( - {kfoTrack->PartialTrack1(), TTTrackRef(orphanHandleTTTracks, i)}); - sortedPartialTracks[kfoTrack->nonantId() * setup_->tfpNumChannel() + kfoTrack->sortKey()].push_back( - {kfoTrack->PartialTrack2(), TTTrackRef(orphanHandleTTTracks, i)}); - sortedPartialTracks[kfoTrack->nonantId() * setup_->tfpNumChannel() + kfoTrack->sortKey()].push_back( - {kfoTrack->PartialTrack3(), TTTrackRef(orphanHandleTTTracks, i)}); - } - } - // fill remaining tracks allowed on each link (setup_->numFramesIO()) with null info - kfoTrack_info nullTrack_info; - for (int i = 0; i < (int)sortedPartialTracks.size(); i++) { - // will not fill if any additional tracks if already above limit - while ((int)sortedPartialTracks.at(i).size() < setup_->numFramesIO() * 2) - sortedPartialTracks.at(i).push_back(nullTrack_info); - } - - // combine sorted partial tracks into proper format: - // < TTTrackRef A, first 64 A bits > - // < TTTrackRef B, last 32 A bits + first 32 B bits > - // < TTTrackRef null, last 64 B bits > - // ... repeat for next tracks - const TTBV nullPartialBits(0, partialTrackWordBits_, false); - const TTTrackRef nullTrackRef; - int partialFactor = TTBV::S_ / partialTrackWordBits_; //how many partial track words to combine in an output - for (int iLink = 0; iLink < (int)sortedPartialTracks.size(); iLink++) { - for (int iTrack = 0; iTrack < (int)sortedPartialTracks[iLink].size(); iTrack += partialFactor) { - // if a partial track has no pair, pair it with null partial track - if (iTrack + 1 == (int)sortedPartialTracks[iLink].size()) - sortedPartialTracks[iLink].push_back({nullPartialBits, nullTrackRef}); - // keep TTTrackRef null every third (96 bits / 32 partial bits) output packet - TTTrackRef fillTrackRef; - if ((iTrack / partialFactor + 1) % (TTTrack_TrackWord::kTrackWordSize / partialTrackWordBits_) != 0) - fillTrackRef = sortedPartialTracks[iLink][iTrack + 1].trackRef; - - // if there are too many output packets, truncate and put remaining outputs in lost collection - if (iTrack / partialFactor < setup_->numFramesIO()) - accepted[iLink].emplace_back( - std::make_pair(fillTrackRef, - (sortedPartialTracks[iLink][iTrack].partialBits.slice(partialTrackWordBits_) + - sortedPartialTracks[iLink][iTrack + 1].partialBits.slice(partialTrackWordBits_)) - .bs())); - else - lost[iLink].emplace_back( - std::make_pair(fillTrackRef, - (sortedPartialTracks[iLink][iTrack].partialBits.slice(partialTrackWordBits_) + - sortedPartialTracks[iLink][iTrack + 1].partialBits.slice(partialTrackWordBits_)) - .bs())); - } - } - } // Config Supported - - // store products - iEvent.emplace(edPutTokenAccepted_, std::move(accepted)); - iEvent.emplace(edPutTokenLost_, std::move(lost)); - } -} // namespace trklet - -DEFINE_FWK_MODULE(trklet::ProducerKFout); diff --git a/L1Trigger/TrackFindingTracklet/plugins/ProducerTBout.cc b/L1Trigger/TrackFindingTracklet/plugins/ProducerTBout.cc deleted file mode 100644 index 981ed2ba75c6b..0000000000000 --- a/L1Trigger/TrackFindingTracklet/plugins/ProducerTBout.cc +++ /dev/null @@ -1,192 +0,0 @@ -#include "FWCore/Framework/interface/stream/EDProducer.h" -#include "FWCore/Framework/interface/Run.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Utilities/interface/EDGetToken.h" -#include "FWCore/Utilities/interface/EDPutToken.h" -#include "FWCore/Utilities/interface/ESGetToken.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "DataFormats/Common/interface/Handle.h" - -#include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" -#include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h" - -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace edm; -using namespace trackerTFP; -using namespace tt; - -namespace trklet { - - /*! \class trklet::ProducerTBout - * \brief Transforms TTTracks and Streams from Tracklet pattern reco. into StreamsTrack - * by adding to the digitised track stream a reference to the corresponding TTTrack. - * (Could not be done in previous L1TrackFPGAProducer, as single EDProducer can't - * produce output containing both an EDProduct and refs to that product). - * Writes Tracks & stubs rejected/kept after truncation to separate StreamsTrack & StreamsStub branches. - * \author Thomas Schuh - * \date 2021, Oct - */ - class ProducerTBout : public stream::EDProducer<> { - public: - explicit ProducerTBout(const ParameterSet&); - ~ProducerTBout() override {} - - private: - void beginRun(const Run&, const EventSetup&) override; - void produce(Event&, const EventSetup&) override; - virtual void endJob() {} - - // ED input token of TTTracks - EDGetTokenT edGetTokenTTTracks_; - // ED input token of Tracklet tracks - EDGetTokenT edGetTokenTracks_; - // ED input token of Tracklet Stubs - EDGetTokenT edGetTokenStubs_; - // ED output token for stubs - EDPutTokenT edPutTokenAcceptedStubs_; - EDPutTokenT edPutTokenLostStubs_; - // ED output token for tracks - EDPutTokenT edPutTokenAcceptedTracks_; - EDPutTokenT edPutTokenLostTracks_; - // Setup token - ESGetToken esGetTokenSetup_; - // DataFormats token - ESGetToken esGetTokenDataFormats_; - // ChannelAssignment token - ESGetToken esGetTokenChannelAssignment_; - // configuration - ParameterSet iConfig_; - // helper class to store configurations - const Setup* setup_ = nullptr; - // helper class to extract structured data from tt::Frames - const DataFormats* dataFormats_ = nullptr; - // helper class to assign tracks to channel - ChannelAssignment* channelAssignment_ = nullptr; - // - bool enableTruncation_; - }; - - ProducerTBout::ProducerTBout(const ParameterSet& iConfig) : iConfig_(iConfig) { - const InputTag& inputTag = iConfig.getParameter("InputTag"); - const string& branchAcceptedStubs = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchAcceptedTracks = iConfig.getParameter("BranchAcceptedTracks"); - const string& branchLostStubs = iConfig.getParameter("BranchLostStubs"); - const string& branchLostTracks = iConfig.getParameter("BranchLostTracks"); - // book in- and output ED products - edGetTokenTTTracks_ = consumes(inputTag); - edGetTokenTracks_ = consumes(inputTag); - edGetTokenStubs_ = consumes(inputTag); - edPutTokenAcceptedStubs_ = produces(branchAcceptedStubs); - edPutTokenAcceptedTracks_ = produces(branchAcceptedTracks); - edPutTokenLostStubs_ = produces(branchLostStubs); - edPutTokenLostTracks_ = produces(branchLostTracks); - // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); - esGetTokenChannelAssignment_ = esConsumes(); - // - enableTruncation_ = iConfig.getParameter("EnableTruncation"); - } - - void ProducerTBout::beginRun(const Run& iRun, const EventSetup& iSetup) { - // helper class to store configurations - setup_ = &iSetup.getData(esGetTokenSetup_); - if (!setup_->configurationSupported()) - return; - // check process history if desired - if (iConfig_.getParameter("CheckHistory")) - setup_->checkHistory(iRun.processHistory()); - // helper class to extract structured data from tt::Frames - dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); - // helper class to assign tracks to channel - channelAssignment_ = const_cast(&iSetup.getData(esGetTokenChannelAssignment_)); - } - - void ProducerTBout::produce(Event& iEvent, const EventSetup& iSetup) { - const int numStreamsTracks = setup_->numRegions() * channelAssignment_->numChannelsTrack(); - const int numStreamsStubs = setup_->numRegions() * channelAssignment_->numChannelsStub(); - // empty KFin products - StreamsStub streamAcceptedStubs(numStreamsStubs); - StreamsTrack streamAcceptedTracks(numStreamsTracks); - StreamsStub streamLostStubs(numStreamsStubs); - StreamsTrack streamLostTracks(numStreamsTracks); - // read in hybrid track finding product and produce KFin product - if (setup_->configurationSupported()) { - // create and structure TTrackRefs in h/w channel - vector> ttTrackRefs(numStreamsTracks); - Handle handleTTTracks; - iEvent.getByToken(edGetTokenTTTracks_, handleTTTracks); - int channelId(-1); - for (int i = 0; i < (int)handleTTTracks->size(); i++) { - const TTTrackRef ttTrackRef(handleTTTracks, i); - const int channelId = channelAssignment_->channelId(ttTrackRef); - ttTrackRefs[channelId].push_back(ttTrackRef); - } - // get and trunacte tracks - Handle handleTracks; - iEvent.getByToken(edGetTokenTracks_, handleTracks); - channelId = 0; - for (const Stream& streamTrack : *handleTracks) { - const int nTracks = accumulate( - streamTrack.begin(), streamTrack.end(), 0, [](int sum, const Frame& f) { return sum + (f.any() ? 1 : 0); }); - StreamTrack& accepted = streamAcceptedTracks[channelId]; - StreamTrack& lost = streamLostTracks[channelId]; - auto limit = streamTrack.end(); - if (enableTruncation_ && (int)streamTrack.size() > setup_->numFrames()) - limit = next(streamTrack.begin(), setup_->numFrames()); - accepted.reserve(distance(streamTrack.begin(), limit)); - lost.reserve(distance(limit, streamTrack.end())); - int nFrame(0); - const deque& ttTracks = ttTrackRefs[channelId++]; - if ((int)ttTracks.size() != nTracks) { - cms::Exception exception("LogicError."); - const int region = channelId / channelAssignment_->numChannelsTrack(); - const int channel = channelId % channelAssignment_->numChannelsTrack(); - exception << "Region " << region << " output channel " << channel << " has " << nTracks - << " tracks found but created " << ttTracks.size() << " TTTracks."; - exception.addContext("trklet::ProducerTBout::produce"); - throw exception; - } - auto toFrameTrack = [&nFrame, &ttTracks](const Frame& frame) { - if (frame.any()) - return FrameTrack(ttTracks[nFrame++], frame); - return FrameTrack(); - }; - transform(streamTrack.begin(), limit, back_inserter(accepted), toFrameTrack); - transform(limit, streamTrack.end(), back_inserter(lost), toFrameTrack); - } - // get and trunacte stubs - Handle handleStubs; - iEvent.getByToken(edGetTokenStubs_, handleStubs); - const StreamsStub& streamsStub = *handleStubs; - // reserve output ed products - channelId = 0; - for (const StreamStub& streamStub : streamsStub) { - auto limit = streamStub.end(); - if (enableTruncation_ && (int)streamStub.size() > setup_->numFrames()) - limit = next(streamStub.begin(), setup_->numFrames()); - streamAcceptedStubs[channelId] = StreamStub(streamStub.begin(), limit); - streamLostStubs[channelId++] = StreamStub(limit, streamStub.end()); - } - } - // store products - iEvent.emplace(edPutTokenAcceptedStubs_, std::move(streamAcceptedStubs)); - iEvent.emplace(edPutTokenAcceptedTracks_, std::move(streamAcceptedTracks)); - iEvent.emplace(edPutTokenLostStubs_, std::move(streamLostStubs)); - iEvent.emplace(edPutTokenLostTracks_, std::move(streamLostTracks)); - } - -} // namespace trklet - -DEFINE_FWK_MODULE(trklet::ProducerTBout); diff --git a/L1Trigger/TrackFindingTracklet/plugins/ProducerTFP.cc b/L1Trigger/TrackFindingTracklet/plugins/ProducerTFP.cc new file mode 100644 index 0000000000000..b83bd449638db --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/plugins/ProducerTFP.cc @@ -0,0 +1,104 @@ +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Utilities/interface/EDPutToken.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/Common/interface/OrphanHandle.h" + +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackFindingTracklet/interface/DataFormats.h" +#include "L1Trigger/TrackerTFP/interface/TrackQuality.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackFindingProcessor.h" + +#include +#include +#include +#include + +namespace trklet { + + /*! \class trklet::ProducerTFP + * \brief L1TrackTrigger final TFP output formatter + * \author Thomas Schuh + * \date 2023, June + */ + class ProducerTFP : public edm::stream::EDProducer<> { + public: + explicit ProducerTFP(const edm::ParameterSet&); + ~ProducerTFP() override {} + + private: + void produce(edm::Event&, const edm::EventSetup&) override; + // ED input token of stubs and tracks + edm::EDGetTokenT edGetTokenTracks_; + edm::EDGetTokenT edGetTokenTracksAdd_; + edm::EDGetTokenT edGetTokenStubs_; + // ED output token for accepted stubs and tracks + edm::EDPutTokenT edPutTokenTTTracks_; + edm::EDPutTokenT edPutTokenTracks_; + // Setup token + edm::ESGetToken esGetTokenSetup_; + // DataFormats token + edm::ESGetToken esGetTokenDataFormats_; + // TrackQuality token + edm::ESGetToken esGetTokenTrackQuality_; + }; + + ProducerTFP::ProducerTFP(const edm::ParameterSet& iConfig) { + const std::string& labelTracks = iConfig.getParameter("InputLabelTFP"); + const std::string& labelStubs = iConfig.getParameter("InputLabelTQ"); + const std::string& branchTracks = iConfig.getParameter("BranchTracks"); + const std::string& branchTTTracks = iConfig.getParameter("BranchTTTracks"); + const std::string& branchStubs = iConfig.getParameter("BranchStubs"); + // book in- and output ED products + edGetTokenTracks_ = consumes(edm::InputTag(labelTracks, branchTracks)); + edGetTokenTracksAdd_ = consumes(edm::InputTag(labelTracks, branchTracks)); + edGetTokenStubs_ = consumes(edm::InputTag(labelStubs, branchStubs)); + edPutTokenTTTracks_ = produces(branchTTTracks); + edPutTokenTracks_ = produces(branchTracks); + // book ES products + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + esGetTokenTrackQuality_ = esConsumes(); + } + + void ProducerTFP::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + // helper class to store configurations + const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_); + // helper class to extract structured data from tt::Frames + const DataFormats* dataFormats = &iSetup.getData(esGetTokenDataFormats_); + // helper class to determine track quality + const trackerTFP::TrackQuality* trackQuality = &iSetup.getData(esGetTokenTrackQuality_); + // empty TFP products + tt::TTTracks ttTracks; + tt::StreamsTrack streamsTrack(setup->numRegions() * setup->tfpNumChannel()); + // read in TQ Products + const tt::StreamsTrack& tracks = iEvent.get(edGetTokenTracks_); + const tt::Streams& tracksAdd = iEvent.get(edGetTokenTracksAdd_); + const tt::StreamsStub& stubs = iEvent.get(edGetTokenStubs_); + // produce TTTracks + TrackFindingProcessor tfp(setup, dataFormats, trackQuality); + tfp.produce(tracks, tracksAdd, stubs, ttTracks, streamsTrack); + // put TTTRacks and produce TTTRackRefs + const int nTrks = ttTracks.size(); + const edm::OrphanHandle oh = iEvent.emplace(edPutTokenTTTracks_, std::move(ttTracks)); + std::vector ttTrackRefs; + ttTrackRefs.reserve(nTrks); + for (int iTrk = 0; iTrk < nTrks; iTrk++) + ttTrackRefs.emplace_back(oh, iTrk); + // replace old TTTrackRefs in streamsTrack with new TTTrackRefs + tfp.produce(ttTrackRefs, streamsTrack); + // put StreamsTrack + iEvent.emplace(edPutTokenTracks_, std::move(streamsTrack)); + } + +} // namespace trklet + +DEFINE_FWK_MODULE(trklet::ProducerTFP); diff --git a/L1Trigger/TrackFindingTracklet/plugins/ProducerTM.cc b/L1Trigger/TrackFindingTracklet/plugins/ProducerTM.cc new file mode 100644 index 0000000000000..edf53252a3d43 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/plugins/ProducerTM.cc @@ -0,0 +1,104 @@ +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Utilities/interface/EDPutToken.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "DataFormats/Common/interface/Handle.h" + +#include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h" +#include "L1Trigger/TrackFindingTracklet/interface/DataFormats.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackMultiplexer.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" + +#include +#include +#include +#include +#include +#include + +namespace trklet { + + /*! \class trklet::ProducerTM + * \brief Transforms format of Track Builder into that expected by DR input and muxes all channels to 1. + Since DR keeps first tracks the mux ordering (currently from low seed id to high seed id) is important. + * \author Thomas Schuh + * \date 2023, Jan + */ + class ProducerTM : public edm::stream::EDProducer<> { + public: + explicit ProducerTM(const edm::ParameterSet&); + ~ProducerTM() override {} + + private: + void produce(edm::Event&, const edm::EventSetup&) override; + + // ED input token of Tracks + edm::EDGetTokenT edGetTokenTracks_; + // ED input token of Stubs + edm::EDGetTokenT edGetTokenStubs_; + // ED output token for stubs + edm::EDPutTokenT edPutTokenStubs_; + // ED output token for tracks + edm::EDPutTokenT edPutTokenTracks_; + // Setup token + edm::ESGetToken esGetTokenSetup_; + // DataFormats token + edm::ESGetToken esGetTokenDataFormats_; + // ChannelAssignment token + edm::ESGetToken esGetTokenChannelAssignment_; + // helper class to store tracklet configurations + trklet::Settings settings_; + }; + + ProducerTM::ProducerTM(const edm::ParameterSet& iConfig) { + const std::string& label = iConfig.getParameter("InputLabelTM"); + const std::string& branchStubs = iConfig.getParameter("BranchStubs"); + const std::string& branchTracks = iConfig.getParameter("BranchTracks"); + // book in- and output ED products + edGetTokenTracks_ = consumes(edm::InputTag(label, branchTracks)); + edGetTokenStubs_ = consumes(edm::InputTag(label, branchStubs)); + edPutTokenStubs_ = produces(branchStubs); + edPutTokenTracks_ = produces(branchTracks); + // book ES products + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + esGetTokenChannelAssignment_ = esConsumes(); + } + + void ProducerTM::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + // helper class to store configurations + const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_); + // helper class to extract structured data from tt::Frames + const DataFormats* dataFormats = &iSetup.getData(esGetTokenDataFormats_); + // helper class to assign tracks to channel + const ChannelAssignment* channelAssignment = &iSetup.getData(esGetTokenChannelAssignment_); + // empty TM products + tt::StreamsStub streamsStub(setup->numRegions() * channelAssignment->tmNumLayers()); + tt::StreamsTrack streamsTrack(setup->numRegions()); + // read in TBout Product and produce TM product + const tt::StreamsStub& stubs = iEvent.get(edGetTokenStubs_); + const tt::StreamsTrack& tracks = iEvent.get(edGetTokenTracks_); + for (int region = 0; region < setup->numRegions(); region++) { + // object to reformat tracks from tracklet fromat to TMTT format in a processing region + TrackMultiplexer tm(setup, dataFormats, channelAssignment, &settings_, region); + // read in and organize input tracks and stubs + tm.consume(tracks, stubs); + // fill output products + tm.produce(streamsTrack, streamsStub); + } + // store products + iEvent.emplace(edPutTokenTracks_, std::move(streamsTrack)); + iEvent.emplace(edPutTokenStubs_, std::move(streamsStub)); + } + +} // namespace trklet + +DEFINE_FWK_MODULE(trklet::ProducerTM); diff --git a/L1Trigger/TrackFindingTracklet/python/Analyzer_cff.py b/L1Trigger/TrackFindingTracklet/python/Analyzer_cff.py index ddc1b5377044a..e7056d4ce6189 100644 --- a/L1Trigger/TrackFindingTracklet/python/Analyzer_cff.py +++ b/L1Trigger/TrackFindingTracklet/python/Analyzer_cff.py @@ -1,12 +1,15 @@ +# EDAnalyzer to analyze hybrid track reconstruction emulation chain + import FWCore.ParameterSet.Config as cms from L1Trigger.TrackFindingTracklet.Analyzer_cfi import TrackFindingTrackletAnalyzer_params from L1Trigger.TrackFindingTracklet.Producer_cfi import TrackFindingTrackletProducer_params +from L1Trigger.TrackFindingTracklet.ChannelAssignment_cff import * +from L1Trigger.TrackFindingTracklet.DataFormats_cff import * -TrackFindingTrackletAnalyzerTBout = cms.EDAnalyzer( 'trklet::AnalyzerTBout', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) -TrackFindingTrackletAnalyzerTracklet = cms.EDAnalyzer( 'trklet::AnalyzerTracklet', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) -TrackFindingTrackletAnalyzerDRin = cms.EDAnalyzer( 'trklet::AnalyzerDRin', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) -TrackFindingTrackletAnalyzerDR = cms.EDAnalyzer( 'trklet::AnalyzerDR', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) -TrackFindingTrackletAnalyzerKFin = cms.EDAnalyzer( 'trklet::AnalyzerKFin', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) -TrackFindingTrackletAnalyzerKF = cms.EDAnalyzer( 'trackerTFP::AnalyzerKF', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) -TrackFindingTrackletAnalyzerKFout = cms.EDAnalyzer( 'trklet::AnalyzerKFout', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) +AnalyzerTracklet = cms.EDAnalyzer( 'trklet::AnalyzerTracklet', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) +AnalyzerTM = cms.EDAnalyzer( 'trklet::AnalyzerTM', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) +AnalyzerDR = cms.EDAnalyzer( 'trklet::AnalyzerDR', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) +AnalyzerKF = cms.EDAnalyzer( 'trklet::AnalyzerKF', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) +AnalyzerTQ = cms.EDAnalyzer( 'trackerTFP::AnalyzerTQ', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) +AnalyzerTFP = cms.EDAnalyzer( 'trackerTFP::AnalyzerTFP', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) diff --git a/L1Trigger/TrackFindingTracklet/python/Analyzer_cfi.py b/L1Trigger/TrackFindingTracklet/python/Analyzer_cfi.py index af2a269ca3793..8a5ae3a29c8be 100644 --- a/L1Trigger/TrackFindingTracklet/python/Analyzer_cfi.py +++ b/L1Trigger/TrackFindingTracklet/python/Analyzer_cfi.py @@ -1,4 +1,5 @@ -# ParameterSet used by AnalyzerKFin and AnalyzerTracklet +# configuration for hybrid track reconstruction chain analyzer + import FWCore.ParameterSet.Config as cms TrackFindingTrackletAnalyzer_params = cms.PSet ( @@ -6,6 +7,12 @@ UseMCTruth = cms.bool( True ), # enables analyze of TPs InputTagReconstructable = cms.InputTag("StubAssociator", "Reconstructable"), # InputTagSelection = cms.InputTag("StubAssociator", "UseForAlgEff"), # + InputTag = cms.InputTag( "l1tTTTracksFromTrackletEmulation", "Level1TTTracks"), # + OutputLabelTM = cms.string ( "ProducerTM" ), # + OutputLabelDR = cms.string ( "ProducerDR" ), # + OutputLabelKF = cms.string ( "ProducerKF" ), # + OutputLabelTQ = cms.string ( "ProducerTQ" ), # + OutputLabelTFP = cms.string ( "ProducerTFP" ), # ) diff --git a/L1Trigger/TrackFindingTracklet/python/ChannelAssignment_cff.py b/L1Trigger/TrackFindingTracklet/python/ChannelAssignment_cff.py index adb369d78606f..46df2cd3cf444 100644 --- a/L1Trigger/TrackFindingTracklet/python/ChannelAssignment_cff.py +++ b/L1Trigger/TrackFindingTracklet/python/ChannelAssignment_cff.py @@ -1,3 +1,5 @@ +# ESProducer providing the algorithm to assign tracklet tracks and stubs to output channel based on their Pt or seed type as well as DTC stubs to input channel + import FWCore.ParameterSet.Config as cms from L1Trigger.TrackFindingTracklet.ChannelAssignment_cfi import ChannelAssignment_params diff --git a/L1Trigger/TrackFindingTracklet/python/ChannelAssignment_cfi.py b/L1Trigger/TrackFindingTracklet/python/ChannelAssignment_cfi.py index 64bee96e8f6bf..9396453ef60ec 100644 --- a/L1Trigger/TrackFindingTracklet/python/ChannelAssignment_cfi.py +++ b/L1Trigger/TrackFindingTracklet/python/ChannelAssignment_cfi.py @@ -1,21 +1,20 @@ -# defines PSet to assign tracklet tracks and stubs to output channel based on their Pt or seed type as well as DTC stubs to input channel +# configuration for ChannelAssignment + import FWCore.ParameterSet.Config as cms ChannelAssignment_params = cms.PSet ( - # DRin parameter - DRin = cms.PSet ( - WidthLayerId = cms.int32( 4 ), # number of bits used to represent layer id [barrel: 0-5, discs: 6-10] - WidthStubId = cms.int32( 10 ), # number of bits used to represent stub id for projected stubs - WidthSeedStubId = cms.int32( 7 ), # number of bits used to represent stub id for seed stubs - WidthPSTilt = cms.int32( 1 ), # number of bits used to distinguish between tilted and untilded barrel modules or 2S and PS endcap modules - DepthMemory = cms.int32( 32 ), # depth of fifos within systolic array - PtBoundaries = cms.vdouble( 3.0, 5.0, 8.0, 12.0, 24.0 ) # positive pt Boundaries in GeV (symmetric negatives are assumed), first boundary is pt cut, last boundary is infinity, defining pt bins used by DR + # TM parameter + TM = cms.PSet ( + MuxOrder = cms.vstring( "L1L2", "L2L3", "L1D1", "D1D2", "D3D4", "L2D1", "L3L4", "L5L6" ), + NumLayers = cms.int32( 11 ), # number of layers per track + WidthStubId = cms.int32( 10 ), # number of bits used to represent stub id for projected stubs + WidthCot = cms.int32( 14 ) ), # DR parameter DR = cms.PSet ( - NumComparisonModules = cms.int32( 16 ), # number of comparison modules used in each DR node + NumComparisonModules = cms.int32( 32 ), # number of comparison modules used in each DR node MinIdenticalStubs = cms.int32( 3 ) # min number of shared stubs to identify duplicates ), diff --git a/L1Trigger/TrackFindingTracklet/python/Customize_cff.py b/L1Trigger/TrackFindingTracklet/python/Customize_cff.py index 6124b40f047e8..bbef580ce9625 100644 --- a/L1Trigger/TrackFindingTracklet/python/Customize_cff.py +++ b/L1Trigger/TrackFindingTracklet/python/Customize_cff.py @@ -1,13 +1,10 @@ -import FWCore.ParameterSet.Config as cms +# functions to alter configurations -# configures track finding s/w to use KF emulator instead of KF simulator -def newKFConfig(process): - process.l1tTTTracksFromTrackletEmulation.Fakefit = True +import FWCore.ParameterSet.Config as cms # configures track finding s/w to behave as track finding f/w def fwConfig(process): - newKFConfig(process) - process.TrackTriggerSetup.Firmware.FreqBE = 240 # Frequency of DTC & KF (determines truncation) + process.l1tTTTracksFromTrackletEmulation.Fakefit = True process.l1tTTTracksFromTrackletEmulation.RemovalType = "" process.l1tTTTracksFromTrackletEmulation.DoMultipleMatches = False process.l1tTTTracksFromTrackletEmulation.StoreTrackBuilderOutput = True @@ -15,6 +12,7 @@ def fwConfig(process): # configures track finding s/w to behave as a subchain of processing steps def reducedConfig(process): fwConfig(process) + process.TrackTriggerSetup.Firmware.FreqBEHigh = 240 # Frequency of DTC & KF (determines truncation) process.TrackTriggerSetup.KalmanFilter.NumWorker = 1 process.ChannelAssignment.SeedTypes = cms.vstring( "L1L2" ) process.ChannelAssignment.SeedTypesSeedLayers = cms.PSet( L1L2 = cms.vint32( 1, 2 ) ) @@ -30,4 +28,80 @@ def reducedConfig(process): # configures pure tracklet algorithm (as opposed to Hybrid algorithm) def trackletConfig(process): - process.l1tTTTracksFromTrackletEmulation.fitPatternFile = cms.FileInPath('L1Trigger/TrackFindingTracklet/data/fitpattern.txt') + process.l1tTTTracksFromTrackletEmulation.fitPatternFile = cms.FileInPath('L1Trigger/TrackFindingTracklet/data/fitpattern.txt') + +# configures KF simulation in emulation chain +def oldKFConfig(process): + #===== Use HYBRID TRACKING (Tracklet pattern reco + TMTT KF -- requires tracklet C++ too) ===== + process.ProducerKF.Hybrid = True + # Emulate dead/inefficient modules using the StubKiller code, with stubs killed according to the scenarios of the Stress Test group. + # (0=Don't kill any stubs; 1-5 = Scenarios described in StubKiller.cc) + process.ProducerKF.DeadModuleOpts.KillScenario = 0 + # Modify TMTT tracking to try to recover tracking efficiency in presence of dead modules. (Does nothing if KillScenario = 0). + process.ProducerKF.DeadModuleOpts.KillRecover = False + # Min track Pt that Hough Transform must find. Also used by StubCuts.KillLowPtStubs and by EtaPhiSectors.UseStubPhi. + process.ProducerKF.HTArraySpecRphi.HoughMinPt = 2. + # Optionally skip track digitisation if done internally inside fitting code. + process.ProducerKF.TrackDigi.KF_skipTrackDigi = True + # Digitize stub coords? If not, use floating point coords. + process.ProducerKF.StubDigitize.EnableDigitize = False + # Use an FPGA-friendly approximation to determine track angle dphi from bend in GP? + process.ProducerKF.GeometricProc.UseApproxB = True + # Gradient term of linear equation for approximating B + process.ProducerKF.GeometricProc.BApprox_gradient = 0.886454 + # Intercept term of linear equation for approximating B + process.ProducerKF.GeometricProc.BApprox_intercept = 0.504148 + # Divisions of Tracker at GP. + process.ProducerKF.PhiSectors.NumPhiSectors = 9 + # Divisions of Tracker at DTC + process.ProducerKF.PhiSectors.NumPhiNonants = 9 + # Use phi of track at this radius for assignment of stubs to phi sectors & also for one of the axes of the r-phi HT. If ChosenRofPhi=0, then use track phi0. - Should be an integer multiple of the stub r digitisation granularity. + process.ProducerKF.PhiSectors.ChosenRofPhi = 55. + # Eta boundaries for 16 eta regions + process.ProducerKF.EtaSectors.EtaRegions = [-2.4, -2.08, -1.68, -1.26, -0.90, -0.62, -0.41, -0.20, 0.0, 0.20, 0.41, 0.62, 0.90, 1.26, 1.68, 2.08, 2.4] + # Use z of track at this radius for assignment of tracks to eta sectors & also for one of the axes of the r-z HT. Do not set to zero! + process.ProducerKF.EtaSectors.ChosenRofZ = 50.0 + # Fit will reject fitted tracks unless it can assign at least this number of stubs to them. + process.ProducerKF.TrackFitSettings.KalmanMinNumStubs = 4 + # Fit will attempt to add up to this nummber of stubs to each fitted tracks, but won't bother adding more. + process.ProducerKF.TrackFitSettings.KalmanMaxNumStubs = 6 + # Allow the KF to skip this many layers in total per track. + process.ProducerKF.TrackFitSettings.KalmanMaxSkipLayersHard = 1 + # For HT tracks with few stubs + process.ProducerKF.TrackFitSettings.KalmanMaxSkipLayersEasy = 2 + # Max stubs an HT track can have to be "easy". + process.ProducerKF.TrackFitSettings.KalmanMaxStubsEasy = 10 + # KF will consider at most this #stubs per layer to save time. + process.ProducerKF.TrackFitSettings.KalmanMaxStubsPerLayer = 4 + # Multiple scattering term - inflate hit phi errors by this divided by Pt (0.00075 gives best helix resolution & 0.00450 gives best chi2 distribution). + process.ProducerKF.TrackFitSettings.KalmanMultiScattTerm = 0.00075 + # Scale down chi2 in r-phi plane by this factor to improve electron performance (should be power of 2) + process.ProducerKF.TrackFitSettings.KalmanChi2RphiScale = 8 + # Disable "maybe layer" to match with firmware + process.ProducerKF.TrackFitSettings.KFUseMaybeLayers = True + # Remove requirement of at least 2 PS layers per track. + process.ProducerKF.TrackFitSettings.KalmanRemove2PScut = True + #--- Cuts applied to KF states as a function of the last KF tracker layer they had a stub in. + # (If "4" or "5" in name, cut only applies to 4 or 5 param helix fit). + process.ProducerKF.TrackFitSettings.KFLayerVsPtToler = [999., 999., 0.1, 0.1, 0.05, 0.05, 0.05] + # d0 cut only applied to 5 param helix fit. + process.ProducerKF.TrackFitSettings.KFLayerVsD0Cut5 = [999., 999., 999., 10., 10., 10., 10.] + process.ProducerKF.TrackFitSettings.KFLayerVsZ0Cut5 = [999., 999., 25.5, 25.5, 25.5, 25.5, 25.5] + process.ProducerKF.TrackFitSettings.KFLayerVsZ0Cut4 = [999., 999., 15., 15., 15., 15., 15.] + # Chi2 cuts should be retuned if KalmanMultiScattTerm value changed. + process.ProducerKF.TrackFitSettings.KFLayerVsChiSq5 = [999., 999., 10., 30., 80., 120., 160.] + process.ProducerKF.TrackFitSettings.KFLayerVsChiSq4 = [999., 999., 10., 30., 80., 120., 160.] + # For 5-param helix fits, calculate also beam-constrained helix params after fit is complete, & use them for duplicate removal if DupTrkAlgFit=1. + process.ProducerKF.TrackFitSettings.KalmanAddBeamConstr = False + # Use approx calc to account for non-radial endcap 2S modules corresponding to current FW, with no special treatment for tilted modules. + process.ProducerKF.TrackFitSettings.KalmanHOfw = False + # Treat z uncertainty in tilted barrel modules correctly. + process.ProducerKF.TrackFitSettings.KalmanHOtilted = True + # Projection from (r,phi) to (z,phi) for endcap 2S modules. (0=disable correction, 1=correct with offset, 2=correct with non-diagonal stub covariance matrix). -- Option 1 is easier in FPGA, but only works if fit adds PS stubs before 2S ones. + process.ProducerKF.TrackFitSettings.KalmanHOprojZcorr = 1 + # Alpha correction for non-radial 2S endcap strips. (0=disable correction, 1=correct with offset, 2=correct with non-diagonal stub covariance matrix). -- Option 1 is easier in FPGA, but only works if fit adds PS stubs before 2S ones. + process.ProducerKF.TrackFitSettings.KalmanHOalpha = 0 + # Higher order circle explansion terms for low Pt. + process.ProducerKF.TrackFitSettings.KalmanHOhelixExp = True + # Larger number has more debug printout. "1" is useful for understanding why tracks are lost, best combined with TrackFitCheat=True. + process.ProducerKF.TrackFitSettings.KalmanDebugLevel = 0 diff --git a/L1Trigger/TrackFindingTracklet/python/DataFormats_cff.py b/L1Trigger/TrackFindingTracklet/python/DataFormats_cff.py new file mode 100644 index 0000000000000..86ef954a1d6bb --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/python/DataFormats_cff.py @@ -0,0 +1,5 @@ +# ESProducer to provide and calculate and provide dataformats used by Hybrid emulator + +import FWCore.ParameterSet.Config as cms + +HybridDataFormats = cms.ESProducer("trklet::ProducerDataFormats") diff --git a/L1Trigger/TrackFindingTracklet/python/Demonstrator_cff.py b/L1Trigger/TrackFindingTracklet/python/Demonstrator_cff.py index 4c01ad1e086a2..d14422e2ac499 100644 --- a/L1Trigger/TrackFindingTracklet/python/Demonstrator_cff.py +++ b/L1Trigger/TrackFindingTracklet/python/Demonstrator_cff.py @@ -1,3 +1,6 @@ +# ESProducer providing the algorithm to run input data through modelsim and to compares results with expected output data +# and EDAnalyzer running the ESProduct produced by above ESProducer + import FWCore.ParameterSet.Config as cms from L1Trigger.TrackFindingTracklet.Demonstrator_cfi import TrackTriggerDemonstrator_params diff --git a/L1Trigger/TrackFindingTracklet/python/Demonstrator_cfi.py b/L1Trigger/TrackFindingTracklet/python/Demonstrator_cfi.py index 8331a613b1813..1f02bb9d1e762 100644 --- a/L1Trigger/TrackFindingTracklet/python/Demonstrator_cfi.py +++ b/L1Trigger/TrackFindingTracklet/python/Demonstrator_cfi.py @@ -1,11 +1,18 @@ # configuration of Demonstrator. This is used to compare FW with SW for the subset fo the chain between LabelIn & LabelOut. FW must be wrapped by EMP & compiled with IPBB. import FWCore.ParameterSet.Config as cms +from L1Trigger.TrackFindingTracklet.Producer_cfi import TrackFindingTrackletProducer_params +from L1Trigger.TrackFindingTracklet.Analyzer_cfi import TrackFindingTrackletAnalyzer_params + +# these parameters a for ModelSim runs of FW TrackTriggerDemonstrator_params = cms.PSet ( - LabelIn = cms.string( "TrackFindingTrackletProducerDRin" ), # - LabelOut = cms.string( "TrackFindingTrackletProducerDR" ), # - DirIPBB = cms.string( "/heplnw039/tschuh/work/proj/DRinDR/" ), # path to ipbb proj area - RunTime = cms.double( 4.5 ) # runtime in us + LabelIn = TrackFindingTrackletProducer_params.InputLabelDR, # + LabelOut = TrackFindingTrackletAnalyzer_params.OutputLabelDR, # + DirIPBB = cms.string( "/heplnw039/tschuh/work/proj/tmdr/" ), # path to ipbb proj area + RunTime = cms.double( 7.5 ), # runtime in us + + LinkMappingIn = cms.vint32( ), + LinkMappingOut = cms.vint32( ) ) diff --git a/L1Trigger/TrackFindingTracklet/python/KalmanFilterFormats_cfi.py b/L1Trigger/TrackFindingTracklet/python/KalmanFilterFormats_cfi.py new file mode 100644 index 0000000000000..606461f085206 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/python/KalmanFilterFormats_cfi.py @@ -0,0 +1,62 @@ +import FWCore.ParameterSet.Config as cms + +HybridKalmanFilterFormats_params = cms.PSet ( + + EnableIntegerEmulation = cms.bool( True ), # enables emulation of integer calculations + + WidthR00 = cms.int32( 20 ), # number of bits used to represent R00 + WidthR11 = cms.int32( 20 ), # number of bits used to represent R11 + + WidthC00 = cms.int32( 20 ), # number of bits used to represent C00 + WidthC01 = cms.int32( 20 ), # number of bits used to represent C01 + WidthC11 = cms.int32( 20 ), # number of bits used to represent C11 + WidthC22 = cms.int32( 20 ), # number of bits used to represent C22 + WidthC23 = cms.int32( 20 ), # number of bits used to represent C23 + WidthC33 = cms.int32( 20 ), # number of bits used to represent C33 + +# configuration of internal KF variable bases which can be shifted by powers of 2 w.r.t. KF output track parameter +# TrackerTFPProducer_params.PrintKFDebug printouts unused MSB for each variable, so that one could consider decreasing the basseshift by that amount +# numerical instabillity (negative C00, C11, C22, C33) requires smaller baseshifts of related variables (rx, Sxx, Kxx, Rxx, invRxx) +# if a variable overflows an Exception will be thrown and the corresponding baseshift needs to be increased. + + BaseShiftx0 = cms.int32( -1 ), # precision difference in powers of 2 between x0 and inv2R at KF output + BaseShiftx1 = cms.int32( -8 ), # precision difference in powers of 2 between x1 and phiT at KF output + BaseShiftx2 = cms.int32( -1 ), # precision difference in powers of 2 between x2 and cotTheta at KF output + BaseShiftx3 = cms.int32( -1 ), # precision difference in powers of 2 between x3 and zT at KF output + + BaseShiftr0 = cms.int32( -8 ), # precision difference in powers of 2 between phi residual and phiT + BaseShiftr1 = cms.int32( 0 ), # precision difference in powers of 2 between z residual and zT + + BaseShiftS00 = cms.int32( -4 ), # precision difference in powers of 2 between S00 and inv2R x phiT + BaseShiftS01 = cms.int32( -12 ), # precision difference in powers of 2 between S01 and phiT x phiT + BaseShiftS12 = cms.int32( 0 ), # precision difference in powers of 2 between S12 and cotTheta x zT + BaseShiftS13 = cms.int32( -1 ), # precision difference in powers of 2 between S13 and zT x zT + + BaseShiftR00 = cms.int32( -5 ), # precision difference in powers of 2 between R00 and phiT x phiT + BaseShiftR11 = cms.int32( 6 ), # precision difference in powers of 2 between R11 and zT x zT + + BaseShiftInvR00Approx = cms.int32( -30 ), + BaseShiftInvR11Approx = cms.int32( -41 ), + BaseShiftInvR00Cor = cms.int32( -24 ), + BaseShiftInvR11Cor = cms.int32( -24 ), + BaseShiftInvR00 = cms.int32( -30 ), # precision difference in powers of 2 between 1 / R00 and 1 / ( phiT x phiT ) + BaseShiftInvR11 = cms.int32( -41 ), # precision difference in powers of 2 between 1 / R11 and 1 / ( zT x zT ) + + BaseShiftS00Shifted = cms.int32( -1 ), + BaseShiftS01Shifted = cms.int32( -7 ), + BaseShiftS12Shifted = cms.int32( 4 ), + BaseShiftS13Shifted = cms.int32( 4 ), + + BaseShiftK00 = cms.int32( -7 ), # precision difference in powers of 2 between K00 and inv2R / phiT + BaseShiftK10 = cms.int32( -13 ), # precision difference in powers of 2 between K10 and 1 + BaseShiftK21 = cms.int32( -13 ), # precision difference in powers of 2 between K21 and cotTheta / zT + BaseShiftK31 = cms.int32( -13 ), # precision difference in powers of 2 between K31 and 1 + + BaseShiftC00 = cms.int32( 6 ), # precision difference in powers of 2 between C00 and inv2R * inv2R + BaseShiftC01 = cms.int32( 1 ), # precision difference in powers of 2 between C01 and inv2R * phiT + BaseShiftC11 = cms.int32( -6 ), # precision difference in powers of 2 between C11 and phiT * phiT + BaseShiftC22 = cms.int32( 5 ), # precision difference in powers of 2 between C22 and cotTheta * cotTheta + BaseShiftC23 = cms.int32( 6 ), # precision difference in powers of 2 between C23 and cotTheta * zT + BaseShiftC33 = cms.int32( 5 ) # precision difference in powers of 2 between C33 and zT * zT + +) diff --git a/L1Trigger/TrackFindingTracklet/python/ProducerHPH_cff.py b/L1Trigger/TrackFindingTracklet/python/ProducerHPH_cff.py index cf287e9b34b4c..947519004024b 100644 --- a/L1Trigger/TrackFindingTracklet/python/ProducerHPH_cff.py +++ b/L1Trigger/TrackFindingTracklet/python/ProducerHPH_cff.py @@ -1,9 +1,9 @@ import FWCore.ParameterSet.Config as cms # Get required input ESProducts -from L1Trigger.TrackerTFP.ProducerES_cff import TrackTriggerDataFormats -from L1Trigger.TrackerTFP.ProducerLayerEncoding_cff import TrackTriggerLayerEncoding -from L1Trigger.TrackTrigger.ProducerSetup_cff import TrackTriggerSetup +from L1Trigger.TrackerTFP.DataFormats_cff import TrackTriggerDataFormats +from L1Trigger.TrackerTFP.LayerEncoding_cff import TrackTriggerLayerEncoding +from L1Trigger.TrackTrigger.Setup_cff import TrackTriggerSetup # HitPatternHelper configuration from L1Trigger.TrackFindingTracklet.ProducerHPH_cfi import HitPatternHelper_params diff --git a/L1Trigger/TrackFindingTracklet/python/Producer_cff.py b/L1Trigger/TrackFindingTracklet/python/Producer_cff.py index c295baa0e2dd9..fb594be6d95b8 100644 --- a/L1Trigger/TrackFindingTracklet/python/Producer_cff.py +++ b/L1Trigger/TrackFindingTracklet/python/Producer_cff.py @@ -1,17 +1,19 @@ +# EDProducer to emulate hybrid track reconstruction chain after tracklet track fingding + import FWCore.ParameterSet.Config as cms -from L1Trigger.TrackTrigger.ProducerSetup_cff import TrackTriggerSetup -from L1Trigger.TrackerTFP.Producer_cfi import TrackerTFPProducer_params -from L1Trigger.TrackerTFP.ProducerES_cff import TrackTriggerDataFormats -from L1Trigger.TrackerTFP.ProducerLayerEncoding_cff import TrackTriggerLayerEncoding -from L1Trigger.TrackerTFP.KalmanFilterFormats_cff import TrackTriggerKalmanFilterFormats +from L1Trigger.TrackTrigger.Setup_cff import TrackTriggerSetup +from L1Trigger.TrackerTFP.LayerEncoding_cff import TrackTriggerLayerEncoding +from L1Trigger.TrackerTFP.TrackQuality_cff import * from L1Trigger.TrackFindingTracklet.ChannelAssignment_cff import ChannelAssignment +from L1Trigger.TrackFindingTracklet.DataFormats_cff import * +from L1Trigger.TrackFindingTracklet.KalmanFilterFormats_cfi import HybridKalmanFilterFormats_params from L1Trigger.TrackFindingTracklet.Producer_cfi import TrackFindingTrackletProducer_params +from L1Trigger.TrackFindingTMTT.TMTrackProducer_Defaults_cfi import TMTrackProducer_params -TrackFindingTrackletProducerIRin = cms.EDProducer( 'trklet::ProducerIRin', TrackFindingTrackletProducer_params ) -TrackFindingTrackletProducerTBout = cms.EDProducer( 'trklet::ProducerTBout', TrackFindingTrackletProducer_params ) -TrackFindingTrackletProducerDRin = cms.EDProducer( 'trklet::ProducerDRin', TrackFindingTrackletProducer_params ) -TrackFindingTrackletProducerDR = cms.EDProducer( 'trklet::ProducerDR', TrackFindingTrackletProducer_params ) -TrackFindingTrackletProducerKFin = cms.EDProducer( 'trklet::ProducerKFin', TrackFindingTrackletProducer_params ) -TrackFindingTrackletProducerKF = cms.EDProducer( 'trackerTFP::ProducerKF', TrackFindingTrackletProducer_params ) -TrackFindingTrackletProducerKFout = cms.EDProducer( 'trklet::ProducerKFout', TrackFindingTrackletProducer_params ) +ProducerIRin = cms.EDProducer( 'trklet::ProducerIRin', TrackFindingTrackletProducer_params ) +ProducerTM = cms.EDProducer( 'trklet::ProducerTM', TrackFindingTrackletProducer_params ) +ProducerDR = cms.EDProducer( 'trklet::ProducerDR', TrackFindingTrackletProducer_params ) +ProducerKF = cms.EDProducer( 'trklet::ProducerKF', TrackFindingTrackletProducer_params, HybridKalmanFilterFormats_params, TMTrackProducer_params ) +ProducerTQ = cms.EDProducer( 'trackerTFP::ProducerTQ', TrackFindingTrackletProducer_params ) +ProducerTFP = cms.EDProducer( 'trklet::ProducerTFP', TrackFindingTrackletProducer_params ) diff --git a/L1Trigger/TrackFindingTracklet/python/Producer_cfi.py b/L1Trigger/TrackFindingTracklet/python/Producer_cfi.py index 3ca33e23bd4e0..6b21d47f95f0a 100644 --- a/L1Trigger/TrackFindingTracklet/python/Producer_cfi.py +++ b/L1Trigger/TrackFindingTracklet/python/Producer_cfi.py @@ -1,26 +1,18 @@ +# configuration for hybrid track reconstruction chain emulating EDProducer + import FWCore.ParameterSet.Config as cms -from L1Trigger.TrackTrigger.TrackQualityParams_cfi import * TrackFindingTrackletProducer_params = cms.PSet ( - InputTag = cms.InputTag( "l1tTTTracksFromTrackletEmulation", "Level1TTTracks"), # - InputTagDTC = cms.InputTag( "TrackerDTCProducer", "StubAccepted"), # - LabelTBout = cms.string ( "TrackFindingTrackletProducerTBout" ), # - LabelDRin = cms.string ( "TrackFindingTrackletProducerDRin" ), # - LabelDR = cms.string ( "TrackFindingTrackletProducerDR" ), # - LabelKFin = cms.string ( "TrackFindingTrackletProducerKFin" ), # - LabelKF = cms.string ( "TrackFindingTrackletProducerKF" ), # - LabelKFout = cms.string ( "TrackFindingTrackletProducerKFout" ), # - BranchAcceptedStubs = cms.string ( "StubAccepted" ), # - BranchAcceptedTracks = cms.string ( "TrackAccepted" ), # - BranchAcceptedTTTracks = cms.string ( "TTTrackAccepted" ), # - BranchLostStubs = cms.string ( "StubLost" ), # - BranchLostTracks = cms.string ( "TrackLost" ), # - CheckHistory = cms.bool ( False ), # checks if input sample production is configured as current process - EnableTruncation = cms.bool ( True ), # enable emulation of truncation for TBout, KF, KFin, lost stubs are filled in BranchLost - PrintKFDebug = cms.bool ( False ), # print end job internal unused MSB - UseTTStubResiduals = cms.bool ( False ), # stub residuals are recalculated from seed parameter and TTStub position - TrackQualityPSet = cms.PSet ( TrackQualityParams ), - + InputLabelTFP = cms.string( "ProducerTQ" ), # + InputLabelTQ = cms.string( "ProducerKF" ), # + InputLabelKF = cms.string( "ProducerDR" ), # + InputLabelDR = cms.string( "ProducerTM" ), # + InputLabelTM = cms.string( "l1tTTTracksFromTrackletEmulation" ), # + BranchStubs = cms.string( "StubAccepted" ), # + BranchTracks = cms.string( "TrackAccepted" ), # + BranchTTTracks = cms.string( "TTTrackAccepted" ), # + BranchTruncated = cms.string( "Truncated" ), # + PrintKFDebug = cms.bool ( False ), # print end job internal unused MSB ) diff --git a/L1Trigger/TrackFindingTracklet/python/l1tTTTracksFromTrackletEmulation_cfi.py b/L1Trigger/TrackFindingTracklet/python/l1tTTTracksFromTrackletEmulation_cfi.py index 7515a7c089c62..4066a576a5250 100644 --- a/L1Trigger/TrackFindingTracklet/python/l1tTTTracksFromTrackletEmulation_cfi.py +++ b/L1Trigger/TrackFindingTracklet/python/l1tTTTracksFromTrackletEmulation_cfi.py @@ -1,11 +1,15 @@ import FWCore.ParameterSet.Config as cms -from L1Trigger.TrackTrigger.TrackQualityParams_cfi import * + +from L1Trigger.TrackFindingTracklet.Producer_cfi import TrackFindingTrackletProducer_params from L1Trigger.TrackFindingTracklet.ChannelAssignment_cff import ChannelAssignment +from L1Trigger.TrackerTFP.TrackQuality_cff import * +from L1Trigger.TrackerTFP.LayerEncoding_cff import TrackTriggerLayerEncoding l1tTTTracksFromTrackletEmulation = cms.EDProducer("L1FPGATrackProducer", + TrackFindingTrackletProducer_params, TTStubSource = cms.InputTag("TTStubsFromPhase2TrackerDigis","StubAccepted"), - InputTagTTDTC = cms.InputTag("TrackerDTCProducer", "StubAccepted"), - readMoreMcTruth = cms.bool(True), + InputTagTTDTC = cms.InputTag("ProducerDTC", "StubAccepted"), + readMoreMcTruth = cms.bool(False), MCTruthClusterInputTag = cms.InputTag("TTClusterAssociatorFromPixelDigis", "ClusterAccepted"), MCTruthStubInputTag = cms.InputTag("TTStubAssociatorFromPixelDigis", "StubAccepted"), TrackingParticleInputTag = cms.InputTag("mix", "MergedTrackTruth"), @@ -21,7 +25,6 @@ wiresFile = cms.FileInPath('L1Trigger/TrackFindingTracklet/data/wires_hourglassExtendedAllCombined.dat'), # Quality Flag and Quality params TrackQuality = cms.bool(True), - TrackQualityPSet = cms.PSet(TrackQualityParams), Fakefit = cms.bool(False), # True causes Tracklet reco to output TTTracks before DR & KF StoreTrackBuilderOutput = cms.bool(False), # if True EDProducts for TrackBuilder tracks and stubs will be filled RemovalType = cms.string("merge"), # Duplicate track removal @@ -36,6 +39,5 @@ tableTEDFile = cms.FileInPath('L1Trigger/TrackFindingTracklet/data/table_TED/table_TED_D1PHIA1_D2PHIA1.txt'), tableTREFile = cms.FileInPath('L1Trigger/TrackFindingTracklet/data/table_TRE/table_TRE_D1AD2A_1.txt'), # Quality Flag and Quality params - TrackQuality = cms.bool(False), - TrackQualityPSet = cms.PSet(TrackQualityParams) + TrackQuality = cms.bool(False) ) diff --git a/L1Trigger/TrackFindingTracklet/src/ChannelAssignment.cc b/L1Trigger/TrackFindingTracklet/src/ChannelAssignment.cc index a040bbc8125c3..4e430123a4112 100644 --- a/L1Trigger/TrackFindingTracklet/src/ChannelAssignment.cc +++ b/L1Trigger/TrackFindingTracklet/src/ChannelAssignment.cc @@ -14,31 +14,25 @@ using namespace tt; namespace trklet { - ChannelAssignment::ChannelAssignment(const edm::ParameterSet& iConfig, const Setup* setup) + ChannelAssignment::ChannelAssignment(const Config& iConfig, const Setup* setup) : setup_(setup), - pSetDRin_(iConfig.getParameter("DRin")), - widthLayerId_(pSetDRin_.getParameter("WidthLayerId")), - widthStubId_(pSetDRin_.getParameter("WidthStubId")), - widthSeedStubId_(pSetDRin_.getParameter("WidthSeedStubId")), - widthPSTilt_(pSetDRin_.getParameter("WidthPSTilt")), - depthMemory_(pSetDRin_.getParameter("DepthMemory")), - ptBoundaries_(pSetDRin_.getParameter>("PtBoundaries")), - pSetDR_(iConfig.getParameter("DR")), - numComparisonModules_(pSetDR_.getParameter("NumComparisonModules")), - minIdenticalStubs_(pSetDR_.getParameter("MinIdenticalStubs")), - numNodesDR_(2 * (ptBoundaries_.size() + 1)), - seedTypeNames_(iConfig.getParameter>("SeedTypes")), - numSeedTypes_(seedTypeNames_.size()), + tmMuxOrder_(iConfig.tmMuxOrder_), + tmNumLayers_(iConfig.tmNumLayers_), + tmWidthStubId_(iConfig.tmWidthStubId_), + tmWidthCot_(iConfig.tmWidthCot_), + numComparisonModules_(iConfig.numComparisonModules_), + minIdenticalStubs_(iConfig.minIdenticalStubs_), + seedTypeNames_(iConfig.seedTypeNames_), + numSeedTypes_(iConfig.seedTypeNames_.size()), numChannelsTrack_(numSeedTypes_), - channelEncoding_(iConfig.getParameter>("IRChannelsIn")) { - const ParameterSet& pSetSeedTypesSeedLayers = iConfig.getParameter("SeedTypesSeedLayers"); - const ParameterSet& pSetSeedTypesProjectionLayers = iConfig.getParameter("SeedTypesProjectionLayers"); - seedTypesSeedLayers_.reserve(numSeedTypes_); - seedTypesProjectionLayers_.reserve(numSeedTypes_); - for (const string& s : seedTypeNames_) { - seedTypesSeedLayers_.emplace_back(pSetSeedTypesSeedLayers.getParameter>(s)); - seedTypesProjectionLayers_.emplace_back(pSetSeedTypesProjectionLayers.getParameter>(s)); - } + numChannelsStub_(iConfig.numChannelsStub_), + seedTypesSeedLayers_(iConfig.seedTypesSeedLayers_), + seedTypesProjectionLayers_(iConfig.seedTypesProjectionLayers_), + maxNumProjectionLayers_(iConfig.maxNumProjectionLayers_), + channelEncoding_(iConfig.channelEncoding_), + offsetsStubs_(iConfig.offsetsStubs_), + numSeedingLayers_(iConfig.numSeedingLayers_), + tmMuxOrderInt_(iConfig.tmMuxOrderInt_) { // consistency check const int offsetBarrel = setup_->offsetLayerId(); const int numBarrelLayer = setup_->numBarrelLayer(); @@ -114,7 +108,7 @@ namespace trklet { numSeedingLayers_ = max_element(seedTypesSeedLayers_.begin(), seedTypesSeedLayers_.end(), bigger)->size(); maxNumProjectionLayers_ = max_element(seedTypesProjectionLayers_.begin(), seedTypesProjectionLayers_.end(), bigger)->size(); - auto acc = [](int sum, vector ints) { return sum += (int)ints.size(); }; + auto acc = [](int sum, vector ints) { return sum + static_cast(ints.size()); }; offsetsStubs_.reserve(numSeedTypes_); numChannelsStub_ = accumulate( seedTypesProjectionLayers_.begin(), seedTypesProjectionLayers_.end(), numSeedingLayers_ * numSeedTypes_, acc); @@ -186,22 +180,6 @@ namespace trklet { return -1; } - // return DR node for given ttTrackRef - int ChannelAssignment::nodeDR(const TTTrackRef& ttTrackRef) const { - const double pt = ttTrackRef->momentum().perp(); - int bin(0); - for (double b : ptBoundaries_) { - if (pt < b) - break; - bin++; - } - if (ttTrackRef->rInv() >= 0.) - bin += numNodesDR_ / 2; - else - bin = numNodesDR_ / 2 - 1 - bin; - return bin; - } - // layers a seed types can project to using default layer id [barrel: 1-6, discs: 11-15] int ChannelAssignment::layerId(int seedType, int channel) const { if (channel < numProjectionLayers(seedType)) diff --git a/L1Trigger/TrackFindingTracklet/src/DR.cc b/L1Trigger/TrackFindingTracklet/src/DR.cc deleted file mode 100644 index 14afa089a247e..0000000000000 --- a/L1Trigger/TrackFindingTracklet/src/DR.cc +++ /dev/null @@ -1,160 +0,0 @@ -#include "L1Trigger/TrackFindingTracklet/interface/DR.h" - -#include -#include -#include - -using namespace std; -using namespace edm; -using namespace tt; -using namespace trackerTFP; - -namespace trklet { - - DR::DR(const ParameterSet& iConfig, - const Setup* setup, - const DataFormats* dataFormats, - const ChannelAssignment* channelAssignment, - int region) - : enableTruncation_(iConfig.getParameter("EnableTruncation")), - setup_(setup), - dataFormats_(dataFormats), - channelAssignment_(channelAssignment), - region_(region), - input_(channelAssignment_->numNodesDR()) {} - - // read in and organize input tracks and stubs - void DR::consume(const StreamsTrack& streamsTrack, const StreamsStub& streamsStub) { - const int offsetTrack = region_ * channelAssignment_->numNodesDR(); - auto nonNullTrack = [](int sum, const FrameTrack& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); }; - auto nonNullStub = [](int sum, const FrameStub& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); }; - // count tracks and stubs and reserve corresponding vectors - int sizeTracks(0); - int sizeStubs(0); - for (int channel = 0; channel < channelAssignment_->numNodesDR(); channel++) { - const int streamTrackId = offsetTrack + channel; - const int offsetStub = streamTrackId * setup_->numLayers(); - const StreamTrack& streamTrack = streamsTrack[streamTrackId]; - input_[channel].reserve(streamTrack.size()); - sizeTracks += accumulate(streamTrack.begin(), streamTrack.end(), 0, nonNullTrack); - for (int layer = 0; layer < setup_->numLayers(); layer++) { - const StreamStub& streamStub = streamsStub[offsetStub + layer]; - sizeStubs += accumulate(streamStub.begin(), streamStub.end(), 0, nonNullStub); - } - } - tracks_.reserve(sizeTracks); - stubs_.reserve(sizeStubs); - // transform input data into handy structs - for (int channel = 0; channel < channelAssignment_->numNodesDR(); channel++) { - vector& input = input_[channel]; - const int streamTrackId = offsetTrack + channel; - const int offsetStub = streamTrackId * setup_->numLayers(); - const StreamTrack& streamTrack = streamsTrack[streamTrackId]; - for (int frame = 0; frame < (int)streamTrack.size(); frame++) { - const FrameTrack& frameTrack = streamTrack[frame]; - if (frameTrack.first.isNull()) { - input.push_back(nullptr); - continue; - } - vector stubs; - stubs.reserve(setup_->numLayers()); - for (int layer = 0; layer < setup_->numLayers(); layer++) { - const FrameStub& frameStub = streamsStub[offsetStub + layer][frame]; - if (frameStub.first.isNull()) - continue; - TTBV ttBV = frameStub.second; - const TTBV z(ttBV, dataFormats_->format(Variable::z, Process::kfin).width(), 0, true); - ttBV >>= dataFormats_->format(Variable::z, Process::kfin).width(); - const TTBV phi(ttBV, dataFormats_->format(Variable::phi, Process::kfin).width(), 0, true); - ttBV >>= dataFormats_->format(Variable::phi, Process::kfin).width(); - const TTBV r(ttBV, dataFormats_->format(Variable::r, Process::kfin).width(), 0, true); - ttBV >>= dataFormats_->format(Variable::r, Process::kfin).width(); - const TTBV stubId(ttBV, channelAssignment_->widthSeedStubId(), 0); - ttBV >>= channelAssignment_->widthSeedStubId(); - const TTBV layerId(ttBV, channelAssignment_->widthLayerId(), 0); - ttBV >>= channelAssignment_->widthLayerId(); - const TTBV tilt(ttBV, channelAssignment_->widthPSTilt(), 0); - const FrameStub frame(frameStub.first, - Frame("1" + tilt.str() + layerId.str() + r.str() + phi.str() + z.str())); - stubs_.emplace_back(frame, stubId.val(), layer); - stubs.push_back(&stubs_.back()); - } - tracks_.emplace_back(frameTrack, stubs); - input.push_back(&tracks_.back()); - } - // remove all gaps between end and last track - for (auto it = input.end(); it != input.begin();) - it = (*--it) ? input.begin() : input.erase(it); - } - } - - // fill output products - void DR::produce(StreamsStub& accpetedStubs, - StreamsTrack& acceptedTracks, - StreamsStub& lostStubs, - StreamsTrack& lostTracks) { - const int offsetTrack = region_ * channelAssignment_->numNodesDR(); - for (int node = 0; node < channelAssignment_->numNodesDR(); node++) { - const int channelTrack = offsetTrack + node; - const int offsetStub = channelTrack * setup_->numLayers(); - // remove duplicated tracks, no merge of stubs, one stub per layer expected - vector cms(channelAssignment_->numComparisonModules(), nullptr); - vector& tracks = input_[node]; - for (Track*& track : tracks) { - if (!track) - // gaps propagate trough chain and appear in output stream - continue; - for (Track*& trackCM : cms) { - if (!trackCM) { - // tracks used in CMs propagate trough chain and appear in output stream unaltered - trackCM = track; - break; - } - if (equalEnough(track, trackCM)) { - // tracks compared in CMs propagate trough chain and appear in output stream as gap if identified as duplicate or unaltered elsewise - track = nullptr; - break; - } - } - } - // remove all gaps between end and last track - for (auto it = tracks.end(); it != tracks.begin();) - it = (*--it) ? tracks.begin() : tracks.erase(it); - // store output - StreamTrack& streamTrack = acceptedTracks[channelTrack]; - streamTrack.reserve(tracks.size()); - for (int layer = 0; layer < setup_->numLayers(); layer++) - accpetedStubs[offsetStub + layer].reserve(tracks.size()); - for (Track* track : tracks) { - if (!track) { - streamTrack.emplace_back(FrameTrack()); - for (int layer = 0; layer < setup_->numLayers(); layer++) - accpetedStubs[offsetStub + layer].emplace_back(FrameStub()); - continue; - } - streamTrack.push_back(track->frame_); - TTBV hitPattern(0, setup_->numLayers()); - for (Stub* stub : track->stubs_) { - hitPattern.set(stub->channel_); - accpetedStubs[offsetStub + stub->channel_].push_back(stub->frame_); - } - for (int layer : hitPattern.ids(false)) - accpetedStubs[offsetStub + layer].emplace_back(FrameStub()); - } - } - } - - // compares two tracks, returns true if those are considered duplicates - bool DR::equalEnough(Track* t0, Track* t1) const { - int same(0); - for (int layer = 0; layer < setup_->numLayers(); layer++) { - auto onLayer = [layer](Stub* stub) { return stub->channel_ == layer; }; - const auto s0 = find_if(t0->stubs_.begin(), t0->stubs_.end(), onLayer); - const auto s1 = find_if(t1->stubs_.begin(), t1->stubs_.end(), onLayer); - if (s0 != t0->stubs_.end() && s1 != t1->stubs_.end() && **s0 == **s1) - same++; - } - return same >= channelAssignment_->minIdenticalStubs(); - } - -} // namespace trklet diff --git a/L1Trigger/TrackFindingTracklet/src/DRin.cc b/L1Trigger/TrackFindingTracklet/src/DRin.cc deleted file mode 100644 index 9196ff1fee994..0000000000000 --- a/L1Trigger/TrackFindingTracklet/src/DRin.cc +++ /dev/null @@ -1,459 +0,0 @@ -#include "L1Trigger/TrackFindingTracklet/interface/DRin.h" - -#include -#include -#include -#include - -using namespace std; -using namespace edm; -using namespace tt; -using namespace trackerTFP; - -namespace trklet { - - DRin::DRin(const ParameterSet& iConfig, - const Setup* setup, - const DataFormats* dataFormats, - const LayerEncoding* layerEncoding, - const ChannelAssignment* channelAssignment, - const Settings* settings, - int region) - : enableTruncation_(iConfig.getParameter("EnableTruncation")), - useTTStubResiduals_(iConfig.getParameter("UseTTStubResiduals")), - setup_(setup), - dataFormats_(dataFormats), - layerEncoding_(layerEncoding), - channelAssignment_(channelAssignment), - settings_(settings), - region_(region), - input_(channelAssignment_->numChannelsTrack()), - // unified tracklet digitisation granularity - baseUinv2R_(.5 * settings_->kphi1() / settings_->kr() * pow(2, settings_->rinv_shift())), - baseUphiT_(settings_->kphi1() * pow(2, settings_->phi0_shift())), - baseUcot_(settings_->kz() / settings_->kr() * pow(2, settings_->t_shift())), - baseUzT_(settings_->kz() * pow(2, settings_->z0_shift())), - baseUr_(settings_->kr()), - baseUphi_(settings_->kphi1()), - baseUz_(settings_->kz()), - // KF input format digitisation granularity (identical to TMTT) - baseLinv2R_(dataFormats->base(Variable::inv2R, Process::kfin)), - baseLphiT_(dataFormats->base(Variable::phiT, Process::kfin)), - baseLcot_(dataFormats->base(Variable::cot, Process::kfin)), - baseLzT_(dataFormats->base(Variable::zT, Process::kfin)), - baseLr_(dataFormats->base(Variable::r, Process::kfin)), - baseLphi_(dataFormats->base(Variable::phi, Process::kfin)), - baseLz_(dataFormats->base(Variable::z, Process::kfin)), - // Finer granularity (by powers of 2) than the TMTT one. Used to transform from Tracklet to TMTT base. - baseHinv2R_(baseLinv2R_ * pow(2, floor(log2(baseUinv2R_ / baseLinv2R_)))), - baseHphiT_(baseLphiT_ * pow(2, floor(log2(baseUphiT_ / baseLphiT_)))), - baseHcot_(baseLcot_ * pow(2, floor(log2(baseUcot_ / baseLcot_)))), - baseHzT_(baseLzT_ * pow(2, floor(log2(baseUzT_ / baseLzT_)))), - baseHr_(baseLr_ * pow(2, floor(log2(baseUr_ / baseLr_)))), - baseHphi_(baseLphi_ * pow(2, floor(log2(baseUphi_ / baseLphi_)))), - baseHz_(baseLz_ * pow(2, floor(log2(baseUz_ / baseLz_)))) { - // calculate digitisation granularity used for inverted cot(theta) - const int baseShiftInvCot = ceil(log2(setup_->outerRadius() / setup_->hybridRangeR())) - setup_->widthDSPbu(); - baseInvCot_ = pow(2, baseShiftInvCot); - } - - // read in and organize input tracks and stubs - void DRin::consume(const StreamsTrack& streamsTrack, const StreamsStub& streamsStub) { - static const double maxCot = sinh(setup_->maxEta()) + setup_->beamWindowZ() / setup_->chosenRofZ(); - static const int unusedMSBcot = floor(log2(baseUcot_ * pow(2, settings_->nbitst()) / (2. * maxCot))); - static const double baseCot = - baseUcot_ * pow(2, settings_->nbitst() - unusedMSBcot - 1 - setup_->widthAddrBRAM18()); - const int offsetTrack = region_ * channelAssignment_->numChannelsTrack(); - // count tracks and stubs to reserve container - int nTracks(0); - int nStubs(0); - for (int channel = 0; channel < channelAssignment_->numChannelsTrack(); channel++) { - const int channelTrack = offsetTrack + channel; - const int offsetStub = channelAssignment_->offsetStub(channelTrack); - const StreamTrack& streamTrack = streamsTrack[channelTrack]; - input_[channel].reserve(streamTrack.size()); - for (int frame = 0; frame < (int)streamTrack.size(); frame++) { - if (streamTrack[frame].first.isNull()) - continue; - nTracks++; - for (int layer = 0; layer < channelAssignment_->numProjectionLayers(channel); layer++) - if (streamsStub[offsetStub + layer][frame].first.isNonnull()) - nStubs++; - } - } - stubs_.reserve(nStubs + nTracks * channelAssignment_->numSeedingLayers()); - tracks_.reserve(nTracks); - // store tracks and stubs - for (int channel = 0; channel < channelAssignment_->numChannelsTrack(); channel++) { - const int channelTrack = offsetTrack + channel; - const int offsetStub = channelAssignment_->offsetStub(channelTrack); - const StreamTrack& streamTrack = streamsTrack[channelTrack]; - vector& input = input_[channel]; - for (int frame = 0; frame < (int)streamTrack.size(); frame++) { - const TTTrackRef& ttTrackRef = streamTrack[frame].first; - if (ttTrackRef.isNull()) { - input.push_back(nullptr); - continue; - } - //convert track parameter - const double r2Inv = digi(-ttTrackRef->rInv() / 2., baseUinv2R_); - const double phi0U = - digi(tt::deltaPhi(ttTrackRef->phi() - region_ * setup_->baseRegion() + setup_->hybridRangePhi() / 2.), - baseUphiT_); - const double phi0S = digi(phi0U - setup_->hybridRangePhi() / 2., baseUphiT_); - const double cot = digi(ttTrackRef->tanL(), baseUcot_); - const double z0 = digi(ttTrackRef->z0(), baseUzT_); - const double phiT = digi(phi0S + r2Inv * digi(dataFormats_->chosenRofPhi(), baseUr_), baseUphiT_); - const double zT = digi(z0 + cot * digi(setup_->chosenRofZ(), baseUr_), baseUzT_); - // kill tracks outside of fiducial range - if (abs(phiT) > setup_->baseRegion() / 2. || abs(zT) > setup_->hybridMaxCot() * setup_->chosenRofZ() || - abs(z0) > setup_->beamWindowZ()) { - input.push_back(nullptr); - continue; - } - // convert stubs - vector stubs; - stubs.reserve(channelAssignment_->numProjectionLayers(channel) + channelAssignment_->numSeedingLayers()); - for (int layer = 0; layer < channelAssignment_->numProjectionLayers(channel); layer++) { - const FrameStub& frameStub = streamsStub[offsetStub + layer][frame]; - const TTStubRef& ttStubRef = frameStub.first; - if (ttStubRef.isNull()) - continue; - const int layerId = channelAssignment_->layerId(channel, layer); - // parse residuals from tt::Frame and take r and layerId from tt::TTStubRef - const bool barrel = setup_->barrel(ttStubRef); - const int layerIdTracklet = setup_->trackletLayerId(ttStubRef); - const double basePhi = barrel ? settings_->kphi1() : settings_->kphi(layerIdTracklet); - const double baseRZ = barrel ? settings_->kz(layerIdTracklet) : settings_->kz(); - const int widthRZ = barrel ? settings_->zresidbits() : settings_->rresidbits(); - TTBV hw(frameStub.second); - const TTBV hwRZ(hw, widthRZ, 0, true); - hw >>= widthRZ; - const TTBV hwPhi(hw, settings_->phiresidbits(), 0, true); - hw >>= settings_->phiresidbits(); - const int indexLayerId = setup_->indexLayerId(ttStubRef); - const SensorModule::Type type = setup_->type(ttStubRef); - const int widthR = setup_->tbWidthR(type); - const double baseR = setup_->hybridBaseR(type); - const TTBV hwR(hw, widthR, 0, barrel); - hw >>= widthR; - double r = hwR.val(baseR) + (barrel ? setup_->hybridLayerR(indexLayerId) : 0.); - if (type == SensorModule::Disk2S) - r = setup_->disk2SR(indexLayerId, r); - r = digi(r - dataFormats_->chosenRofPhi(), baseUr_); - double phi = hwPhi.val(basePhi); - if (basePhi > baseUphi_) - phi += baseUphi_ / 2.; - const double z = digi(hwRZ.val(baseRZ) * (barrel ? 1. : -cot), baseUz_); - const TTBV hwStubId(hw, channelAssignment_->widthSeedStubId(), 0, false); - const int stubId = hwStubId.val(); - // determine module type - bool psTilt; - if (barrel) { - const double posZ = (r + digi(dataFormats_->chosenRofPhi(), baseUr_)) * cot + z0 + z; - const int indexLayerId = setup_->indexLayerId(ttStubRef); - const double limit = setup_->tiltedLayerLimitZ(indexLayerId); - psTilt = abs(posZ) < limit; - } else - psTilt = setup_->psModule(ttStubRef); - if (useTTStubResiduals_) { - const GlobalPoint gp = setup_->stubPos(ttStubRef); - const double ttR = r; - const double ttZ = gp.z() - (z0 + (ttR + dataFormats_->chosenRofPhi()) * cot); - stubs_.emplace_back(ttStubRef, layerId, layerIdTracklet, false, stubId, ttR, phi, ttZ, psTilt); - } else - stubs_.emplace_back(ttStubRef, layerId, layerIdTracklet, false, stubId, r, phi, z, psTilt); - stubs.push_back(&stubs_.back()); - } - // create fake seed stubs, since TrackBuilder doesn't output these stubs, required by the KF. - for (int seedingLayer = 0; seedingLayer < channelAssignment_->numSeedingLayers(); seedingLayer++) { - const int channelStub = channelAssignment_->numProjectionLayers(channel) + seedingLayer; - const FrameStub& frameStub = streamsStub[offsetStub + channelStub][frame]; - const TTStubRef& ttStubRef = frameStub.first; - if (ttStubRef.isNull()) - continue; - const int layerId = channelAssignment_->layerId(channel, channelStub); - const int layerIdTracklet = setup_->trackletLayerId(ttStubRef); - const int stubId = TTBV(frameStub.second).val(channelAssignment_->widthSeedStubId()); - const bool barrel = setup_->barrel(ttStubRef); - double r; - if (barrel) - r = digi(setup_->hybridLayerR(layerId - setup_->offsetLayerId()) - dataFormats_->chosenRofPhi(), baseUr_); - else { - r = (z0 + - digi(setup_->hybridDiskZ(layerId - setup_->offsetLayerId() - setup_->offsetLayerDisks()), baseUzT_)) * - digi(1. / digi(abs(cot), baseCot), baseInvCot_); - r = digi(r - digi(dataFormats_->chosenRofPhi(), baseUr_), baseUr_); - } - static constexpr double phi = 0.; - static constexpr double z = 0.; - // determine module type - bool psTilt; - if (barrel) { - const double posZ = - digi(digi(setup_->hybridLayerR(layerId - setup_->offsetLayerId()), baseUr_) * cot + z0, baseUz_); - const int indexLayerId = setup_->indexLayerId(ttStubRef); - const double limit = digi(setup_->tiltedLayerLimitZ(indexLayerId), baseUz_); - psTilt = abs(posZ) < limit; - } else - psTilt = true; - const GlobalPoint gp = setup_->stubPos(ttStubRef); - const double ttR = gp.perp() - dataFormats_->chosenRofPhi(); - const double ttZ = gp.z() - (z0 + (ttR + dataFormats_->chosenRofPhi()) * cot); - if (useTTStubResiduals_) - stubs_.emplace_back(ttStubRef, layerId, layerIdTracklet, true, stubId, ttR, phi, ttZ, psTilt); - else - stubs_.emplace_back(ttStubRef, layerId, layerIdTracklet, true, stubId, r, phi, z, psTilt); - stubs.push_back(&stubs_.back()); - } - const bool valid = frame < setup_->numFrames() ? true : enableTruncation_; - tracks_.emplace_back(ttTrackRef, valid, r2Inv, phiT, cot, zT, stubs); - input.push_back(&tracks_.back()); - } - } - } - - // fill output products - void DRin::produce(StreamsStub& accpetedStubs, - StreamsTrack& acceptedTracks, - StreamsStub& lostStubs, - StreamsTrack& lostTracks) { - // base transform into high precision TMTT format - for (Track& track : tracks_) { - track.inv2R_ = redigi(track.inv2R_, baseUinv2R_, baseHinv2R_, setup_->widthDSPbu()); - track.phiT_ = redigi(track.phiT_, baseUphiT_, baseHphiT_, setup_->widthDSPbu()); - track.cot_ = redigi(track.cot_, baseUcot_, baseHcot_, setup_->widthDSPbu()); - track.zT_ = redigi(track.zT_, baseUzT_, baseHzT_, setup_->widthDSPbu()); - for (Stub* stub : track.stubs_) { - stub->r_ = redigi(stub->r_, baseUr_, baseHr_, setup_->widthDSPbu()); - stub->phi_ = redigi(stub->phi_, baseUphi_, baseHphi_, setup_->widthDSPbu()); - stub->z_ = redigi(stub->z_, baseUz_, baseHz_, setup_->widthDSPbu()); - } - } - // find sector - for (Track& track : tracks_) { - const int sectorPhi = track.phiT_ < 0. ? 0 : 1; - track.phiT_ -= (sectorPhi - .5) * setup_->baseSector(); - int sectorEta(-1); - for (; sectorEta < setup_->numSectorsEta(); sectorEta++) - if (track.zT_ < digi(setup_->chosenRofZ() * sinh(setup_->boundarieEta(sectorEta + 1)), baseHzT_)) - break; - if (sectorEta >= setup_->numSectorsEta() || sectorEta <= -1) { - track.valid_ = false; - continue; - } - track.cot_ = track.cot_ - digi(setup_->sectorCot(sectorEta), baseHcot_); - track.zT_ = track.zT_ - digi(setup_->chosenRofZ() * setup_->sectorCot(sectorEta), baseHzT_); - track.sector_ = sectorPhi * setup_->numSectorsEta() + sectorEta; - } - // base transform into TMTT format - for (Track& track : tracks_) { - if (!track.valid_) - continue; - // store track parameter shifts - const double dinv2R = digi(track.inv2R_ - digi(track.inv2R_, baseLinv2R_), baseHinv2R_); - const double dphiT = digi(track.phiT_ - digi(track.phiT_, baseLphiT_), baseHphiT_); - const double dcot = digi(track.cot_ - digi(track.cot_, baseLcot_), baseHcot_); - const double dzT = digi(track.zT_ - digi(track.zT_, baseLzT_), baseHzT_); - // shift track parameter; - track.inv2R_ = digi(track.inv2R_, baseLinv2R_); - track.phiT_ = digi(track.phiT_, baseLphiT_); - track.cot_ = digi(track.cot_, baseLcot_); - track.zT_ = digi(track.zT_, baseLzT_); - // range checks - if (!dataFormats_->format(Variable::inv2R, Process::kfin).inRange(track.inv2R_, true)) - track.valid_ = false; - if (!dataFormats_->format(Variable::phiT, Process::kfin).inRange(track.phiT_, true)) - track.valid_ = false; - if (!dataFormats_->format(Variable::cot, Process::kfin).inRange(track.cot_, true)) - track.valid_ = false; - if (!dataFormats_->format(Variable::zT, Process::kfin).inRange(track.zT_, true)) - track.valid_ = false; - if (!track.valid_) - continue; - // adjust stub residuals by track parameter shifts - for (Stub* stub : track.stubs_) { - const double dphi = digi(dphiT + stub->r_ * dinv2R, baseHphi_); - const double r = stub->r_ + digi(dataFormats_->chosenRofPhi() - setup_->chosenRofZ(), baseHr_); - const double dz = digi(dzT + r * dcot, baseHz_); - stub->phi_ = digi(stub->phi_ + dphi, baseLphi_); - stub->z_ = digi(stub->z_ + dz, baseLz_); - // range checks - if (!dataFormats_->format(Variable::phi, Process::kfin).inRange(stub->phi_)) - stub->valid_ = false; - if (!dataFormats_->format(Variable::z, Process::kfin).inRange(stub->z_)) - stub->valid_ = false; - } - } - // encode layer id - for (Track& track : tracks_) { - if (!track.valid_) - continue; - const int sectorEta = track.sector_ % setup_->numSectorsEta(); - const int zT = dataFormats_->format(Variable::zT, Process::kfin).toUnsigned(track.zT_); - const int cot = dataFormats_->format(Variable::cot, Process::kfin).toUnsigned(track.cot_); - for (Stub* stub : track.stubs_) { - if (!stub->valid_) - continue; - // store encoded layerId - stub->layerKF_ = layerEncoding_->layerIdKF(sectorEta, zT, cot, stub->layer_); - // kill stubs from layers which can't be crossed by track - if (stub->layerKF_ == -1) - stub->valid_ = false; - } - TTBV hitPattern(0, setup_->numLayers()); - // kill multiple stubs from same kf layer - for (Stub* stub : track.stubs_) { - if (!stub->valid_) - continue; - if (hitPattern[stub->layerKF_]) - stub->valid_ = false; - else - hitPattern.set(stub->layerKF_); - } - // lookup maybe layers - track.maybe_ = layerEncoding_->maybePattern(sectorEta, zT, cot); - } - // kill tracks with not enough layer - for (Track& track : tracks_) { - if (!track.valid_) - continue; - TTBV hits(0, setup_->numLayers()); - for (const Stub* stub : track.stubs_) - if (stub->valid_) - hits.set(stub->layerKF_); - if (hits.count() < setup_->kfMinLayers()) - track.valid_ = false; - } - // store helper - auto frameTrack = [this](Track* track) { - const TTBV sectorPhi( - dataFormats_->format(Variable::sectorPhi, Process::kfin).ttBV(track->sector_ / setup_->numSectorsEta())); - const TTBV sectorEta( - dataFormats_->format(Variable::sectorEta, Process::kfin).ttBV(track->sector_ % setup_->numSectorsEta())); - const TTBV inv2R(dataFormats_->format(Variable::inv2R, Process::kfin).ttBV(track->inv2R_)); - const TTBV phiT(dataFormats_->format(Variable::phiT, Process::kfin).ttBV(track->phiT_)); - const TTBV cot(dataFormats_->format(Variable::cot, Process::kfin).ttBV(track->cot_)); - const TTBV zT(dataFormats_->format(Variable::zT, Process::kfin).ttBV(track->zT_)); - return FrameTrack( - track->ttTrackRef_, - Frame("1" + sectorPhi.str() + sectorEta.str() + inv2R.str() + phiT.str() + zT.str() + cot.str())); - }; - auto frameStub = [this](Track* track, int layer) { - auto equal = [layer](Stub* stub) { return stub->valid_ && stub->layerKF_ == layer; }; - const auto it = find_if(track->stubs_.begin(), track->stubs_.end(), equal); - if (it == track->stubs_.end() || !(*it)->valid_) - return FrameStub(); - Stub* stub = *it; - const TTBV layerId(stub->layerDet_, channelAssignment_->widthLayerId()); - const TTBV stubId(stub->stubId_, channelAssignment_->widthSeedStubId(), true); - const TTBV r(dataFormats_->format(Variable::r, Process::kfin).ttBV(stub->r_)); - const TTBV phi(dataFormats_->format(Variable::phi, Process::kfin).ttBV(stub->phi_)); - const TTBV z(dataFormats_->format(Variable::z, Process::kfin).ttBV(stub->z_)); - return FrameStub( - stub->ttStubRef_, - Frame("1" + to_string(stub->psTilt_) + layerId.str() + stubId.str() + r.str() + phi.str() + z.str())); - }; - // route tracks into pt bins and store result - const int offsetTrack = region_ * channelAssignment_->numNodesDR(); - for (int nodeDR = 0; nodeDR < channelAssignment_->numNodesDR(); nodeDR++) { - deque accepted; - deque lost; - vector> stacks(channelAssignment_->numChannelsTrack()); - vector> inputs(channelAssignment_->numChannelsTrack()); - for (int channel = 0; channel < channelAssignment_->numChannelsTrack(); channel++) { - for (Track* track : input_[channel]) { - const bool match = track && channelAssignment_->nodeDR(track->ttTrackRef_) == nodeDR; - if (match && !track->valid_) - lost.push_back(track); - inputs[channel].push_back(match && track->valid_ ? track : nullptr); - } - } - // remove all gaps between end and last track - for (deque& input : inputs) - for (auto it = input.end(); it != input.begin();) - it = (*--it) ? input.begin() : input.erase(it); - // clock accurate firmware emulation, each while trip describes one clock tick, one stub in and one stub out per tick - while (!all_of(inputs.begin(), inputs.end(), [](const deque& tracks) { return tracks.empty(); }) or - !all_of(stacks.begin(), stacks.end(), [](const deque& tracks) { return tracks.empty(); })) { - // fill input fifos - for (int channel = 0; channel < channelAssignment_->numChannelsTrack(); channel++) { - deque& stack = stacks[channel]; - Track* track = pop_front(inputs[channel]); - if (track) { - if (enableTruncation_ && (int)stack.size() == channelAssignment_->depthMemory() - 1) - lost.push_back(pop_front(stack)); - stack.push_back(track); - } - } - // merge input fifos to one stream, prioritizing higher input channel over lower channel - bool nothingToRoute(true); - for (int channel = channelAssignment_->numChannelsTrack() - 1; channel >= 0; channel--) { - Track* track = pop_front(stacks[channel]); - if (track) { - nothingToRoute = false; - accepted.push_back(track); - break; - } - } - if (nothingToRoute) - accepted.push_back(nullptr); - } - // truncate if desired - if (enableTruncation_ && (int)accepted.size() > setup_->numFrames()) { - const auto limit = next(accepted.begin(), setup_->numFrames()); - copy_if(limit, accepted.end(), back_inserter(lost), [](const Track* track) { return track; }); - accepted.erase(limit, accepted.end()); - } - // remove all gaps between end and last track - for (auto it = accepted.end(); it != accepted.begin();) - it = (*--it) ? accepted.begin() : accepted.erase(it); - // fill products StreamsStub& accpetedStubs, StreamsTrack& acceptedTracks, StreamsStub& lostStubs, StreamsTrack& lostTracks - const int channelTrack = offsetTrack + nodeDR; - const int offsetStub = channelTrack * setup_->numLayers(); - // fill lost tracks and stubs without gaps - lostTracks[channelTrack].reserve(lost.size()); - for (int layer = 0; layer < setup_->numLayers(); layer++) - lostStubs[offsetStub + layer].reserve(lost.size()); - for (Track* track : lost) { - lostTracks[channelTrack].emplace_back(frameTrack(track)); - for (int layer = 0; layer < setup_->numLayers(); layer++) - lostStubs[offsetStub + layer].emplace_back(frameStub(track, layer)); - } - // fill accepted tracks and stubs with gaps - acceptedTracks[channelTrack].reserve(accepted.size()); - for (int layer = 0; layer < setup_->numLayers(); layer++) - accpetedStubs[offsetStub + layer].reserve(accepted.size()); - for (Track* track : accepted) { - if (!track) { // fill gap - acceptedTracks[channelTrack].emplace_back(FrameTrack()); - for (int layer = 0; layer < setup_->numLayers(); layer++) - accpetedStubs[offsetStub + layer].emplace_back(FrameStub()); - continue; - } - acceptedTracks[channelTrack].emplace_back(frameTrack(track)); - for (int layer = 0; layer < setup_->numLayers(); layer++) - accpetedStubs[offsetStub + layer].emplace_back(frameStub(track, layer)); - } - } - } - - // remove and return first element of deque, returns nullptr if empty - template - T* DRin::pop_front(deque& ts) const { - T* t = nullptr; - if (!ts.empty()) { - t = ts.front(); - ts.pop_front(); - } - return t; - } - - // basetransformation of val from baseLow into baseHigh using widthMultiplier bit multiplication - double DRin::redigi(double val, double baseLow, double baseHigh, int widthMultiplier) const { - const double base = pow(2, 1 - widthMultiplier); - const double transform = digi(baseLow / baseHigh, base); - return (floor(val * transform / baseLow) + .5) * baseHigh; - } - -} // namespace trklet diff --git a/L1Trigger/TrackFindingTracklet/src/DataFormats.cc b/L1Trigger/TrackFindingTracklet/src/DataFormats.cc new file mode 100644 index 0000000000000..8665338fcc950 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/DataFormats.cc @@ -0,0 +1,245 @@ +#include "L1Trigger/TrackFindingTracklet/interface/DataFormats.h" +#include "DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace trklet { + + // default constructor, trying to need space as proper constructed object + DataFormats::DataFormats() + : numDataFormats_(0), + formats_(+Variable::end, std::vector(+Process::end, nullptr)), + numUnusedBitsStubs_(+Process::end, TTBV::S_ - 1), + numUnusedBitsTracks_(+Process::end, TTBV::S_ - 1) { + channelAssignment_ = nullptr; + countFormats(); + dataFormats_.reserve(numDataFormats_); + } + + // method to count number of unique data formats + template + void DataFormats::countFormats() { + if constexpr (config_[+v][+p] == p) + numDataFormats_++; + if constexpr (++p != Process::end) + countFormats(); + else if constexpr (++v != Variable::end) + countFormats<++v>(); + } + + // proper constructor + DataFormats::DataFormats(const ChannelAssignment* channelAssignment) : DataFormats() { + channelAssignment_ = channelAssignment; + fillDataFormats(); + for (const Process p : Processes) + for (const Variable v : stubs_[+p]) + numUnusedBitsStubs_[+p] -= formats_[+v][+p] ? formats_[+v][+p]->width() : 0; + for (const Process p : Processes) + for (const Variable v : tracks_[+p]) + numUnusedBitsTracks_[+p] -= formats_[+v][+p] ? formats_[+v][+p]->width() : 0; + } + + // constructs data formats of all unique used variables and flavours + template + void DataFormats::fillDataFormats() { + if constexpr (config_[+v][+p] == p) { + dataFormats_.emplace_back(makeDataFormat(channelAssignment_)); + fillFormats(); + } + if constexpr (++p != Process::end) + fillDataFormats(); + else if constexpr (++v != Variable::end) + fillDataFormats<++v>(); + } + + // helper (loop) data formats of all unique used variables and flavours + template + void DataFormats::fillFormats() { + if (config_[+v][+it] == p) { + formats_[+v][+it] = &dataFormats_.back(); + } + if constexpr (++it != Process::end) + fillFormats(); + } + + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca) { + const int width = TTTrack_TrackWord::TrackBitWidths::kRinvSize; + const double range = -2. * TTTrack_TrackWord::minRinv; + const double base = range * std::pow(2, -width); + return DataFormat(true, width, base, range); + } + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca) { + const int width = TTTrack_TrackWord::TrackBitWidths::kPhiSize; + const double range = -2. * TTTrack_TrackWord::minPhi0; + const double base = range * std::pow(2, -width); + return DataFormat(true, width, base, range); + } + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca) { + const int width = TTTrack_TrackWord::TrackBitWidths::kTanlSize; + const double range = -2. * TTTrack_TrackWord::minTanl; + const double base = range * std::pow(2, -width); + return DataFormat(true, width, base, range); + } + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca) { + const int width = TTTrack_TrackWord::TrackBitWidths::kZ0Size; + const double range = -2. * TTTrack_TrackWord::minZ0; + const double base = range * std::pow(2, -width); + return DataFormat(true, width, base, range); + } + + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca) { + const tt::Setup* s = ca->setup(); + const double thight = s->htNumBinsInv2R(); + const double loose = thight + 2; + const double range = 2. * s->invPtToDphi() / s->minPt() * loose / thight; + const double base = range / loose; + const int width = std::ceil(std::log2(range / base)); + return DataFormat(true, width, base, range); + } + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca) { + const tt::Setup* s = ca->setup(); + const double thight = s->gpNumBinsPhiT() * s->htNumBinsPhiT(); + const double loose = thight + 2 * s->gpNumBinsPhiT(); + const double range = 2. * M_PI / s->numRegions() * loose / thight; + const double base = range / loose; + const int width = std::ceil(std::log2(range / base)); + return DataFormat(true, width, base, range); + } + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca) { + const tt::Setup* s = ca->setup(); + const double thight = s->gpNumBinsZT(); + const double loose = thight + 2; + const double range = 2. * std::sinh(s->maxEta()) * s->chosenRofZ() * loose / thight; + const double base = range / loose; + const int width = std::ceil(std::log2(range / base)); + return DataFormat(true, width, base, range); + } + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca) { + const tt::Setup* s = ca->setup(); + const DataFormat zT = makeDataFormat(ca); + const double range = (zT.range() + 2. * s->beamWindowZ()) / s->chosenRofZ(); + const double base = (zT.base() + 2. * s->beamWindowZ()) / s->chosenRofZ(); + const int width = std::ceil(std::log2(range / base)); + return DataFormat(true, width, base, range); + } + + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca) { + const int width = ca->tmWidthStubId() + 1; + const double base = 1.; + const double range = std::pow(2, width); + return DataFormat(false, width, base, range); + } + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca) { + const tt::Setup* s = ca->setup(); + const DataFormat phiT = makeDataFormat(ca); + const DataFormat inv2R = makeDataFormat(ca); + const double range = 2. * s->maxRphi(); + const double baseShifted = phiT.base() / inv2R.base(); + const int shift = std::ceil(std::log2(range / baseShifted)) - s->tmttWidthR(); + const double base = baseShifted * std::pow(2., shift); + const int width = std::ceil(std::log2(range / base)); + return DataFormat(true, width, base, range); + } + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca) { + const tt::Setup* s = ca->setup(); + const DataFormat phiT = makeDataFormat(ca); + const DataFormat inv2R = makeDataFormat(ca); + const double rangeMin = s->baseRegion() + s->maxRphi() * inv2R.range(); + const double range = phiT.base() + s->maxRphi() * inv2R.base(); + const int shift = std::ceil(std::log2(rangeMin / phiT.base())) - s->tmttWidthPhi(); + const double base = phiT.base() * std::pow(2., shift); + const int width = std::ceil(std::log2(range / base)); + return DataFormat(true, width, base, range); + } + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca) { + const tt::Setup* s = ca->setup(); + const DataFormat zT = makeDataFormat(ca); + const DataFormat cot = makeDataFormat(ca); + const double rangeMin = 2. * s->halfLength(); + const double range = zT.base() + s->maxRz() * cot.base(); + const int shift = std::ceil(std::log2(rangeMin / zT.base())) - s->tmttWidthZ(); + const double base = zT.base() * std::pow(2., shift); + const int width = std::ceil(std::log2(range / base)); + return DataFormat(true, width, base, range); + } + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca) { + const tt::Setup* s = ca->setup(); + const DataFormat phi = makeDataFormat(ca); + const DataFormat inv2R = makeDataFormat(ca); + const double range = + .5 * s->pitchRowPS() / s->innerRadius() + .25 * (s->pitchCol2S() + s->scattering()) * inv2R.range(); + const double base = phi.base(); + const int width = std::ceil(std::log2(range / base)); + return DataFormat(false, width, base, range); + } + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca) { + const tt::Setup* s = ca->setup(); + const DataFormat z = makeDataFormat(ca); + const double range = .5 * s->pitchCol2S() * std::sinh(s->maxEta()); + const double base = z.base(); + const int width = std::ceil(std::log2(range / base)); + return DataFormat(false, width, base, range); + } + + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca) { + const DataFormat tfp = makeDataFormat(ca); + const DataFormat tm = makeDataFormat(ca); + const double range = tm.range(); + const double base = tm.base() * std::pow(2., std::floor(std::log2(.5 * tfp.base() / tm.base()))); + const int width = std::ceil(std::log2(range / base)); + return DataFormat(true, width, base, range); + } + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca) { + const DataFormat tfp = makeDataFormat(ca); + const DataFormat tm = makeDataFormat(ca); + const double range = tm.range(); + const double base = tm.base() * std::pow(2., std::floor(std::log2(tfp.base() / tm.base()))); + const int width = std::ceil(std::log2(range / base)); + return DataFormat(true, width, base, range); + } + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca) { + const DataFormat tfp = makeDataFormat(ca); + const DataFormat cot = makeDataFormat(ca); + const DataFormat z = makeDataFormat(ca); + const DataFormat r = makeDataFormat(ca); + const double range = cot.range(); + const double base = z.base() / r.base() * std::pow(2., std::floor(std::log2(tfp.base() / z.base() * r.base()))); + const int width = std::ceil(std::log2(range / base)); + return DataFormat(true, width, base, range); + } + template <> + DataFormat makeDataFormat(const ChannelAssignment* ca) { + const DataFormat tfp = makeDataFormat(ca); + const DataFormat tm = makeDataFormat(ca); + const double range = tm.range(); + const double base = tm.base() * pow(2., std::floor(std::log2(tfp.base() / tm.base()))); + const int width = std::ceil(std::log2(range / base)); + return DataFormat(true, width, base, range); + } + +} // namespace trklet diff --git a/L1Trigger/TrackFindingTracklet/src/DuplicateRemoval.cc b/L1Trigger/TrackFindingTracklet/src/DuplicateRemoval.cc new file mode 100644 index 0000000000000..97769f2a79fe3 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/DuplicateRemoval.cc @@ -0,0 +1,177 @@ +#include "L1Trigger/TrackFindingTracklet/interface/DuplicateRemoval.h" + +#include +#include +#include + +namespace trklet { + + DuplicateRemoval::DuplicateRemoval(const tt::Setup* setup, + const trackerTFP::LayerEncoding* layerEncoding, + const DataFormats* dataFormats, + const ChannelAssignment* channelAssignment, + int region) + : setup_(setup), + layerEncoding_(layerEncoding), + dataFormats_(dataFormats), + channelAssignment_(channelAssignment), + region_(region) { + const DataFormat& r = dataFormats_->format(Variable::r, Process::dr); + const int width = setup_->widthAddrBRAM18() - 1; + const double base = r.base() * pow(2., r.width() - width); + const double range = r.range(); + r_ = DataFormat(true, width, base, range); + tmNumLayers_ = channelAssignment_->tmNumLayers(); + phi_ = dataFormats_->format(Variable::phi, Process::dr); + } + + // read in and organize input tracks and stubs + void DuplicateRemoval::consume(const tt::StreamsTrack& streamsTrack, const tt::StreamsStub& streamsStub) { + auto nonNullTrack = [](int sum, const tt::FrameTrack& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); }; + auto nonNullStub = [](int sum, const tt::FrameStub& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); }; + // count tracks and stubs and reserve corresponding vectors + int sizeStubs(0); + const int offset = region_ * tmNumLayers_; + const tt::StreamTrack& streamTrack = streamsTrack[region_]; + input_.reserve(streamTrack.size()); + const int sizeTracks = std::accumulate(streamTrack.begin(), streamTrack.end(), 0, nonNullTrack); + for (int layer = 0; layer < tmNumLayers_; layer++) { + const tt::StreamStub& streamStub = streamsStub[offset + layer]; + sizeStubs += std::accumulate(streamStub.begin(), streamStub.end(), 0, nonNullStub); + } + tracks_.reserve(sizeTracks); + stubs_.reserve(sizeStubs); + // transform input data into handy structs + for (int frame = 0; frame < static_cast(streamTrack.size()); frame++) { + const tt::FrameTrack& frameTrack = streamTrack[frame]; + if (frameTrack.first.isNull()) { + input_.push_back(nullptr); + continue; + } + // lookup layerEncoding + const TrackTM track(frameTrack, dataFormats_); + const double inv2R = abs(track.inv2R()); + const double zT = abs(track.zT()); + const double cot = zT / setup_->chosenRofZ(); + const std::vector& layerEncoding = layerEncoding_->layerEncoding(zT); + std::vector stubs(tmNumLayers_, nullptr); + TTBV hitPattern(0, setup_->numLayers()); + for (int layer = 0; layer < tmNumLayers_; layer++) { + const tt::FrameStub& frameStub = streamsStub[offset + layer][frame]; + const TTStubRef& ttStubRef = frameStub.first; + if (ttStubRef.isNull()) + continue; + // encode layerId + const int decodedLayerId = + layer + setup_->offsetLayerId() + + (layer < setup_->numBarrelLayer() ? 0 : setup_->offsetLayerDisks() - setup_->numBarrelLayer()); + const auto it = std::find(layerEncoding.begin(), layerEncoding.end(), decodedLayerId); + const int encodedLayerId = + std::min(static_cast(std::distance(layerEncoding.begin(), it)), setup_->numLayers() - 1); + // kill stub on already occupied layer + if (hitPattern.test(encodedLayerId)) + continue; + hitPattern.set(encodedLayerId); + const StubTM stubTM(frameStub, dataFormats_); + const int stubId = stubTM.stubId() / 2; + const bool psTilt = stubTM.stubId() % 2 == 1; + // calculate stub uncertainties + static constexpr int numBarrelPSLayer = 3; + const bool barrel = layer < setup_->numBarrelLayer(); + const bool ps = barrel ? layer < numBarrelPSLayer : psTilt; + const bool tilt = barrel && psTilt; + const double length = .5 * (ps ? setup_->pitchColPS() : setup_->pitchCol2S()); + const double pitch = .5 * (ps ? setup_->pitchRowPS() : setup_->pitchRow2S()); + const double pitchOverR = phi_.digi(pitch / (r_.digi(stubTM.r()) + setup_->chosenRofPhi())); + double lengthZ = length; + double lengthR = 0.; + if (!barrel) { + lengthZ = length * cot; + lengthR = length; + } else if (tilt) { + lengthZ = length * (setup_->tiltApproxSlope() * cot + setup_->tiltApproxIntercept()); + lengthR = .5 * setup_->tiltUncertaintyR(); + } + const double dR = lengthR + .5 * setup_->scattering(); + const double dZ = lengthZ; + const double dPhi = phi_.digi(dR * inv2R) + pitchOverR; + const StubDR stubDR(stubTM, stubTM.r(), stubTM.phi(), stubTM.z(), dPhi, dZ); + stubs_.emplace_back(stubDR.frame(), stubId, encodedLayerId); + stubs[layer] = &stubs_.back(); + } + // kill tracks with not enough layers + if (hitPattern.count() < setup_->kfMinLayers()) { + input_.push_back(nullptr); + continue; + } + tracks_.emplace_back(frameTrack, stubs); + input_.push_back(&tracks_.back()); + } + // remove all gaps between end and last track + for (auto it = input_.end(); it != input_.begin();) + it = (*--it) ? input_.begin() : input_.erase(it); + } + + // fill output products + void DuplicateRemoval::produce(tt::StreamsTrack& streamsTrack, tt::StreamsStub& streamsStub) { + const int offset = region_ * setup_->numLayers(); + // remove duplicated tracks, no merge of stubs, one stub per layer expected + std::vector cms(channelAssignment_->numComparisonModules(), nullptr); + for (Track*& track : input_) { + if (!track) + // gaps propagate through chain and appear in output stream + continue; + for (Track*& trackCM : cms) { + if (!trackCM) { + // tracks used in CMs propagate through chain and do appear in output stream unaltered + trackCM = track; + break; + } + if (equalEnough(track, trackCM)) { + // tracks compared in CMs propagate through chain and appear in output stream as gap if identified as duplicate or unaltered elsewise + track = nullptr; + break; + } + } + } + // remove all gaps between end and last track + for (auto it = input_.end(); it != input_.begin();) + it = (*--it) ? input_.begin() : input_.erase(it); + // store output + tt::StreamTrack& streamTrack = streamsTrack[region_]; + streamTrack.reserve(input_.size()); + for (int layer = 0; layer < setup_->numLayers(); layer++) + streamsStub[offset + layer].reserve(input_.size()); + for (Track* track : input_) { + if (!track) { + streamTrack.emplace_back(tt::FrameTrack()); + for (int layer = 0; layer < setup_->numLayers(); layer++) + streamsStub[offset + layer].emplace_back(tt::FrameStub()); + continue; + } + streamTrack.push_back(track->frame_); + TTBV hitPattern(0, setup_->numLayers()); + for (Stub* stub : track->stubs_) { + if (!stub) + continue; + hitPattern.set(stub->layer_); + streamsStub[offset + stub->layer_].emplace_back(stub->frame_); + } + for (int layer : hitPattern.ids(false)) + streamsStub[offset + layer].emplace_back(tt::FrameStub()); + } + } + + // compares two tracks, returns true if those are considered duplicates + bool DuplicateRemoval::equalEnough(Track* t0, Track* t1) const { + int same(0); + for (int layer = 0; layer < channelAssignment_->tmNumLayers(); layer++) { + Stub* s0 = t0->stubs_[layer]; + Stub* s1 = t1->stubs_[layer]; + if (s0 && s1 && s0->stubId_ == s1->stubId_) + same++; + } + return same >= channelAssignment_->minIdenticalStubs(); + } + +} // namespace trklet diff --git a/L1Trigger/TrackFindingTracklet/src/ES_DataFormats.cc b/L1Trigger/TrackFindingTracklet/src/ES_DataFormats.cc new file mode 100644 index 0000000000000..6cc58920fd5f2 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/ES_DataFormats.cc @@ -0,0 +1,4 @@ +#include "FWCore/Utilities/interface/typelookup.h" +#include "L1Trigger/TrackFindingTracklet/interface/DataFormats.h" + +TYPELOOKUP_DATA_REG(trklet::DataFormats); diff --git a/L1Trigger/TrackFindingTracklet/src/FitTrack.cc b/L1Trigger/TrackFindingTracklet/src/FitTrack.cc index 04c5f565f335f..b0b0b9412da91 100644 --- a/L1Trigger/TrackFindingTracklet/src/FitTrack.cc +++ b/L1Trigger/TrackFindingTracklet/src/FitTrack.cc @@ -1077,10 +1077,10 @@ void FitTrack::execute(deque& streamTrackRaw, } } // convert seed stubs - const string& stubId0 = bestTracklet->innerFPGAStub()->stubindex().str(); + const string& stubId0 = bestTracklet->innerFPGAStub()->phiregionaddressstr(); const L1TStub* stub0 = bestTracklet->innerFPGAStub()->l1tstub(); streamsStubRaw[ihit++].emplace_back(seedType, *stub0, valid + stubId0); - const string& stubId1 = bestTracklet->outerFPGAStub()->stubindex().str(); + const string& stubId1 = bestTracklet->outerFPGAStub()->phiregionaddressstr(); const L1TStub* stub1 = bestTracklet->outerFPGAStub()->l1tstub(); streamsStubRaw[ihit++].emplace_back(seedType, *stub1, valid + stubId1); // fill all layers that have no stubs with gaps diff --git a/L1Trigger/TrackFindingTracklet/src/HitPatternHelper.cc b/L1Trigger/TrackFindingTracklet/src/HitPatternHelper.cc index 9ff54c3d35aeb..8f3ca57a62443 100644 --- a/L1Trigger/TrackFindingTracklet/src/HitPatternHelper.cc +++ b/L1Trigger/TrackFindingTracklet/src/HitPatternHelper.cc @@ -13,21 +13,15 @@ namespace hph { - Setup::Setup(const edm::ParameterSet& iConfig, + Setup::Setup(const Config& iConfig, const tt::Setup& setupTT, const trackerTFP::DataFormats& dataFormats, const trackerTFP::LayerEncoding& layerEncoding) - : iConfig_(iConfig), - oldKFPSet_(iConfig.getParameter("oldKFPSet")), - setupTT_(setupTT), - dataFormats_(dataFormats), - dfcot_(dataFormats_.format(trackerTFP::Variable::cot, trackerTFP::Process::kfin)), - dfzT_(dataFormats_.format(trackerTFP::Variable::zT, trackerTFP::Process::kfin)), - layerEncoding_(layerEncoding), - hphDebug_(iConfig.getParameter("hphDebug")), - useNewKF_(iConfig.getParameter("useNewKF")), - chosenRofZNewKF_(setupTT_.chosenRofZ()), - etaRegionsNewKF_(setupTT_.boundarieEta()), + : setupTT_(&setupTT), + layerEncoding_(&layerEncoding), + hphDebug_(iConfig.hphDebug_), + useNewKF_(iConfig.useNewKF_), + chosenRofZNewKF_(setupTT_->chosenRofZ()), layermap_(), nEtaRegions_(tmtt::KFbase::nEta_ / 2), nKalmanLayers_(tmtt::KFbase::nKFlayer_) { @@ -35,8 +29,8 @@ namespace hph { chosenRofZ_ = chosenRofZNewKF_; etaRegions_ = etaRegionsNewKF_; } else { - chosenRofZ_ = oldKFPSet_.getParameter("ChosenRofZ"); - etaRegions_ = oldKFPSet_.getParameter>("EtaRegions"); + chosenRofZ_ = iConfig.chosenRofZ_; + etaRegions_ = iConfig.etaRegions_; } static constexpr auto layerIds = {1, 2, 3, 4, 5, 6, 11, 12, 13, 14, 15}; //layer ID 11~15 correspond to D1~D5 // Converting tmtt::KFbase::layerMap_ to a format that is acceptatble by HitPatternHelper @@ -62,11 +56,8 @@ namespace hph { etaRegions_(setup_->etaRegions()), layermap_(setup_->layermap()), nKalmanLayers_(setup_->nKalmanLayers()), - etaBin_(setup_->etaRegion(z0, cot, true)), - cotBin_(setup_->digiCot(cot, etaBin_)), - zTBin_(setup_->digiZT(z0, cot, etaBin_)), - layerEncoding_(setup->layerEncoding(etaBin_, zTBin_, cotBin_)), - layerEncodingMap_(setup->layerEncodingMap(etaBin_, zTBin_, cotBin_)), + zT_(z0 + cot * setup_->chosenRofZ()), + layerEncoding_(setup->layerEncoding(zT_)), numExpLayer_(layerEncoding_.size()), hitpattern_(hitpattern), etaSector_(setup_->etaRegion(z0, cot, useNewKF_)), @@ -79,6 +70,7 @@ namespace hph { numMissingInterior2_(0), binary_(11, 0), //there are 11 unique layer IDs, as defined in variable "layerIds" bonusFeatures_() { + setup->analyze(hitpattern, cot, z0, numPS_, num2S_, numMissingPS_, numMissing2S_); int kf_eta_reg = etaSector_; if (kf_eta_reg < ((int)etaRegions_.size() - 1) / 2) { kf_eta_reg = ((int)etaRegions_.size() - 1) / 2 - 1 - kf_eta_reg; @@ -139,23 +131,11 @@ namespace hph { if (hphDebug_) { edm::LogVerbatim("TrackTriggerHPH") << "Layer found in hitpattern"; } - binary_[reducedId(layerEncoding_[i])] = 1; - if (layerEncodingMap_[layerEncoding_[i]]->psModule()) { - numPS_++; - } else { - num2S_++; - } } else { if (hphDebug_) { edm::LogVerbatim("TrackTriggerHPH") << "Layer missing in hitpattern"; } - - if (layerEncodingMap_[layerEncoding_[i]]->psModule()) { - numMissingPS_++; - } else { - numMissing2S_++; - } } } @@ -205,23 +185,11 @@ namespace hph { if (hphDebug_) { edm::LogVerbatim("TrackTriggerHPH") << "Layer found in hitpattern"; } - binary_[reducedId(j)] = 1; - if (layerEncodingMap_[layerEncoding_[k]]->psModule()) { - numPS_++; - } else { - num2S_++; - } } else { if (hphDebug_) { edm::LogVerbatim("TrackTriggerHPH") << "Layer missing in hitpattern"; } - - if (layerEncodingMap_[layerEncoding_[k]]->psModule()) { - numMissingPS_++; - } else { - numMissing2S_++; - } } } } @@ -258,17 +226,6 @@ namespace hph { return kf_eta_reg; } - int Setup::digiCot(double cot, int binEta) const { - double cotLocal = dfcot_.digi(cot - setupTT_.sectorCot(binEta)); - return dfcot_.toUnsigned(dfcot_.integer(cotLocal)); - } - - int Setup::digiZT(double z0, double cot, int binEta) const { - double zT = z0 + setupTT_.chosenRofZ() * cot; - double zTLocal = dfzT_.digi(zT - setupTT_.sectorCot(binEta) * setupTT_.chosenRofZ()); - return dfzT_.toUnsigned(dfzT_.integer(zTLocal)); - } - int HitPatternHelper::reducedId(int layerId) { if (hphDebug_ && (layerId > 15 || layerId < 1)) { edm::LogVerbatim("TrackTriggerHPH") << "Warning: invalid layer id !"; diff --git a/L1Trigger/TrackFindingTracklet/src/KFin.cc b/L1Trigger/TrackFindingTracklet/src/KFin.cc deleted file mode 100644 index c5cbc3d469648..0000000000000 --- a/L1Trigger/TrackFindingTracklet/src/KFin.cc +++ /dev/null @@ -1,270 +0,0 @@ -#include "L1Trigger/TrackFindingTracklet/interface/KFin.h" - -#include -#include -#include - -using namespace std; -using namespace edm; -using namespace tt; -using namespace trackerTFP; - -namespace trklet { - - KFin::KFin(const ParameterSet& iConfig, - const Setup* setup, - const DataFormats* dataFormats, - const LayerEncoding* layerEncoding, - const ChannelAssignment* channelAssignment, - int region) - : enableTruncation_(iConfig.getParameter("EnableTruncation")), - setup_(setup), - dataFormats_(dataFormats), - layerEncoding_(layerEncoding), - channelAssignment_(channelAssignment), - region_(region), - input_(channelAssignment_->numNodesDR()) {} - - // read in and organize input tracks and stubs - void KFin::consume(const StreamsTrack& streamsTrack, const StreamsStub& streamsStub) { - const int offsetTrack = region_ * channelAssignment_->numNodesDR(); - auto nonNullTrack = [](int sum, const FrameTrack& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); }; - auto nonNullStub = [](int sum, const FrameStub& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); }; - // count tracks and stubs and reserve corresponding vectors - int sizeTracks(0); - int sizeStubs(0); - for (int channel = 0; channel < channelAssignment_->numNodesDR(); channel++) { - const int streamTrackId = offsetTrack + channel; - const int offsetStub = streamTrackId * setup_->numLayers(); - const StreamTrack& streamTrack = streamsTrack[streamTrackId]; - input_[channel].reserve(streamTrack.size()); - sizeTracks += accumulate(streamTrack.begin(), streamTrack.end(), 0, nonNullTrack); - for (int layer = 0; layer < setup_->numLayers(); layer++) { - const StreamStub& streamStub = streamsStub[offsetStub + layer]; - sizeStubs += accumulate(streamStub.begin(), streamStub.end(), 0, nonNullStub); - } - } - tracks_.reserve(sizeTracks); - stubs_.reserve(sizeStubs); - // transform input data into handy structs - for (int channel = 0; channel < channelAssignment_->numNodesDR(); channel++) { - vector& input = input_[channel]; - const int streamTrackId = offsetTrack + channel; - const int offsetStub = streamTrackId * setup_->numLayers(); - const StreamTrack& streamTrack = streamsTrack[streamTrackId]; - for (int frame = 0; frame < (int)streamTrack.size(); frame++) { - const FrameTrack& frameTrack = streamTrack[frame]; - if (frameTrack.first.isNull()) { - input.push_back(nullptr); - continue; - } - vector stubs; - stubs.reserve(setup_->numLayers()); - for (int layer = 0; layer < setup_->numLayers(); layer++) { - const FrameStub& frameStub = streamsStub[offsetStub + layer][frame]; - if (frameStub.first.isNull()) - continue; - TTBV ttBV = frameStub.second; - const TTBV zBV(ttBV, dataFormats_->format(Variable::z, Process::kfin).width(), 0, true); - ttBV >>= dataFormats_->format(Variable::z, Process::kfin).width(); - const TTBV phiBV(ttBV, dataFormats_->format(Variable::phi, Process::kfin).width(), 0, true); - ttBV >>= dataFormats_->format(Variable::phi, Process::kfin).width(); - const TTBV rBV(ttBV, dataFormats_->format(Variable::r, Process::kfin).width(), 0, true); - ttBV >>= dataFormats_->format(Variable::r, Process::kfin).width(); - const TTBV layerIdBV(ttBV, channelAssignment_->widthLayerId(), 0); - ttBV >>= channelAssignment_->widthPSTilt(); - const TTBV tiltBV(ttBV, channelAssignment_->widthPSTilt(), 0); - const double r = rBV.val(dataFormats_->base(Variable::r, Process::kfin)); - const double phi = phiBV.val(dataFormats_->base(Variable::phi, Process::kfin)); - const double z = zBV.val(dataFormats_->base(Variable::z, Process::kfin)); - stubs_.emplace_back(frameStub.first, r, phi, z, layerIdBV.val(), tiltBV.val(), layer); - stubs.push_back(&stubs_.back()); - } - TTBV ttBV = frameTrack.second; - const TTBV cotBV(ttBV, dataFormats_->format(Variable::cot, Process::kfin).width(), 0, true); - ttBV >>= dataFormats_->format(Variable::cot, Process::kfin).width(); - const TTBV zTBV(ttBV, dataFormats_->format(Variable::zT, Process::kfin).width(), 0, true); - ttBV >>= dataFormats_->format(Variable::zT, Process::kfin).width(); - const TTBV phiTBV(ttBV, dataFormats_->format(Variable::phiT, Process::kfin).width(), 0, true); - ttBV >>= dataFormats_->format(Variable::phiT, Process::kfin).width(); - const TTBV inv2RBV(ttBV, dataFormats_->format(Variable::inv2R, Process::kfin).width(), 0, true); - ttBV >>= dataFormats_->format(Variable::inv2R, Process::kfin).width(); - const TTBV sectorEtaBV(ttBV, dataFormats_->format(Variable::sectorEta, Process::kfin).width(), 0); - ttBV >>= dataFormats_->format(Variable::sectorEta, Process::kfin).width(); - const TTBV sectorPhiBV(ttBV, dataFormats_->format(Variable::sectorPhi, Process::kfin).width(), 0); - const double cot = cotBV.val(dataFormats_->base(Variable::cot, Process::kfin)); - const double zT = zTBV.val(dataFormats_->base(Variable::zT, Process::kfin)); - const double inv2R = inv2RBV.val(dataFormats_->base(Variable::inv2R, Process::kfin)); - const int sectorEta = sectorEtaBV.val(); - const int zTu = dataFormats_->format(Variable::zT, Process::kfin).toUnsigned(zT); - const int cotu = dataFormats_->format(Variable::cot, Process::kfin).toUnsigned(cot); - const TTBV maybe = layerEncoding_->maybePattern(sectorEta, zTu, cotu); - const FrameTrack frameT(frameTrack.first, - Frame("1" + maybe.str() + sectorPhiBV.str() + sectorEtaBV.str() + phiTBV.str() + - inv2RBV.str() + zTBV.str() + cotBV.str())); - tracks_.emplace_back(frameT, stubs, cot, zT, inv2R, sectorEtaBV.val()); - input.push_back(&tracks_.back()); - } - // remove all gaps between end and last track - for (auto it = input.end(); it != input.begin();) - it = (*--it) ? input.begin() : input.erase(it); - } - } - - // fill output products - void KFin::produce(StreamsStub& accpetedStubs, - StreamsTrack& acceptedTracks, - StreamsStub& lostStubs, - StreamsTrack& lostTracks) { - // calculate stub uncertainties - static constexpr int usedMSBpitchOverRaddr = 1; - static const double baseRlut = - dataFormats_->base(Variable::r, Process::kfin) * - pow(2, dataFormats_->width(Variable::r, Process::zht) - setup_->widthAddrBRAM18() + usedMSBpitchOverRaddr); - static const double baseRinvR = dataFormats_->base(Variable::r, Process::kfin) * - pow(2, dataFormats_->width(Variable::r, Process::zht) - setup_->widthAddrBRAM18()); - static const double basePhi = - dataFormats_->base(Variable::inv2R, Process::kfin) * dataFormats_->base(Variable::r, Process::kfin); - static const double baseInvR = - pow(2., - ceil(log2(dataFormats_->base(Variable::r, Process::kfin) / setup_->tbInnerRadius())) - - setup_->widthDSPbu()) / - dataFormats_->base(Variable::r, Process::kfin); - static const double maxCot = sinh(setup_->maxEta()) + setup_->beamWindowZ() / setup_->chosenRofZ(); - static constexpr int usedMSBCotLutaddr = 3; - static const double baseCotLut = pow(2., ceil(log2(maxCot)) - setup_->widthAddrBRAM18() + usedMSBCotLutaddr); - static const double baseCot = dataFormats_->base(Variable::cot, Process::kfin); - static const double baseZ = dataFormats_->base(Variable::z, Process::kfin); - static const double baseR = dataFormats_->base(Variable::r, Process::kfin); - for (const Track& track : tracks_) { - const int sectorEta = track.sectorEta_; - const double inv2R = abs(track.inv2R_); - for (Stub* stub : track.stubs_) { - const bool barrel = setup_->barrel(stub->ttStubRef_); - const bool ps = barrel ? setup_->psModule(stub->ttStubRef_) : stub->psTilt_; - const bool tilt = barrel ? (ps && !stub->psTilt_) : false; - const double length = ps ? setup_->lengthPS() : setup_->length2S(); - const double pitch = ps ? setup_->pitchPS() : setup_->pitch2S(); - const double pitchOverR = digi(pitch / (digi(stub->r_, baseRlut) + dataFormats_->chosenRofPhi()), basePhi); - const double r = digi(stub->r_, baseRinvR) + dataFormats_->chosenRofPhi(); - const double sumdz = track.zT_ + stub->z_; - const double dZ = digi(sumdz - digi(setup_->chosenRofZ(), baseR) * track.cot_, baseCot * baseR); - const double sumcot = track.cot_ + digi(setup_->sectorCot(sectorEta), baseCot); - const double cot = digi(abs(dZ * digi(1. / r, baseInvR) + sumcot), baseCotLut); - double lengthZ = length; - double lengthR = 0.; - if (!barrel) { - lengthZ = length * cot; - lengthR = length; - } else if (tilt) { - lengthZ = length * abs(setup_->tiltApproxSlope() * cot + setup_->tiltApproxIntercept()); - lengthR = setup_->tiltUncertaintyR(); - } - const double scat = digi(setup_->scattering(), baseR); - stub->dZ_ = lengthZ + baseZ; - stub->dPhi_ = (scat + digi(lengthR, baseR)) * inv2R + pitchOverR; - stub->dPhi_ = digi(stub->dPhi_, basePhi) + basePhi; - } - } - // store helper - auto frameTrack = [](Track* track) { return track->frame_; }; - auto frameStub = [this](Track* track, int layer) { - auto equal = [layer](Stub* stub) { return stub->channel_ == layer; }; - const auto it = find_if(track->stubs_.begin(), track->stubs_.end(), equal); - if (it == track->stubs_.end()) - return FrameStub(); - Stub* stub = *it; - const TTBV r(dataFormats_->format(Variable::r, Process::kfin).ttBV(stub->r_)); - const TTBV phi(dataFormats_->format(Variable::phi, Process::kfin).ttBV(stub->phi_)); - const TTBV z(dataFormats_->format(Variable::z, Process::kfin).ttBV(stub->z_)); - const TTBV dPhi(dataFormats_->format(Variable::dPhi, Process::kfin).ttBV(stub->dPhi_)); - const TTBV dZ(dataFormats_->format(Variable::dZ, Process::kfin).ttBV(stub->dZ_)); - return FrameStub(stub->ttStubRef_, Frame("1" + r.str() + phi.str() + z.str() + dPhi.str() + dZ.str())); - }; - // merge number of nodes DR to number of Nodes KF and store result - static const int nMux = channelAssignment_->numNodesDR() / setup_->kfNumWorker(); - const int offsetTrack = region_ * setup_->kfNumWorker(); - for (int nodeKF = 0; nodeKF < setup_->kfNumWorker(); nodeKF++) { - const int offset = nodeKF * nMux; - deque accepted; - deque lost; - vector> stacks(nMux); - vector> inputs(nMux); - for (int channel = 0; channel < nMux; channel++) { - const vector& input = input_[offset + channel]; - inputs[channel] = deque(input.begin(), input.end()); - } - // clock accurate firmware emulation, each while trip describes one clock tick, one stub in and one stub out per tick - while (!all_of(inputs.begin(), inputs.end(), [](const deque& tracks) { return tracks.empty(); }) or - !all_of(stacks.begin(), stacks.end(), [](const deque& tracks) { return tracks.empty(); })) { - // fill input fifos - for (int channel = 0; channel < nMux; channel++) { - deque& stack = stacks[channel]; - Track* track = pop_front(inputs[channel]); - if (track) - stack.push_back(track); - } - // merge input fifos to one stream, prioritizing higher input channel over lower channel - bool nothingToRoute(true); - for (int channel = nMux - 1; channel >= 0; channel--) { - Track* track = pop_front(stacks[channel]); - if (track) { - nothingToRoute = false; - accepted.push_back(track); - break; - } - } - if (nothingToRoute) - accepted.push_back(nullptr); - } - // truncate if desired - if (enableTruncation_ && (int)accepted.size() > setup_->numFrames()) { - const auto limit = next(accepted.begin(), setup_->numFrames()); - copy_if(limit, accepted.end(), back_inserter(lost), [](const Track* track) { return track; }); - accepted.erase(limit, accepted.end()); - } - // remove all gaps between end and last track - for (auto it = accepted.end(); it != accepted.begin();) - it = (*--it) ? accepted.begin() : accepted.erase(it); - // fill products StreamsStub& accpetedStubs, StreamsTrack& acceptedTracks, StreamsStub& lostStubs, StreamsTrack& lostTracks - const int channelTrack = offsetTrack + nodeKF; - const int offsetStub = channelTrack * setup_->numLayers(); - // fill lost tracks and stubs without gaps - lostTracks[channelTrack].reserve(lost.size()); - for (int layer = 0; layer < setup_->numLayers(); layer++) - lostStubs[offsetStub + layer].reserve(lost.size()); - for (Track* track : lost) { - lostTracks[channelTrack].emplace_back(frameTrack(track)); - for (int layer = 0; layer < setup_->numLayers(); layer++) - lostStubs[offsetStub + layer].emplace_back(frameStub(track, layer)); - } - // fill accepted tracks and stubs with gaps - acceptedTracks[channelTrack].reserve(accepted.size()); - for (int layer = 0; layer < setup_->numLayers(); layer++) - accpetedStubs[offsetStub + layer].reserve(accepted.size()); - for (Track* track : accepted) { - if (!track) { // fill gap - acceptedTracks[channelTrack].emplace_back(FrameTrack()); - for (int layer = 0; layer < setup_->numLayers(); layer++) - accpetedStubs[offsetStub + layer].emplace_back(FrameStub()); - continue; - } - acceptedTracks[channelTrack].emplace_back(frameTrack(track)); - for (int layer = 0; layer < setup_->numLayers(); layer++) - accpetedStubs[offsetStub + layer].emplace_back(frameStub(track, layer)); - } - } - } - - // remove and return first element of deque, returns nullptr if empty - template - T* KFin::pop_front(deque& ts) const { - T* t = nullptr; - if (!ts.empty()) { - t = ts.front(); - ts.pop_front(); - } - return t; - } - -} // namespace trklet diff --git a/L1Trigger/TrackFindingTracklet/src/KalmanFilter.cc b/L1Trigger/TrackFindingTracklet/src/KalmanFilter.cc new file mode 100644 index 0000000000000..57dc64f981e13 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/KalmanFilter.cc @@ -0,0 +1,698 @@ +#include "L1Trigger/TrackFindingTracklet/interface/KalmanFilter.h" +#include "L1Trigger/TrackFindingTMTT/interface/L1track3D.h" +#include "L1Trigger/TrackFindingTMTT/interface/Stub.h" +#include "L1Trigger/TrackFindingTMTT/interface/L1fittedTrack.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace trklet { + + KalmanFilter::KalmanFilter(const tt::Setup* setup, + const DataFormats* dataFormats, + KalmanFilterFormats* kalmanFilterFormats, + tmtt::Settings* settings, + tmtt::KFParamsComb* tmtt, + int region, + tt::TTTracks& ttTracks) + : setup_(setup), + dataFormats_(dataFormats), + kalmanFilterFormats_(kalmanFilterFormats), + settings_(settings), + tmtt_(tmtt), + region_(region), + ttTracks_(ttTracks), + layer_(0) { + zTs_.reserve(settings_->etaRegions().size()); + for (double eta : settings_->etaRegions()) + zTs_.emplace_back(std::sinh(eta) * settings_->chosenRofZ()); + } + + // read in and organize input tracks and stubs + void KalmanFilter::consume(const tt::StreamsTrack& streamsTrack, const tt::StreamsStub& streamsStub) { + const int offset = region_ * setup_->numLayers(); + const tt::StreamTrack& streamTrack = streamsTrack[region_]; + const int numTracks = + std::accumulate(streamTrack.begin(), streamTrack.end(), 0, [](int sum, const tt::FrameTrack& f) { + return sum + (f.first.isNull() ? 0 : 1); + }); + int numStubs(0); + for (int layer = 0; layer < setup_->numLayers(); layer++) { + const tt::StreamStub& streamStub = streamsStub[offset + layer]; + numStubs += std::accumulate(streamStub.begin(), streamStub.end(), 0, [](int sum, const tt::FrameStub& f) { + return sum + (f.first.isNull() ? 0 : 1); + }); + } + tracks_.reserve(numTracks); + stubs_.reserve(numStubs); + int trackId(0); + for (int frame = 0; frame < static_cast(streamTrack.size()); frame++) { + const tt::FrameTrack& frameTrack = streamTrack[frame]; + if (frameTrack.first.isNull()) { + stream_.push_back(nullptr); + continue; + } + tracks_.emplace_back(frameTrack, dataFormats_); + TrackDR* track = &tracks_.back(); + std::vector stubs(setup_->numLayers(), nullptr); + TTBV hitPattern(0, setup_->numLayers()); + for (int layer = 0; layer < setup_->numLayers(); layer++) { + const tt::FrameStub& frameStub = streamsStub[offset + layer][frame]; + if (frameStub.first.isNull()) + continue; + stubs_.emplace_back(kalmanFilterFormats_, frameStub); + stubs[layer] = &stubs_.back(); + hitPattern.set(layer); + } + if (hitPattern.count(0, setup_->kfMaxSeedingLayer()) < setup_->kfNumSeedStubs()) { + stream_.push_back(nullptr); + continue; + } + states_.emplace_back(kalmanFilterFormats_, track, stubs, trackId++); + stream_.push_back(&states_.back()); + if (setup_->enableTruncation() && trackId == setup_->kfMaxTracks()) + break; + } + } + + // call old KF + void KalmanFilter::simulate(tt::StreamsStub& streamsStub, tt::StreamsTrack& streamsTrack) { + // prep finals_ where old KF tracks will be stored + finals_.reserve(states_.size()); + for (const State& state : states_) { + // convert tracks to by old KF expected data formats + TrackDR* trackFound = state.track(); + const TTTrackRef& ttTrackRef = trackFound->frame().first; + const double qOverPt = -trackFound->inv2R() / setup_->invPtToDphi(); + const double phi0 = tt::deltaPhi(trackFound->phiT() - setup_->chosenRofPhi() * trackFound->inv2R() + + region_ * setup_->baseRegion()); + const double tanLambda = trackFound->zT() / setup_->chosenRofZ(); + static constexpr double z0 = 0; + static constexpr double helixD0 = 0.; + // convert stubs to by old KF expected data formats + std::vector stubs; + std::vector stubsFound; + stubs.reserve(state.trackPattern().count()); + stubsFound.reserve(state.trackPattern().count()); + const std::vector& stubsState = state.stubs(); + for (int layer = 0; layer < setup_->numLayers(); layer++) { + if (!stubsState[layer]) + continue; + const StubDR& stub = stubsState[layer]->stubDR_; + const TTStubRef& ttStubRef = stub.frame().first; + tt::SensorModule* sensorModule = setup_->sensorModule(ttStubRef); + // convert position + double r, phi, z; + if (setup_->kfUseTTStubResiduals()) { + const GlobalPoint gp = setup_->stubPos(ttStubRef); + r = gp.perp(); + phi = gp.phi(); + z = gp.z(); + } else { + r = stub.r() + setup_->chosenRofPhi(); + phi = tt::deltaPhi(stub.phi() + trackFound->phiT() + stub.r() * trackFound->inv2R() + + region_ * setup_->baseRegion()); + z = stub.z() + trackFound->zT() + (r - setup_->chosenRofZ()) * tanLambda; + } + // convert stub layer id (barrel: 1 - 6, endcap: 11 - 15) to reduced layer id (0 - 6) + int layerId = setup_->layerId(ttStubRef); + if (layerId > 10 && z < 0.) + layerId += 10; + int layerIdReduced = setup_->layerId(ttStubRef); + if (layerIdReduced == 6) + layerIdReduced = 11; + else if (layerIdReduced == 5) + layerIdReduced = 12; + else if (layerIdReduced == 4) + layerIdReduced = 13; + else if (layerIdReduced == 3) + layerIdReduced = 15; + if (layerIdReduced > 10) + layerIdReduced -= 8; + const double stripPitch = sensorModule->pitchRow(); + const double stripLength = sensorModule->pitchCol(); + const bool psModule = sensorModule->psModule(); + const bool barrel = sensorModule->barrel(); + const bool tiltedBarrel = sensorModule->tilted(); + stubs.emplace_back( + ttStubRef, r, phi, z, layerId, layerIdReduced, stripPitch, stripLength, psModule, barrel, tiltedBarrel); + stubsFound.push_back(&stubs.back()); + } + // determine phi and eta region + const int iPhiSec = region_; + const double zTtrack = ttTrackRef->z0() + settings_->chosenRofZ() * ttTrackRef->tanL(); + int iEtaReg = 0; + for (; iEtaReg < 15; iEtaReg++) + if (zTtrack < zTs_[iEtaReg + 1]) + break; + const tmtt::L1track3D l1track3D(settings_, stubsFound, qOverPt, phi0, z0, tanLambda, helixD0, iPhiSec, iEtaReg); + // perform fit + const tmtt::L1fittedTrack trackFitted(tmtt_->fit(l1track3D)); + if (!trackFitted.accepted()) + continue; + // convert olf kf fitted track format into emulator format + static constexpr int trackId = 0; + static constexpr int numConsistent = 0; + static constexpr int numConsistentPS = 0; + const double inv2R = -trackFitted.qOverPt() * setup_->invPtToDphi(); + const double phiT = + tt::deltaPhi(trackFitted.phi0() + inv2R * setup_->chosenRofPhi() - region_ * setup_->baseRegion()); + const double cot = trackFitted.tanLambda(); + const double zT = trackFitted.z0() + cot * setup_->chosenRofZ(); + // check for bit overflows + if (!dataFormats_->format(Variable::inv2R, Process::kf).inRange(inv2R, true)) + continue; + if (!dataFormats_->format(Variable::phiT, Process::kf).inRange(phiT, true)) + continue; + if (!dataFormats_->format(Variable::cot, Process::kf).inRange(cot, true)) + continue; + if (!dataFormats_->format(Variable::zT, Process::kf).inRange(zT, true)) + continue; + const double d0 = trackFitted.d0(); + const double x0 = inv2R - trackFound->inv2R(); + const double x1 = phiT - trackFound->phiT(); + const double x2 = cot - tanLambda; + const double x3 = zT - trackFound->zT(); + const double x4 = d0; + // get intput stubs and convert to emulator format + TTBV hitPattern(0, setup_->numLayers()); + std::vector stubsKF; + stubsKF.reserve(setup_->numLayers()); + for (tmtt::Stub* stub : trackFitted.stubs()) { + if (!stub) + continue; + // get stub + const auto it = std::find_if(stubsState.begin(), stubsState.end(), [stub](Stub* state) { + return state && (stub->ttStubRef() == state->stubDR_.frame().first); + }); + const StubDR& s = (*it)->stubDR_; + // convert position relative to track + const double r = s.r(); + const double r0 = r + setup_->chosenRofPhi(); + const double phi = s.phi() - (x1 + r * x0 + x4 / r0); + const double z = s.z() - (x3 + (r0 - setup_->chosenRofZ()) * x2); + const double dPhi = s.dPhi(); + const double dZ = s.dZ(); + const int layer = std::distance(stubsState.begin(), it); + // check for bit overflows + if (!dataFormats_->format(Variable::phi, Process::kf).inRange(phi, true)) + continue; + if (!dataFormats_->format(Variable::z, Process::kf).inRange(z, true)) + continue; + hitPattern.set(layer); + stubsKF.emplace_back(s, r, phi, z, dPhi, dZ); + } + // check if enough stubs left to form a track + if (hitPattern.count() < setup_->kfMinLayers()) + continue; + // store track + const TrackKF trackKF(*trackFound, inv2R, phiT, cot, zT); + finals_.emplace_back(trackId, numConsistent, numConsistentPS, d0, hitPattern, trackKF, stubsKF); + } + conv(streamsStub, streamsTrack); + } + + // fill output products + void KalmanFilter::produce(tt::StreamsStub& streamsStub, + tt::StreamsTrack& streamsTrack, + int& numAcceptedStates, + int& numLostStates) { + if (setup_->kfUseSimmulation()) + return simulate(streamsStub, streamsTrack); + // 5 parameter fit simulation + if (setup_->kfUse5ParameterFit()) { + // Propagate state to each layer in turn, updating it with all viable stub combinations there, using KF maths + for (layer_ = 0; layer_ < setup_->numLayers(); layer_++) + addLayer(); + } else { // 4 parameter fit emulation + // seed building + for (layer_ = 0; layer_ < setup_->kfMaxSeedingLayer(); layer_++) + addLayer(true); + // calulcate seed parameter + calcSeeds(); + // Propagate state to each layer in turn, updating it with all viable stub combinations there, using KF maths + for (layer_ = setup_->kfNumSeedStubs(); layer_ < setup_->numLayers(); layer_++) + addLayer(); + } + // count total number of final states + const int nStates = + std::accumulate(stream_.begin(), stream_.end(), 0, [](int sum, State* state) { return sum + (state ? 1 : 0); }); + // apply truncation + if (setup_->enableTruncation() && static_cast(stream_.size()) > setup_->numFramesHigh()) + stream_.resize(setup_->numFramesHigh()); + // cycle event, remove gaps + stream_.erase(std::remove(stream_.begin(), stream_.end(), nullptr), stream_.end()); + // store number of states which got taken into account + numAcceptedStates += stream_.size(); + // store number of states which got not taken into account due to truncation + numLostStates += nStates - stream_.size(); + // apply final cuts + finalize(); + // best track per candidate selection + accumulator(); + // Transform States into output products + conv(streamsStub, streamsTrack); + } + + // apply final cuts + void KalmanFilter::finalize() { + finals_.reserve(stream_.size()); + for (State* state : stream_) { + int numConsistent(0); + int numConsistentPS(0); + TTBV hitPattern = state->hitPattern(); + std::vector stubsKF; + stubsKF.reserve(setup_->numLayers()); + // stub residual cut + State* s = state; + while ((s = s->parent())) { + const double dPhi = state->x1() + s->H00() * state->x0() + state->x4() / s->H04(); + const double dZ = state->x3() + s->H12() * state->x2(); + const double phi = digi(VariableKF::m0, s->m0() - dPhi); + const double z = digi(VariableKF::m1, s->m1() - dZ); + const bool validPhi = dataFormats_->format(Variable::phi, Process::kf).inRange(phi); + const bool validZ = dataFormats_->format(Variable::z, Process::kf).inRange(z); + if (validPhi && validZ) { + const double r = s->H00(); + const double dPhi = s->d0(); + const double dZ = s->d1(); + const StubDR& stubDR = s->stub()->stubDR_; + stubsKF.emplace_back(stubDR, r, phi, z, dPhi, dZ); + if (abs(phi) <= dPhi && abs(z) <= dZ) { + numConsistent++; + if (setup_->psModule(stubDR.frame().first)) + numConsistentPS++; + } + } else + hitPattern.reset(s->layer()); + } + std::reverse(stubsKF.begin(), stubsKF.end()); + // layer cut + bool validLayers = hitPattern.count() >= setup_->kfMinLayers(); + // track parameter cuts + const double cotTrack = + dataFormats_->format(Variable::cot, Process::kf).digi(state->track()->zT() / setup_->chosenRofZ()); + const double inv2R = state->x0() + state->track()->inv2R(); + const double phiT = state->x1() + state->track()->phiT(); + const double cot = state->x2() + cotTrack; + const double zT = state->x3() + state->track()->zT(); + const double d0 = state->x4(); + // pt cut + const bool validX0 = dataFormats_->format(Variable::inv2R, Process::kf).inRange(inv2R); + // cut on phi sector boundaries + const bool validX1 = abs(phiT) < setup_->baseRegion() / 2.; + // cot cut + const bool validX2 = dataFormats_->format(Variable::cot, Process::kf).inRange(cot); + // zT cut + const bool validX3 = dataFormats_->format(Variable::zT, Process::kf).inRange(zT); + if (!validLayers || !validX0 || !validX1 || !validX2 || !validX3) + continue; + const int trackId = state->trackId(); + const TrackKF trackKF(*state->track(), inv2R, phiT, cot, zT); + finals_.emplace_back(trackId, numConsistent, numConsistentPS, d0, hitPattern, trackKF, stubsKF); + } + } + + // best state selection + void KalmanFilter::accumulator() { + // create container of pointer to make sorts less CPU intense + std::vector finals; + finals.reserve(finals_.size()); + std::transform(finals_.begin(), finals_.end(), std::back_inserter(finals), [](Track& track) { return &track; }); + // prepare arrival order + std::vector trackIds; + trackIds.reserve(tracks_.size()); + for (Track* track : finals) { + const int trackId = track->trackId_; + if (std::find_if(trackIds.begin(), trackIds.end(), [trackId](int id) { return id == trackId; }) == trackIds.end()) + trackIds.push_back(trackId); + } + // sort in number of consistent stubs + auto moreConsistentLayers = [](Track* lhs, Track* rhs) { return lhs->numConsistent_ > rhs->numConsistent_; }; + std::stable_sort(finals.begin(), finals.end(), moreConsistentLayers); + // sort in number of consistent ps stubs + auto moreConsistentLayersPS = [](Track* lhs, Track* rhs) { return lhs->numConsistentPS_ > rhs->numConsistentPS_; }; + std::stable_sort(finals.begin(), finals.end(), moreConsistentLayersPS); + // sort in track id as arrived + auto order = [&trackIds](auto lhs, auto rhs) { + const auto l = find(trackIds.begin(), trackIds.end(), lhs->trackId_); + const auto r = find(trackIds.begin(), trackIds.end(), rhs->trackId_); + return std::distance(r, l) < 0; + }; + std::stable_sort(finals.begin(), finals.end(), order); + // keep first state (best due to previous sorts) per track id + const auto it = std::unique( + finals.begin(), finals.end(), [](Track* lhs, Track* rhs) { return lhs->trackId_ == rhs->trackId_; }); + finals.erase(it, finals.end()); + // apply to actual track container + int i(0); + for (Track* track : finals) + finals_[i++] = *track; + finals_.resize(i); + } + + // Transform States into output products + void KalmanFilter::conv(tt::StreamsStub& streamsStub, tt::StreamsTrack& streamsTrack) { + const int offset = region_ * setup_->numLayers(); + tt::StreamTrack& streamTrack = streamsTrack[region_]; + streamTrack.reserve(stream_.size()); + for (int layer = 0; layer < setup_->numLayers(); layer++) + streamsStub[offset + layer].reserve(stream_.size()); + for (const Track& track : finals_) { + streamTrack.emplace_back(track.trackKF_.frame()); + const TTBV& hitPattern = track.hitPattern_; + const std::vector& stubsKF = track.stubsKF_; + int i(0); + for (int layer = 0; layer < setup_->numLayers(); layer++) + streamsStub[offset + layer].emplace_back(hitPattern.test(layer) ? stubsKF[i++].frame() : tt::FrameStub()); + // store d0 in copied TTTracks + if (setup_->kfUse5ParameterFit()) { + const TTTrackRef& ttTrackRef = track.trackKF_.frame().first; + ttTracks_.emplace_back(ttTrackRef->rInv(), + ttTrackRef->phi(), + ttTrackRef->tanL(), + ttTrackRef->z0(), + track.d0_, + ttTrackRef->chi2XY(), + ttTrackRef->chi2Z(), + ttTrackRef->trkMVA1(), + ttTrackRef->trkMVA2(), + ttTrackRef->trkMVA3(), + ttTrackRef->hitPattern(), + 5, + setup_->bField()); + ttTracks_.back().setPhiSector(ttTrackRef->phiSector()); + ttTracks_.back().setEtaSector(ttTrackRef->etaSector()); + ttTracks_.back().setTrackSeedType(ttTrackRef->trackSeedType()); + ttTracks_.back().setStubPtConsistency(ttTrackRef->stubPtConsistency()); + ttTracks_.back().setStubRefs(ttTrackRef->getStubRefs()); + } + } + } + + // calculates the helix params & their cov. matrix from a pair of stubs + void KalmanFilter::calcSeeds() { + auto update = [this](State* s) { + updateRangeActual(VariableKF::m0, s->m0()); + updateRangeActual(VariableKF::m1, s->m1()); + updateRangeActual(VariableKF::v0, s->v0()); + updateRangeActual(VariableKF::v1, s->v1()); + updateRangeActual(VariableKF::H00, s->H00()); + updateRangeActual(VariableKF::H12, s->H12()); + }; + for (State*& state : stream_) { + if (!state) + continue; + State* s1 = state->parent(); + State* s0 = s1->parent(); + update(s0); + update(s1); + const double dH = digi(VariableKF::dH, s1->H00() - s0->H00()); + const double invdH = digi(VariableKF::invdH, 1.0 / dH); + const double invdH2 = digi(VariableKF::invdH2, 1.0 / dH / dH); + const double H12 = digi(VariableKF::H2, s1->H00() * s1->H00()); + const double H02 = digi(VariableKF::H2, s0->H00() * s0->H00()); + const double H32 = digi(VariableKF::H2, s1->H12() * s1->H12()); + const double H22 = digi(VariableKF::H2, s0->H12() * s0->H12()); + const double H1m0 = digi(VariableKF::Hm0, s1->H00() * s0->m0()); + const double H0m1 = digi(VariableKF::Hm0, s0->H00() * s1->m0()); + const double H3m2 = digi(VariableKF::Hm1, s1->H12() * s0->m1()); + const double H2m3 = digi(VariableKF::Hm1, s0->H12() * s1->m1()); + const double H1v0 = digi(VariableKF::Hv0, s1->H00() * s0->v0()); + const double H0v1 = digi(VariableKF::Hv0, s0->H00() * s1->v0()); + const double H3v2 = digi(VariableKF::Hv1, s1->H12() * s0->v1()); + const double H2v3 = digi(VariableKF::Hv1, s0->H12() * s1->v1()); + const double H12v0 = digi(VariableKF::H2v0, H12 * s0->v0()); + const double H02v1 = digi(VariableKF::H2v0, H02 * s1->v0()); + const double H32v2 = digi(VariableKF::H2v1, H32 * s0->v1()); + const double H22v3 = digi(VariableKF::H2v1, H22 * s1->v1()); + const double x0 = digi(VariableKF::x0, (s1->m0() - s0->m0()) * invdH); + const double x2 = digi(VariableKF::x2, (s1->m1() - s0->m1()) * invdH); + const double x1 = digi(VariableKF::x1, (H1m0 - H0m1) * invdH); + const double x3 = digi(VariableKF::x3, (H3m2 - H2m3) * invdH); + const double C00 = digi(VariableKF::C00, (s1->v0() + s0->v0()) * invdH2); + const double C22 = digi(VariableKF::C22, (s1->v1() + s0->v1()) * invdH2); + const double C01 = -digi(VariableKF::C01, (H1v0 + H0v1) * invdH2); + const double C23 = -digi(VariableKF::C23, (H3v2 + H2v3) * invdH2); + const double C11 = digi(VariableKF::C11, (H12v0 + H02v1) * invdH2); + const double C33 = digi(VariableKF::C33, (H32v2 + H22v3) * invdH2); + // create updated state + states_.emplace_back(State(s1, {x0, x1, x2, x3, 0., C00, C11, C22, C33, C01, C23, 0., 0., 0.})); + state = &states_.back(); + updateRangeActual(VariableKF::x0, x0); + updateRangeActual(VariableKF::x1, x1); + updateRangeActual(VariableKF::x2, x2); + updateRangeActual(VariableKF::x3, x3); + updateRangeActual(VariableKF::C00, C00); + updateRangeActual(VariableKF::C01, C01); + updateRangeActual(VariableKF::C11, C11); + updateRangeActual(VariableKF::C22, C22); + updateRangeActual(VariableKF::C23, C23); + updateRangeActual(VariableKF::C33, C33); + } + } + + // adds a layer to states + void KalmanFilter::addLayer(bool seed) { + auto comb = [seed, this](State*& s) { + if (s) + s = seed ? s->combSeed(states_, layer_) : s->comb(states_, layer_); + }; + auto param = [this](State*& s) { setup_->kfUse5ParameterFit() ? this->update5(s) : this->update4(s); }; + auto update = [seed, param, this](State*& s) { + if (s && (seed || s->hitPattern().pmEncode() == layer_)) { + if (seed) + s = s->update(states_, layer_); + else + param(s); + } + }; + // Latency of KF Associator block firmware + static constexpr int latency = 5; + // dynamic state container for clock accurate emulation + std::deque streamOutput; + // Memory stack used to handle combinatorics + std::deque stack; + // static delay container + std::deque delay(latency, nullptr); + // each trip corresponds to a f/w clock tick + // done if no states to process left, taking as much time as needed + while (!stream_.empty() || !stack.empty() || + !std::all_of(delay.begin(), delay.end(), [](const State* state) { return state == nullptr; })) { + State* state = pop_front(stream_); + // Process a combinatoric state if no (non-combinatoric?) state available + if (!state) + state = pop_front(stack); + streamOutput.push_back(state); + // The remainder of the code in this loop deals with combinatoric states. + comb(state); + delay.push_back(state); + state = pop_front(delay); + if (state) + stack.push_back(state); + } + stream_ = streamOutput; + // Update state with next stub using KF maths + for (State*& state : stream_) + update(state); + } + + // updates state + void KalmanFilter::update4(State*& state) { + // All variable names & equations come from Fruhwirth KF paper http://dx.doi.org/10.1016/0168-9002%2887%2990887-4", where F taken as unit matrix. Stub uncertainties projected onto (phi,z), assuming no correlations between r-phi & r-z planes. + // stub phi residual wrt input helix + const double m0 = state->m0(); + // stub z residual wrt input helix + const double m1 = state->m1(); + // stub projected phi uncertainty squared); + const double v0 = state->v0(); + // stub projected z uncertainty squared + const double v1 = state->v1(); + // Derivative of predicted stub coords wrt helix params: stub radius minus chosenRofPhi + const double H00 = state->H00(); + // Derivative of predicted stub coords wrt helix params: stub radius minus chosenRofZ + const double H12 = state->H12(); + updateRangeActual(VariableKF::m0, m0); + updateRangeActual(VariableKF::m1, m1); + updateRangeActual(VariableKF::v0, v0); + updateRangeActual(VariableKF::v1, v1); + updateRangeActual(VariableKF::H00, H00); + updateRangeActual(VariableKF::H12, H12); + // helix inv2R wrt input helix + double x0 = state->x0(); + // helix phi at radius ChosenRofPhi wrt input helix + double x1 = state->x1(); + // helix cot(Theta) wrt input helix + double x2 = state->x2(); + // helix z at radius chosenRofZ wrt input helix + double x3 = state->x3(); + // cov. matrix + double C00 = state->C00(); + double C01 = state->C01(); + double C11 = state->C11(); + double C22 = state->C22(); + double C23 = state->C23(); + double C33 = state->C33(); + // stub phi residual wrt current state + const double r0C = digi(VariableKF::x1, m0 - x1); + const double r0 = digi(VariableKF::r0, r0C - x0 * H00); + // stub z residual wrt current state + const double r1C = digi(VariableKF::x3, m1 - x3); + const double r1 = digi(VariableKF::r1, r1C - x2 * H12); + // matrix S = H*C + const double S00 = digi(VariableKF::S00, C01 + H00 * C00); + const double S01 = digi(VariableKF::S01, C11 + H00 * C01); + const double S12 = digi(VariableKF::S12, C23 + H12 * C22); + const double S13 = digi(VariableKF::S13, C33 + H12 * C23); + // Cov. matrix of predicted residuals R = V+HCHt = C+H*St + const double R00 = digi(VariableKF::R00, v0 + S01 + H00 * S00); + const double R11 = digi(VariableKF::R11, v1 + S13 + H12 * S12); + // improved dynamic cancelling + const int msb0 = std::max(0, static_cast(std::ceil(std::log2(R00 / base(VariableKF::R00))))); + const int msb1 = std::max(0, static_cast(std::ceil(std::log2(R11 / base(VariableKF::R11))))); + const int shift0 = width(VariableKF::R00) - msb0; + const int shift1 = width(VariableKF::R11) - msb1; + const double R00Shifted = R00 * std::pow(2., shift0); + const double R11Shifted = R11 * std::pow(2., shift1); + const double R00Rough = digi(VariableKF::R00Rough, R00Shifted); + const double R11Rough = digi(VariableKF::R11Rough, R11Shifted); + const double invR00Approx = digi(VariableKF::invR00Approx, 1. / R00Rough); + const double invR11Approx = digi(VariableKF::invR11Approx, 1. / R11Rough); + const double invR00Cor = digi(VariableKF::invR00Cor, 2. - invR00Approx * R00Shifted); + const double invR11Cor = digi(VariableKF::invR11Cor, 2. - invR11Approx * R11Shifted); + const double invR00 = digi(VariableKF::invR00, invR00Approx * invR00Cor); + const double invR11 = digi(VariableKF::invR11, invR11Approx * invR11Cor); + // shift S to "undo" shifting of R + auto digiShifted = [](double val, double base) { return std::floor(val / base * 2. + 1.e-11) * base / 2.; }; + const double S00Shifted = digiShifted(S00 * std::pow(2., shift0), base(VariableKF::S00Shifted)); + const double S01Shifted = digiShifted(S01 * std::pow(2., shift0), base(VariableKF::S01Shifted)); + const double S12Shifted = digiShifted(S12 * std::pow(2., shift1), base(VariableKF::S12Shifted)); + const double S13Shifted = digiShifted(S13 * std::pow(2., shift1), base(VariableKF::S13Shifted)); + // Kalman gain matrix K = S*R(inv) + const double K00 = digi(VariableKF::K00, S00Shifted * invR00); + const double K10 = digi(VariableKF::K10, S01Shifted * invR00); + const double K21 = digi(VariableKF::K21, S12Shifted * invR11); + const double K31 = digi(VariableKF::K31, S13Shifted * invR11); + // Updated helix params, their cov. matrix + x0 = digi(VariableKF::x0, x0 + r0 * K00); + x1 = digi(VariableKF::x1, x1 + r0 * K10); + x2 = digi(VariableKF::x2, x2 + r1 * K21); + x3 = digi(VariableKF::x3, x3 + r1 * K31); + C00 = digi(VariableKF::C00, C00 - S00 * K00); + C01 = digi(VariableKF::C01, C01 - S01 * K00); + C11 = digi(VariableKF::C11, C11 - S01 * K10); + C22 = digi(VariableKF::C22, C22 - S12 * K21); + C23 = digi(VariableKF::C23, C23 - S13 * K21); + C33 = digi(VariableKF::C33, C33 - S13 * K31); + // update variable ranges to tune variable granularity + updateRangeActual(VariableKF::r0, r0); + updateRangeActual(VariableKF::r1, r1); + updateRangeActual(VariableKF::S00, S00); + updateRangeActual(VariableKF::S01, S01); + updateRangeActual(VariableKF::S12, S12); + updateRangeActual(VariableKF::S13, S13); + updateRangeActual(VariableKF::S00Shifted, S00Shifted); + updateRangeActual(VariableKF::S01Shifted, S01Shifted); + updateRangeActual(VariableKF::S12Shifted, S12Shifted); + updateRangeActual(VariableKF::S13Shifted, S13Shifted); + updateRangeActual(VariableKF::R00, R00); + updateRangeActual(VariableKF::R11, R11); + updateRangeActual(VariableKF::R00Rough, R00Rough); + updateRangeActual(VariableKF::R11Rough, R11Rough); + updateRangeActual(VariableKF::invR00Approx, invR00Approx); + updateRangeActual(VariableKF::invR11Approx, invR11Approx); + updateRangeActual(VariableKF::invR00Cor, invR00Cor); + updateRangeActual(VariableKF::invR11Cor, invR11Cor); + updateRangeActual(VariableKF::invR00, invR00); + updateRangeActual(VariableKF::invR11, invR11); + updateRangeActual(VariableKF::K00, K00); + updateRangeActual(VariableKF::K10, K10); + updateRangeActual(VariableKF::K21, K21); + updateRangeActual(VariableKF::K31, K31); + // create updated state + states_.emplace_back(State(state, {x0, x1, x2, x3, 0., C00, C11, C22, C33, C01, C23, 0., 0., 0.})); + state = &states_.back(); + updateRangeActual(VariableKF::x0, x0); + updateRangeActual(VariableKF::x1, x1); + updateRangeActual(VariableKF::x2, x2); + updateRangeActual(VariableKF::x3, x3); + updateRangeActual(VariableKF::C00, C00); + updateRangeActual(VariableKF::C01, C01); + updateRangeActual(VariableKF::C11, C11); + updateRangeActual(VariableKF::C22, C22); + updateRangeActual(VariableKF::C23, C23); + updateRangeActual(VariableKF::C33, C33); + } + + // updates state + void KalmanFilter::update5(State*& state) { + const double m0 = state->m0(); + const double m1 = state->m1(); + const double v0 = state->v0(); + const double v1 = state->v1(); + const double H00 = state->H00(); + const double H12 = state->H12(); + const double H04 = state->H04(); + double x0 = state->x0(); + double x1 = state->x1(); + double x2 = state->x2(); + double x3 = state->x3(); + double x4 = state->x4(); + double C00 = state->C00(); + double C01 = state->C01(); + double C11 = state->C11(); + double C22 = state->C22(); + double C23 = state->C23(); + double C33 = state->C33(); + double C44 = state->C44(); + double C40 = state->C40(); + double C41 = state->C41(); + const double r0 = m0 - x1 - x0 * H00 - x4 / H04; + const double r1 = m1 - x3 - x2 * H12; + const double S00 = C01 + H00 * C00 + C40 / H04; + const double S01 = C11 + H00 * C01 + C41 / H04; + const double S12 = C23 + H12 * C22; + const double S13 = C33 + H12 * C23; + const double S04 = C41 + H00 * C40 + C44 / H04; + const double R00 = v0 + S01 + H00 * S00 + S04 / H04; + const double R11 = v1 + S13 + H12 * S12; + const double K00 = S00 / R00; + const double K10 = S01 / R00; + const double K21 = S12 / R11; + const double K31 = S13 / R11; + const double K40 = S04 / R00; + x0 += r0 * K00; + x1 += r0 * K10; + x2 += r1 * K21; + x3 += r1 * K31; + x4 += r0 * K40; + C00 -= S00 * K00; + C01 -= S01 * K00; + C11 -= S01 * K10; + C22 -= S12 * K21; + C23 -= S13 * K21; + C33 -= S13 * K31; + C44 -= S04 * K40; + C40 -= S04 * K00; + C41 -= S04 * K10; + states_.emplace_back(State(state, {x0, x1, x2, x3, x4, C00, C11, C22, C33, C01, C23, C44, C40, C41})); + state = &states_.back(); + } + + // remove and return first element of deque, returns nullptr if empty + template + T* KalmanFilter::pop_front(std::deque& ts) const { + T* t = nullptr; + if (!ts.empty()) { + t = ts.front(); + ts.pop_front(); + } + return t; + } + +} // namespace trklet diff --git a/L1Trigger/TrackFindingTracklet/src/KalmanFilterFormats.cc b/L1Trigger/TrackFindingTracklet/src/KalmanFilterFormats.cc new file mode 100644 index 0000000000000..a973e65fa3563 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/KalmanFilterFormats.cc @@ -0,0 +1,587 @@ +#include "L1Trigger/TrackFindingTracklet/interface/KalmanFilterFormats.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace trklet { + + constexpr auto variableKFstrs_ = { + "x0", "x1", "x2", "x3", "H00", "H12", "m0", "m1", + "v0", "v1", "r0", "r1", "S00", "S01", "S12", "S13", + "S00Shifted", "S01Shifted", "S12Shifted", "S13Shifted", "K00", "K10", "K21", "K31", + "R00", "R11", "R00Rough", "R11Rough", "invR00Approx", "invR11Approx", "invR00Cor", "invR11Cor", + "invR00", "invR11", "C00", "C01", "C11", "C22", "C23", "C33"}; + + void KalmanFilterFormats::endJob(std::stringstream& ss) { + const int wName = + std::strlen(*std::max_element(variableKFstrs_.begin(), variableKFstrs_.end(), [](const auto& a, const auto& b) { + return std::strlen(a) < std::strlen(b); + })); + for (VariableKF v = VariableKF::begin; v != VariableKF::dH; v = VariableKF(+v + 1)) { + const double r = + format(v).twos() ? std::max(std::abs(format(v).min()), std::abs(format(v).max())) * 2. : format(v).max(); + const int delta = format(v).width() - std::ceil(std::log2(r / format(v).base())); + ss << std::setw(wName) << *std::next(variableKFstrs_.begin(), +v) << ": "; + ss << std::setw(3) << (delta == -2147483648 ? "-" : std::to_string(delta)) << std::endl; + } + } + + KalmanFilterFormats::KalmanFilterFormats() { formats_.reserve(+VariableKF::end); } + + void KalmanFilterFormats::consume(const DataFormats* dataFormats, const ConfigKF& iConfig) { + iConfig_ = iConfig; + dataFormats_ = dataFormats; + fillFormats(); + } + + template + void KalmanFilterFormats::fillFormats() { + formats_.emplace_back(makeDataFormat(dataFormats_, iConfig_)); + if constexpr (it + 1 != VariableKF::end) + fillFormats(); + } + + DataFormatKF::DataFormatKF( + const VariableKF& v, bool twos, bool enableIntegerEmulation, int width, double base, double range) + : v_(v), + twos_(twos), + enableIntegerEmulation_(enableIntegerEmulation), + width_(width), + base_(base), + range_(range), + min_(std::numeric_limits::max()), + abs_(std::numeric_limits::max()), + max_(std::numeric_limits::lowest()) {} + + // returns false if data format would oferflow for this double value + bool DataFormatKF::inRange(double d) const { + if (twos_) + return d >= -range_ / 2. && d < range_ / 2.; + return d >= 0 && d < range_; + } + + void DataFormatKF::updateRangeActual(double d) { + min_ = std::min(min_, d); + abs_ = std::min(abs_, std::abs(d)); + max_ = std::max(max_, d); + if (enableIntegerEmulation_ && !inRange(d)) { + std::string v = *std::next(variableKFstrs_.begin(), +v_); + cms::Exception exception("out_of_range"); + exception.addContext("trackFindingTracklet:DataFormatKF::updateRangeActual"); + exception << "Variable " << v << " = " << d << " is out of range " << (twos_ ? -range_ / 2. : 0) << " to " + << (twos_ ? range_ / 2. : range_) << "." << std::endl; + if (twos_ || d >= 0.) + exception.addAdditionalInfo("Consider raising BaseShift" + v + " in KalmanFilterFormats_cfi.py."); + exception.addAdditionalInfo("Consider disabling integer emulation in KalmanFilterFormats_cfi.py."); + throw exception; + } + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& input = dataFormats->format(Variable::inv2R, Process::kf); + const int baseShift = iConfig.baseShiftx0_; + const double base = std::pow(2, baseShift) * input.base(); + const int width = dataFormats->setup()->widthDSPbb(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::x0, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& input = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.baseShiftx1_; + const double base = std::pow(2, baseShift) * input.base(); + const int width = dataFormats->setup()->widthDSPbb(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::x1, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& input = dataFormats->format(Variable::cot, Process::kf); + const int baseShift = iConfig.baseShiftx2_; + const double base = std::pow(2, baseShift) * input.base(); + const int width = dataFormats->setup()->widthDSPbb(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::x2, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& input = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.baseShiftx3_; + const double base = std::pow(2, baseShift) * input.base(); + const int width = dataFormats->setup()->widthDSPbb(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::x3, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& tm = dataFormats->format(Variable::r, Process::tm); + const double base = tm.base(); + const int width = tm.width(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::H00, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const tt::Setup* setup = dataFormats->setup(); + const DataFormat& tm = dataFormats->format(Variable::r, Process::tm); + const double base = tm.base(); + const double rangeMin = 2. * setup->maxRz(); + const int width = std::ceil(std::log2(rangeMin / base)); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::H12, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& tm = dataFormats->format(Variable::phi, Process::tm); + const double base = tm.base(); + const int width = tm.width(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::m0, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& tm = dataFormats->format(Variable::z, Process::tm); + const double base = tm.base(); + const int width = tm.width(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::m1, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& dPhi = dataFormats->format(Variable::dPhi, Process::tm); + const DataFormatKF S01 = makeDataFormat(dataFormats, iConfig); + const double range = 4. * dPhi.range() * dPhi.range(); + const double base = S01.base(); + const int width = std::ceil(std::log2(range / base) - 1.e-11); + return DataFormatKF(VariableKF::v0, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& dZ = dataFormats->format(Variable::dZ, Process::tm); + const DataFormatKF S13 = makeDataFormat(dataFormats, iConfig); + const double range = 4. * dZ.range() * dZ.range(); + const double base = S13.base(); + const int width = std::ceil(std::log2(range / base) - 1.e-11); + return DataFormatKF(VariableKF::v1, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.baseShiftr0_; + const double base = std::pow(2., baseShift) * x1.base(); + const int width = dataFormats->setup()->widthDSPbb(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::r0, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.baseShiftr1_; + const double base = std::pow(2., baseShift) * x3.base(); + const int width = dataFormats->setup()->widthDSPbb(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::r1, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x0 = dataFormats->format(Variable::inv2R, Process::kf); + const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.baseShiftS00_; + const double base = std::pow(2., baseShift) * x0.base() * x1.base(); + const int width = dataFormats->setup()->widthDSPab(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::S00, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.baseShiftS01_; + const double base = std::pow(2., baseShift) * x1.base() * x1.base(); + const int width = dataFormats->setup()->widthDSPab(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::S01, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x2 = dataFormats->format(Variable::cot, Process::kf); + const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.baseShiftS12_; + const double base = std::pow(2., baseShift) * x2.base() * x3.base(); + const int width = dataFormats->setup()->widthDSPab(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::S12, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.baseShiftS13_; + const double base = std::pow(2., baseShift) * x3.base() * x3.base(); + const int width = dataFormats->setup()->widthDSPab(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::S13, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x0 = dataFormats->format(Variable::inv2R, Process::kf); + const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.baseShiftS00Shifted_; + const double base = std::pow(2., baseShift) * x0.base() * x1.base(); + const int width = dataFormats->setup()->widthDSPab(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::S00Shifted, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.baseShiftS01Shifted_; + const double base = std::pow(2., baseShift) * x1.base() * x1.base(); + const int width = dataFormats->setup()->widthDSPab(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::S01Shifted, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x2 = dataFormats->format(Variable::cot, Process::kf); + const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.baseShiftS12Shifted_; + const double base = std::pow(2., baseShift) * x2.base() * x3.base(); + const int width = dataFormats->setup()->widthDSPab(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::S12Shifted, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.baseShiftS13Shifted_; + const double base = std::pow(2., baseShift) * x3.base() * x3.base(); + const int width = dataFormats->setup()->widthDSPab(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::S13Shifted, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x0 = dataFormats->format(Variable::inv2R, Process::kf); + const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.baseShiftK00_; + const double base = std::pow(2., baseShift) * x0.base() / x1.base(); + const int width = dataFormats->setup()->widthDSPbb(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::K00, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const int baseShift = iConfig.baseShiftK10_; + const double base = std::pow(2., baseShift); + const int width = dataFormats->setup()->widthDSPbb(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::K10, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x2 = dataFormats->format(Variable::cot, Process::kf); + const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.baseShiftK21_; + const double base = std::pow(2., baseShift) * x2.base() / x3.base(); + const int width = dataFormats->setup()->widthDSPbb(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::K21, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const int baseShift = iConfig.baseShiftK31_; + const double base = std::pow(2., baseShift); + const int width = dataFormats->setup()->widthDSPbb(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::K31, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.baseShiftR00_; + const int width = iConfig.widthR00_; + const double base = std::pow(2., baseShift) * x1.base() * x1.base(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::R00, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.baseShiftR11_; + const int width = iConfig.widthR11_; + const double base = std::pow(2., baseShift) * x3.base() * x3.base(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::R11, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF R00 = makeDataFormat(dataFormats, iConfig); + const int width = dataFormats->setup()->widthAddrBRAM18(); + const double range = R00.range(); + const int baseShift = R00.width() - width - 1; + const double base = std::pow(2., baseShift) * R00.base(); + return DataFormatKF(VariableKF::R00Rough, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF R11 = makeDataFormat(dataFormats, iConfig); + const int width = dataFormats->setup()->widthAddrBRAM18(); + const double range = R11.range(); + const int baseShift = R11.width() - width - 1; + const double base = std::pow(2., baseShift) * R11.base(); + return DataFormatKF(VariableKF::R11Rough, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.baseShiftInvR00Approx_; + const double base = std::pow(2., baseShift) / x1.base() / x1.base(); + const int width = dataFormats->setup()->widthDSPbu(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::invR00Approx, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.baseShiftInvR11Approx_; + const double base = std::pow(2., baseShift) / x3.base() / x3.base(); + const int width = dataFormats->setup()->widthDSPbu(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::invR11Approx, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const int baseShift = iConfig.baseShiftInvR00Cor_; + const double base = std::pow(2., baseShift); + const int width = dataFormats->setup()->widthDSPau(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::invR00Cor, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const int baseShift = iConfig.baseShiftInvR11Cor_; + const double base = std::pow(2., baseShift); + const int width = dataFormats->setup()->widthDSPau(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::invR11Cor, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.baseShiftInvR00_; + const double base = std::pow(2., baseShift) / x1.base() / x1.base(); + const int width = dataFormats->setup()->widthDSPbu(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::invR00, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.baseShiftInvR11_; + const double base = pow(2., baseShift) / x3.base() / x3.base(); + const int width = dataFormats->setup()->widthDSPbu(); + const double range = base * pow(2, width); + return DataFormatKF(VariableKF::invR11, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x0 = dataFormats->format(Variable::inv2R, Process::kf); + const int baseShift = iConfig.baseShiftC00_; + const int width = iConfig.widthC00_; + const double base = std::pow(2., baseShift) * x0.base() * x0.base(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::C00, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x0 = dataFormats->format(Variable::inv2R, Process::kf); + const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.baseShiftC01_; + const int width = iConfig.widthC01_; + const double base = std::pow(2., baseShift) * x0.base() * x1.base(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::C01, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.baseShiftC11_; + const int width = iConfig.widthC11_; + const double base = std::pow(2., baseShift) * x1.base() * x1.base(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::C11, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x2 = dataFormats->format(Variable::cot, Process::kf); + const int baseShift = iConfig.baseShiftC22_; + const int width = iConfig.widthC22_; + const double base = std::pow(2., baseShift) * x2.base() * x2.base(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::C22, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x2 = dataFormats->format(Variable::cot, Process::kf); + const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.baseShiftC23_; + const int width = iConfig.widthC23_; + const double base = std::pow(2., baseShift) * x2.base() * x3.base(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::C23, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.baseShiftC33_; + const int width = iConfig.widthC33_; + const double base = std::pow(2., baseShift) * x3.base() * x3.base(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::C33, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF H00 = makeDataFormat(dataFormats, iConfig); + const int width = dataFormats->setup()->widthAddrBRAM18(); + const double range = dataFormats->setup()->outerRadius() - dataFormats->setup()->innerRadius(); + const double base = H00.base() * std::pow(2, ceil(log2(range / H00.base())) - width); + return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF H00 = makeDataFormat(dataFormats, iConfig); + const int width = dataFormats->setup()->widthDSPbu(); + const double range = 1. / dataFormats->setup()->kfMinSeedDeltaR(); + const int baseShift = std::ceil(std::log2(range * std::pow(2., -width) * H00.base())); + const double base = std::pow(2., baseShift) / H00.base(); + return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF H00 = makeDataFormat(dataFormats, iConfig); + const int width = dataFormats->setup()->widthDSPbu(); + const double range = 1. / std::pow(dataFormats->setup()->kfMinSeedDeltaR(), 2); + const double baseH2 = H00.base() * H00.base(); + const int baseShift = std::ceil(std::log2(range * std::pow(2., -width) * baseH2)); + const double base = std::pow(2., baseShift) / baseH2; + return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF H00 = makeDataFormat(dataFormats, iConfig); + const int width = H00.width() + H00.width(); + const double base = H00.base() * H00.base(); + const double range = H00.range() * H00.range(); + return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF H00 = makeDataFormat(dataFormats, iConfig); + const DataFormatKF m0 = makeDataFormat(dataFormats, iConfig); + const int width = H00.width() + m0.width(); + const double base = H00.base() * m0.base(); + const double range = H00.range() * m0.range(); + return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF H12 = makeDataFormat(dataFormats, iConfig); + const DataFormatKF m1 = makeDataFormat(dataFormats, iConfig); + const int width = H12.width() + m1.width(); + const double base = H12.base() * m1.base(); + const double range = H12.range() * m1.range(); + return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF H00 = makeDataFormat(dataFormats, iConfig); + const DataFormatKF v0 = makeDataFormat(dataFormats, iConfig); + const int width = dataFormats->setup()->widthDSPab(); + const double base = H00.base() * v0.base() * pow(2, H00.width() + v0.width() - width); + const double range = H00.range() * v0.range(); + return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF H12 = makeDataFormat(dataFormats, iConfig); + const DataFormatKF v1 = makeDataFormat(dataFormats, iConfig); + const int width = dataFormats->setup()->widthDSPab(); + const double base = H12.base() * v1.base() * pow(2, H12.width() + v1.width() - width); + const double range = H12.range() * v1.range(); + return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF H00 = makeDataFormat(dataFormats, iConfig); + const DataFormatKF v0 = makeDataFormat(dataFormats, iConfig); + const int width = dataFormats->setup()->widthDSPau(); + const double base = H00.base() * H00.base() * v0.base() * pow(2, 2 * H00.width() + v0.width() - width); + const double range = H00.range() * H00.range() * v0.range(); + return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF H12 = makeDataFormat(dataFormats, iConfig); + const DataFormatKF v1 = makeDataFormat(dataFormats, iConfig); + const int width = dataFormats->setup()->widthDSPau(); + const double base = H12.base() * H12.base() * v1.base() * pow(2, 2 * H12.width() + v1.width() - width); + const double range = H12.range() * H12.range() * v1.range(); + return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range); + } + +} // namespace trklet diff --git a/L1Trigger/TrackFindingTracklet/src/PurgeDuplicate.cc b/L1Trigger/TrackFindingTracklet/src/PurgeDuplicate.cc index fc2a8b59a206c..b64f81e99d30f 100644 --- a/L1Trigger/TrackFindingTracklet/src/PurgeDuplicate.cc +++ b/L1Trigger/TrackFindingTracklet/src/PurgeDuplicate.cc @@ -220,10 +220,10 @@ void PurgeDuplicate::execute(std::vector& outputtracks, unsigned int iSec if (st1.first == st2.first && st1.second == st2.second) { // tracks share stub // Converts layer/disk encoded in st1->first to an index in the layer array int i = st1.first; // layer/disk - bool barrel = (i > 0 && i < 10); - bool endcapA = (i > 10); + bool barrel = (i > 0 && i <= N_LAYER); + bool endcapA = (i > N_LAYER); bool endcapB = (i < 0); - int lay = barrel * (i - 1) + endcapA * (i - 5) - endcapB * i; // encode in range 0-15 + int lay = barrel * (i - 1) + endcapA * (i - (N_LAYER - 1)) - endcapB * i; // encode in range 0-15 if (!layerArr[lay]) { nShareLay++; layerArr[lay] = true; @@ -260,10 +260,10 @@ void PurgeDuplicate::execute(std::vector& outputtracks, unsigned int iSec // For each stub on the second track, find the stub with the best residual and store its index in the layStubidsTrk1 array for (unsigned int stcount = 0; stcount < stubsTrk2.size(); stcount++) { int i = stubsTrk2[stcount].first; // layer/disk - bool barrel = (i > 0 && i < 10); - bool endcapA = (i > 10); + bool barrel = (i > 0 && i <= N_LAYER); + bool endcapA = (i > N_LAYER); bool endcapB = (i < 0); - int lay = barrel * (i - 1) + endcapA * (i - 5) - endcapB * i; // encode in range 0-15 + int lay = barrel * (i - 1) + endcapA * (i - (N_LAYER - 1)) - endcapB * i; // encode in range 0-15 double nres = getPhiRes(inputtracklets_[jtrk], fullStubslistsTrk2[stcount]); double ores = 0; if (layStubidsTrk2[lay] != -1) diff --git a/L1Trigger/TrackFindingTracklet/src/State.cc b/L1Trigger/TrackFindingTracklet/src/State.cc new file mode 100644 index 0000000000000..8fe30200da7ed --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/State.cc @@ -0,0 +1,167 @@ +#include "L1Trigger/TrackFindingTracklet/interface/State.h" + +#include +#include +#include +#include +#include + +namespace trklet { + + // + State::Stub::Stub(KalmanFilterFormats* kff, const tt::FrameStub& frame) : stubDR_(frame, kff->dataFormats()) { + const tt::Setup* setup = kff->setup(); + H12_ = kff->format(VariableKF::H12).digi(stubDR_.r() + setup->chosenRofPhi() - setup->chosenRofZ()); + H04_ = stubDR_.r() + setup->chosenRofPhi(); + v0_ = kff->format(VariableKF::v0).digi(pow(2. * stubDR_.dPhi(), 2)); + v1_ = kff->format(VariableKF::v1).digi(pow(2. * stubDR_.dZ(), 2)); + } + + // proto state constructor + State::State(KalmanFilterFormats* kff, TrackDR* track, const std::vector& stubs, int trackId) + : kff_(kff), + setup_(kff->setup()), + track_(track), + stubs_(stubs), + trackId_(trackId), + parent_(nullptr), + stub_(nullptr), + hitPattern_(0, setup_->numLayers()), + trackPattern_(0, setup_->numLayers()), + x0_(0.), + x1_(0.), + x2_(0.), + x3_(0.), + x4_(0.), + C00_(9.e9), + C01_(0.), + C11_(9.e9), + C22_(9.e9), + C23_(0.), + C33_(9.e9), + C44_(pow(setup_->maxD0(), 2)), + C40_(0.), + C41_(0.) { + int layer(0); + for (Stub* stub : stubs_) + trackPattern_[layer++] = (bool)stub; + layer = trackPattern_.plEncode(); + stub_ = stubs_[layer]; + hitPattern_.set(layer); + } + + // updated state constructor + State::State(State* state, const std::vector& doubles) : State(state) { + parent_ = state; + // updated track parameter and uncertainties + x0_ = doubles[0]; + x1_ = doubles[1]; + x2_ = doubles[2]; + x3_ = doubles[3]; + x4_ = doubles[4]; + C00_ = doubles[5]; + C11_ = doubles[6]; + C22_ = doubles[7]; + C33_ = doubles[8]; + C01_ = doubles[9]; + C23_ = doubles[10]; + C44_ = doubles[11]; + C40_ = doubles[12]; + C41_ = doubles[13]; + // pick next stub + const int layer = this->layer(); + stub_ = nullptr; + if (hitPattern_.count() >= setup_->kfMinLayers() || hitPattern_.count() == setup_->kfMaxLayers()) + return; + const int nextLayer = trackPattern_.plEncode(layer + 1, setup_->numLayers()); + if (nextLayer == setup_->numLayers()) + return; + stub_ = stubs_[nextLayer]; + hitPattern_.set(nextLayer); + } + + // combinatoric and seed building state constructor + State::State(State* state, State* parent, int layer) : State(state) { + parent_ = parent; + hitPattern_ = parent ? parent->hitPattern() : TTBV(0, setup_->numLayers()); + stub_ = stubs_[layer]; + hitPattern_.set(layer); + } + + // + State* State::update(std::deque& states, int layer) { + if (!hitPattern_.test(layer) || hitPattern_.count() > setup_->kfNumSeedStubs()) + return this; + const int nextLayer = trackPattern_.plEncode(layer + 1, setup_->numLayers()); + states.emplace_back(this, this, nextLayer); + return &states.back(); + } + + // + State* State::combSeed(std::deque& states, int layer) { + // handle trivial state + if (!hitPattern_.test(layer) || hitPattern_.count() > setup_->kfNumSeedStubs()) + return nullptr; + // skip layers + const int nextLayer = trackPattern_.plEncode(layer + 1, setup_->numLayers()); + const int maxSeedStubs = hitPattern_.count(0, layer) + trackPattern_.count(nextLayer, setup_->kfMaxSeedingLayer()); + if (maxSeedStubs < setup_->kfNumSeedStubs()) + return nullptr; + const int maxStubs = maxSeedStubs + trackPattern_.count(setup_->kfMaxSeedingLayer(), setup_->numLayers()); + if (maxStubs < setup_->kfMinLayers()) + return nullptr; + states.emplace_back(this, parent_, nextLayer); + return &states.back(); + } + + // + State* State::comb(std::deque& states, int layer) { + // handle skipping and min reached + if (!hitPattern_.test(layer)) { + if (!stub_ && trackPattern_[layer] && hitPattern_.count() < setup_->kfMaxLayers()) { + states.emplace_back(this, parent_, layer); + return &states.back(); + } + return nullptr; + } + // handle part of seed + if (hitPattern_.pmEncode() != layer) + return nullptr; + // handle skip + const int nextLayer = trackPattern_.plEncode(layer + 1, setup_->numLayers()); + if (nextLayer == setup_->numLayers()) + return nullptr; + // not enough layer left + if (hitPattern_.count() - 1 + trackPattern_.count(nextLayer, setup_->numLayers()) < setup_->kfMinLayers()) + return nullptr; + states.emplace_back(this, parent_, nextLayer); + return &states.back(); + } + + // copy constructor + State::State(State* state) + : kff_(state->kff_), + setup_(state->setup_), + track_(state->track_), + stubs_(state->stubs_), + trackId_(state->trackId_), + parent_(state->parent_), + stub_(state->stub_), + hitPattern_(state->hitPattern_), + trackPattern_(state->trackPattern_), + x0_(state->x0_), + x1_(state->x1_), + x2_(state->x2_), + x3_(state->x3_), + x4_(state->x4_), + C00_(state->C00_), + C01_(state->C01_), + C11_(state->C11_), + C22_(state->C22_), + C23_(state->C23_), + C33_(state->C33_), + C44_(state->C44_), + C40_(state->C40_), + C41_(state->C41_) {} + +} // namespace trklet diff --git a/L1Trigger/TrackFindingTracklet/src/TrackFindingProcessor.cc b/L1Trigger/TrackFindingTracklet/src/TrackFindingProcessor.cc new file mode 100644 index 0000000000000..3fd685b9f9797 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/TrackFindingProcessor.cc @@ -0,0 +1,282 @@ +#include "L1Trigger/TrackFindingTracklet/interface/TrackFindingProcessor.h" +#include "L1Trigger/TrackTrigger/interface/StubPtConsistency.h" + +#include +#include +#include +#include +#include + +namespace trklet { + + TrackFindingProcessor::TrackFindingProcessor(const tt::Setup* setup, + const DataFormats* dataFormats, + const trackerTFP::TrackQuality* trackQuality) + : setup_(setup), dataFormats_(dataFormats), trackQuality_(trackQuality) { + bfield_ = setup_->bField(); + } + + // + TrackFindingProcessor::Track::Track(const tt::FrameTrack& frameTrack, + const tt::Frame& frameTQ, + const std::vector& ttStubRefs, + const DataFormats* df, + const trackerTFP::TrackQuality* tq) + : ttTrackRef_(frameTrack.first), ttStubRefs_(ttStubRefs), valid_(true) { + partials_.reserve(partial_in); + const double rangeInvR = -2. * TTTrack_TrackWord::minRinv; + const double rangePhi0 = -2. * TTTrack_TrackWord::minPhi0; + const double rangeCot = -2. * TTTrack_TrackWord::minTanl; + const double rangeZ0 = -2. * TTTrack_TrackWord::minZ0; + const double rangeD0 = -2. * TTTrack_TrackWord::minD0; + const double baseInvR = rangeInvR / std::pow(2., TTTrack_TrackWord::TrackBitWidths::kRinvSize); + const double basePhi0 = rangePhi0 / std::pow(2., TTTrack_TrackWord::TrackBitWidths::kPhiSize); + const double baseCot = rangeCot / std::pow(2., TTTrack_TrackWord::TrackBitWidths::kTanlSize); + const double baseZ0 = rangeZ0 / std::pow(2., TTTrack_TrackWord::TrackBitWidths::kZ0Size); + const double baseD0 = rangeD0 / std::pow(2., TTTrack_TrackWord::TrackBitWidths::kD0Size); + const int nLayers = TTTrack_TrackWord::TrackBitWidths::kHitPatternSize; + const TTBV other_MVAs = TTBV(0, 2 * TTTrack_TrackWord::TrackBitWidths::kMVAQualitySize); + const TTBV chi2bend = TTBV(0, TTTrack_TrackWord::TrackBitWidths::kBendChi2Size); + const TTBV valid = TTBV(1, TTTrack_TrackWord::TrackBitWidths::kValidSize); + // convert bits into nice formats + const tt::Setup* setup = df->setup(); + const TrackKF track(frameTrack, df); + inv2R_ = track.inv2R(); + phiT_ = track.phiT(); + cot_ = track.cot(); + zT_ = track.zT(); + const double d0 = std::max(std::min(ttTrackRef_->d0(), -TTTrack_TrackWord::minD0), TTTrack_TrackWord::minD0); + TTBV ttBV = TTBV(frameTQ); + tq->format(trackerTFP::VariableTQ::chi2rz).extract(ttBV, chi2rz_); + tq->format(trackerTFP::VariableTQ::chi2rphi).extract(ttBV, chi2rphi_); + mva_ = TTBV(ttBV, trackerTFP::widthMVA_).val(); + ttBV >>= trackerTFP::widthMVA_; + hitPattern_ = TTBV(ttBV, setup->numLayers()); + channel_ = cot_ < 0. ? 0 : 1; + // convert nice formats into bits + const double z0 = zT_ - cot_ * setup->chosenRofZ(); + const double phi0 = phiT_ - inv2R_ * setup->chosenRofPhi(); + double invR = -2. * inv2R_; + if (invR < TTTrack_TrackWord::minRinv) + invR = TTTrack_TrackWord::minRinv + df->format(Variable::inv2R, Process::dr).base(); + else if (invR > -TTTrack_TrackWord::minRinv) + invR = -TTTrack_TrackWord::minRinv - df->format(Variable::inv2R, Process::dr).base(); + const double chi2rphi = chi2rphi_ / (hitPattern_.count() - 2); + const double chi2rz = chi2rz_ / (hitPattern_.count() - 2); + int chi2rphiBin(-1); + for (double d : TTTrack_TrackWord::chi2RPhiBins) + if (chi2rphi >= d) + chi2rphiBin++; + else + break; + int chi2rzBin(-1); + for (double d : TTTrack_TrackWord::chi2RZBins) + if (chi2rz >= d) + chi2rzBin++; + else + break; + if (std::abs(invR) > rangeInvR / 2.) + valid_ = false; + if (std::abs(phi0) > rangePhi0 / 2.) + valid_ = false; + if (std::abs(cot_) > rangeCot / 2.) + valid_ = false; + if (std::abs(z0) > rangeZ0 / 2.) + valid_ = false; + if (std::abs(d0) > rangeD0 / 2.) + valid_ = false; + if (!valid_) + return; + const TTBV MVA_quality(mva_, TTTrack_TrackWord::TrackBitWidths::kMVAQualitySize); + const TTBV hit_pattern(hitPattern_.resize(nLayers).val(), nLayers); + const TTBV D0(d0, baseD0, TTTrack_TrackWord::TrackBitWidths::kD0Size, true); + const TTBV Chi2rz(chi2rzBin, TTTrack_TrackWord::TrackBitWidths::kChi2RZSize); + const TTBV Z0(z0, baseZ0, TTTrack_TrackWord::TrackBitWidths::kZ0Size, true); + const TTBV tanL(cot_, baseCot, TTTrack_TrackWord::TrackBitWidths::kTanlSize, true); + const TTBV Chi2rphi(chi2rphiBin, TTTrack_TrackWord::TrackBitWidths::kChi2RPhiSize); + const TTBV Phi0(phi0, basePhi0, TTTrack_TrackWord::TrackBitWidths::kPhiSize, true); + const TTBV InvR(invR, baseInvR, TTTrack_TrackWord::TrackBitWidths::kRinvSize, true); + partials_.emplace_back((valid + InvR + Phi0 + Chi2rphi).str()); + partials_.emplace_back((tanL + Z0 + Chi2rz).str()); + partials_.emplace_back((D0 + chi2bend + hit_pattern + MVA_quality + other_MVAs).str()); + } + + // fill output products + void TrackFindingProcessor::produce(const tt::StreamsTrack& inputs, + const tt::Streams& inputsAdd, + const tt::StreamsStub& stubs, + tt::TTTracks& ttTracks, + tt::StreamsTrack& outputs) { + // organize input tracks + std::vector> streams(outputs.size()); + consume(inputs, inputsAdd, stubs, streams); + // emualte data format f/w + produce(streams, outputs); + // produce TTTracks + produce(outputs, ttTracks); + } + + // + void TrackFindingProcessor::consume(const tt::StreamsTrack& inputs, + const tt::Streams& inputsAdd, + const tt::StreamsStub& stubs, + std::vector>& outputs) { + // count input objects + int nTracks(0); + auto valid = [](int sum, const tt::FrameTrack& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); }; + for (const tt::StreamTrack& tracks : inputs) + nTracks += std::accumulate(tracks.begin(), tracks.end(), 0, valid); + tracks_.reserve(nTracks); + // convert input data + for (int region = 0; region < setup_->numRegions(); region++) { + const int offsetTFP = region * setup_->tfpNumChannel(); + const int offsetStub = region * setup_->numLayers(); + const tt::StreamTrack& streamKF = inputs[region]; + const tt::Stream& streamTQ = inputsAdd[region]; + for (int channel = 0; channel < setup_->tfpNumChannel(); channel++) + outputs[offsetTFP + channel] = std::deque(streamKF.size(), nullptr); + for (int frame = 0; frame < (int)streamKF.size(); frame++) { + const tt::FrameTrack& frameTrack = streamKF[frame]; + const tt::Frame& frameTQ = streamTQ[frame]; + if (frameTrack.first.isNull()) + continue; + std::vector ttStubRefs; + ttStubRefs.reserve(setup_->numLayers()); + for (int layer = 0; layer < setup_->numLayers(); layer++) { + const TTStubRef& ttStubRef = stubs[offsetStub + layer][frame].first; + if (ttStubRef.isNonnull()) + ttStubRefs.push_back(ttStubRef); + } + tracks_.emplace_back(frameTrack, frameTQ, ttStubRefs, dataFormats_, trackQuality_); + Track& track = tracks_.back(); + outputs[offsetTFP + track.channel_][frame] = track.valid_ ? &track : nullptr; + } + // remove all gaps between end and last track + for (int channel = 0; channel < setup_->tfpNumChannel(); channel++) { + std::deque input = outputs[offsetTFP + channel]; + for (auto it = input.end(); it != input.begin();) + it = (*--it) ? input.begin() : input.erase(it); + } + } + } + + // emualte data format f/w + void TrackFindingProcessor::produce(std::vector>& inputs, tt::StreamsTrack& outputs) const { + for (int channel = 0; channel < static_cast(inputs.size()); channel++) { + std::deque& input = inputs[channel]; + std::deque stack; + std::deque output; + // clock accurate firmware emulation, each while trip describes one clock tick, one stub in and one stub out per tick + while (!input.empty() || !stack.empty()) { + output.emplace_back(tt::FrameTrack()); + tt::FrameTrack& frame = output.back(); + Track* track = pop_front(input); + if (track) + for (const PartialFrame& pf : track->partials_) + stack.emplace_back(track->ttTrackRef_, pf); + TTBV ttBV; + for (int i = 0; i < partial_out; i++) { + if (stack.empty()) { + ttBV += TTBV(0, partial_width); + continue; + } + const PartialFrameTrack& pft = stack.front(); + frame.first = pft.first; + ttBV += TTBV(pft.second.to_string()); + stack.pop_front(); + } + frame.second = ttBV.bs(); + } + // perorm truncation + if (setup_->enableTruncation() && static_cast(output.size()) > setup_->numFramesIOHigh()) + output.resize(setup_->numFramesIOHigh()); + outputs[channel] = tt::StreamTrack(output.begin(), output.end()); + } + } + + // produce TTTracks + void TrackFindingProcessor::produce(const tt::StreamsTrack& inputs, tt::TTTracks& outputs) const { + // collect input TTTrackRefs + std::vector ttTrackRefs; + ttTrackRefs.reserve(tracks_.size()); + const TTTrack* last = nullptr; + for (const tt::StreamTrack& stream : inputs) { + for (const tt::FrameTrack& frame : stream) { + const TTTrackRef& ttTrackRef = frame.first; + if (frame.first.isNull() || last == ttTrackRef.get()) + continue; + last = ttTrackRef.get(); + ttTrackRefs.push_back(ttTrackRef); + } + } + // convert input TTTrackRefs into output TTTracks + outputs.reserve(ttTrackRefs.size()); + for (const TTTrackRef& ttTrackRef : ttTrackRefs) { + auto match = [&ttTrackRef](const Track& track) { return track.ttTrackRef_ == ttTrackRef; }; + const auto it = std::find_if(tracks_.begin(), tracks_.end(), match); + // TTTrack conversion + const int region = ttTrackRef->phiSector(); + const double aRinv = -2. * it->inv2R_; + const double aphi = tt::deltaPhi(it->phiT_ - it->inv2R_ * setup_->chosenRofPhi() + region * setup_->baseRegion()); + const double aTanLambda = it->cot_; + const double az0 = it->zT_ - it->cot_ * setup_->chosenRofZ(); + const double ad0 = -ttTrackRef->d0(); + const double aChi2xyfit = it->chi2rphi_; + const double aChi2zfit = it->chi2rz_; + const double trkMVA1 = (TTTrack_TrackWord::tqMVABins[it->mva_]); + static constexpr double trkMVA2 = 0.; + static constexpr double trkMVA3 = 0.; + const unsigned int aHitpattern = it->hitPattern_.val(); + const unsigned int nPar = ttTrackRef->nFitPars(); + outputs.emplace_back(aRinv, + aphi, + aTanLambda, + az0, + ad0, + aChi2xyfit, + aChi2zfit, + trkMVA1, + trkMVA2, + trkMVA3, + aHitpattern, + nPar, + bfield_); + TTTrack& ttTrack = outputs.back(); + ttTrack.setPhiSector(region); + ttTrack.setEtaSector(ttTrackRef->etaSector()); + ttTrack.setTrackSeedType(ttTrackRef->trackSeedType()); + ttTrack.setStubRefs(it->ttStubRefs_); + ttTrack.setStubPtConsistency(StubPtConsistency::getConsistency( + ttTrack, setup_->trackerGeometry(), setup_->trackerTopology(), bfield_, nPar)); + } + } + + // produce StreamsTrack + void TrackFindingProcessor::produce(const std::vector& inputs, tt::StreamsTrack& outputs) const { + int iTrk(-1); + const TTTrack* last = nullptr; + for (tt::StreamTrack& stream : outputs) { + for (tt::FrameTrack& frame : stream) { + const TTTrackRef& ttTrackRef = frame.first; + if (ttTrackRef.isNull()) + continue; + if (last != ttTrackRef.get()) + iTrk++; + last = ttTrackRef.get(); + frame.first = inputs[iTrk]; + } + } + } + + // remove and return first element of deque, returns nullptr if empty + template + T* TrackFindingProcessor::pop_front(std::deque& ts) const { + T* t = nullptr; + if (!ts.empty()) { + t = ts.front(); + ts.pop_front(); + } + return t; + } + +} // namespace trklet diff --git a/L1Trigger/TrackFindingTracklet/src/TrackMultiplexer.cc b/L1Trigger/TrackFindingTracklet/src/TrackMultiplexer.cc new file mode 100644 index 0000000000000..61ed6d355a793 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/TrackMultiplexer.cc @@ -0,0 +1,418 @@ +#include "L1Trigger/TrackFindingTracklet/interface/TrackMultiplexer.h" + +#include +#include +#include +#include +#include + +namespace trklet { + + TrackMultiplexer::TrackMultiplexer(const tt::Setup* setup, + const DataFormats* dataFormats, + const ChannelAssignment* channelAssignment, + const Settings* settings, + int region) + : setup_(setup), + dataFormats_(dataFormats), + channelAssignment_(channelAssignment), + settings_(settings), + region_(region), + input_(channelAssignment_->numChannelsTrack()) { + // unified tracklet digitisation granularity + baseUinv2R_ = .5 * settings_->kphi1() / settings_->kr() * pow(2, settings_->rinv_shift()); + baseUphiT_ = settings_->kphi1() * pow(2, settings_->phi0_shift()); + baseUcot_ = settings_->kz() / settings_->kr() * pow(2, settings_->t_shift()); + baseUzT_ = settings_->kz() * pow(2, settings_->z0_shift()); + baseUr_ = settings_->kr(); + baseUphi_ = settings_->kphi1(); + baseUz_ = settings_->kz(); + // DR input format digitisation granularity (identical to TMTT) + baseLinv2R_ = dataFormats->base(Variable::inv2R, Process::tm); + baseLphiT_ = dataFormats->base(Variable::phiT, Process::tm); + baseLzT_ = dataFormats->base(Variable::zT, Process::tm); + baseLr_ = dataFormats->base(Variable::r, Process::tm); + baseLphi_ = dataFormats->base(Variable::phi, Process::tm); + baseLz_ = dataFormats->base(Variable::z, Process::tm); + baseLcot_ = baseLz_ / baseLr_; + // Finer granularity (by powers of 2) than the TMTT one. Used to transform from Tracklet to TMTT base. + baseHinv2R_ = baseLinv2R_ * pow(2, floor(log2(baseUinv2R_ / baseLinv2R_))); + baseHphiT_ = baseLphiT_ * pow(2, floor(log2(baseUphiT_ / baseLphiT_))); + baseHzT_ = baseLzT_ * pow(2, floor(log2(baseUzT_ / baseLzT_))); + baseHr_ = baseLr_ * pow(2, floor(log2(baseUr_ / baseLr_))); + baseHphi_ = baseLphi_ * pow(2, floor(log2(baseUphi_ / baseLphi_))); + baseHz_ = baseLz_ * pow(2, floor(log2(baseUz_ / baseLz_))); + baseHcot_ = baseLcot_ * pow(2, floor(log2(baseUcot_ / baseLcot_))); + // calculate digitisation granularity used for inverted cot(theta) + const int baseShiftInvCot = ceil(log2(setup_->outerRadius() / setup_->hybridRangeR())) - setup_->widthDSPbu(); + baseInvCot_ = pow(2, baseShiftInvCot); + const int unusedMSBScot = + floor(log2(baseUcot_ * pow(2.0, channelAssignment_->tmWidthCot()) / 2. / setup_->maxCot())); + const int baseShiftScot = channelAssignment_->tmWidthCot() - unusedMSBScot - 1 - setup_->widthAddrBRAM18(); + baseScot_ = baseUcot_ * pow(2.0, baseShiftScot); + } + + // read in and organize input tracks and stubs + void TrackMultiplexer::consume(const tt::StreamsTrack& streamsTrack, const tt::StreamsStub& streamsStub) { + const int offsetTrack = region_ * channelAssignment_->numChannelsTrack(); + // count tracks and stubs to reserve container + int nTracks(0); + int nStubs(0); + for (int channel = 0; channel < channelAssignment_->numChannelsTrack(); channel++) { + const int channelTrack = offsetTrack + channel; + const int offsetStub = channelAssignment_->offsetStub(channelTrack); + const int numProjectionLayers = channelAssignment_->numProjectionLayers(channel); + const tt::StreamTrack& streamTrack = streamsTrack[channelTrack]; + input_[channel].reserve(streamTrack.size()); + for (int frame = 0; frame < static_cast(streamTrack.size()); frame++) { + if (streamTrack[frame].first.isNull()) + continue; + nTracks++; + for (int layer = 0; layer < numProjectionLayers; layer++) + if (streamsStub[offsetStub + layer][frame].first.isNonnull()) + nStubs++; + } + } + stubs_.reserve(nStubs + nTracks * channelAssignment_->numSeedingLayers()); + tracks_.reserve(nTracks); + // store tracks and stubs + for (int channel = 0; channel < channelAssignment_->numChannelsTrack(); channel++) { + const int numP = channelAssignment_->numProjectionLayers(channel); + const int channelTrack = offsetTrack + channel; + const int offsetStub = channelAssignment_->offsetStub(channelTrack); + const tt::StreamTrack& streamTrack = streamsTrack[channelTrack]; + std::vector& input = input_[channel]; + for (int frame = 0; frame < static_cast(streamTrack.size()); frame++) { + const TTTrackRef& ttTrackRef = streamTrack[frame].first; + if (ttTrackRef.isNull()) { + input.push_back(nullptr); + continue; + } + //convert track parameter + const double offset = region_ * setup_->baseRegion(); + double inv2R = digi(-ttTrackRef->rInv() / 2., baseUinv2R_); + const double phi0U = digi(tt::deltaPhi(ttTrackRef->phi() - offset + setup_->hybridRangePhi() / 2.), baseUphiT_); + const double phi0S = digi(phi0U - setup_->hybridRangePhi() / 2., baseUphiT_); + double cot = digi(ttTrackRef->tanL(), baseUcot_); + double z0 = digi(ttTrackRef->z0(), baseUzT_); + double phiT = digi(phi0S + inv2R * digi(setup_->chosenRofPhi(), baseUr_), baseUphiT_); + double zT = digi(z0 + cot * digi(setup_->chosenRofZ(), baseUr_), baseUzT_); + // convert stubs + std::vector stubs; + stubs.reserve(channelAssignment_->numSeedingLayers() + numP); + for (int layer = 0; layer < numP; layer++) { + const tt::FrameStub& frameStub = streamsStub[offsetStub + layer][frame]; + const TTStubRef& ttStubRef = frameStub.first; + if (ttStubRef.isNull()) + continue; + // parse residuals from tt::Frame and take layerId from tt::TTStubRef + const bool barrel = setup_->barrel(ttStubRef); + const int layerIdTracklet = setup_->trackletLayerId(ttStubRef); + const double basePhi = barrel ? settings_->kphi1() : settings_->kphi(layerIdTracklet); + const double baseRZ = barrel ? settings_->kz(layerIdTracklet) : settings_->kz(); + const int widthRZ = barrel ? settings_->zresidbits() : settings_->rresidbits(); + TTBV hw(frameStub.second); + const TTBV hwRZ(hw, widthRZ, 0, true); + hw >>= widthRZ; + const TTBV hwPhi(hw, settings_->phiresidbits(), 0, true); + hw >>= settings_->phiresidbits(); + const int indexLayerId = setup_->indexLayerId(ttStubRef); + const tt::SensorModule::Type type = setup_->type(ttStubRef); + const int widthR = setup_->tbWidthR(type); + const double baseR = setup_->hybridBaseR(type); + const TTBV hwR(hw, widthR, 0, barrel); + hw >>= widthR; + const TTBV hwStubId(hw, channelAssignment_->tmWidthStubId(), 0, false); + const int stubId = hwStubId.val(); + double r = hwR.val(baseR) + (barrel ? setup_->hybridLayerR(indexLayerId) : 0.); + if (type == tt::SensorModule::Disk2S) + r = setup_->disk2SR(indexLayerId, r); + r = digi(r - setup_->chosenRofPhi(), baseUr_); + double phi = hwPhi.val(basePhi); + if (basePhi > baseUphi_) + phi += baseUphi_ / 2.; + double z = digi(hwRZ.val(baseRZ) * (barrel ? 1. : -cot), baseUz_); + // determine module type + bool psTilt = setup_->psModule(ttStubRef); + if (barrel) { + const double posZ = (r + digi(setup_->chosenRofPhi(), baseUr_)) * cot + z0 + z; + const int indexLayerId = setup_->indexLayerId(ttStubRef); + const double limit = setup_->tiltedLayerLimitZ(indexLayerId); + psTilt = std::abs(posZ) < limit; + } + stubs_.emplace_back(ttStubRef, layerIdTracklet, stubId, r, phi, z, psTilt); + stubs.push_back(&stubs_.back()); + } + if (setup_->kfUseTTStubParameters()) { + std::vector seedTTStubRefs; + seedTTStubRefs.reserve(channelAssignment_->numSeedingLayers()); + std::map mapStubs; + for (TTStubRef& ttStubRef : ttTrackRef->getStubRefs()) + mapStubs.emplace(setup_->layerId(ttStubRef), ttStubRef); + for (int layer : channelAssignment_->seedingLayers(ttTrackRef->trackSeedType())) + seedTTStubRefs.push_back(mapStubs[layer]); + const GlobalPoint gp0 = setup_->stubPos(seedTTStubRefs[0]); + const GlobalPoint gp1 = setup_->stubPos(seedTTStubRefs[1]); + const double dH = gp1.perp() - gp0.perp(); + const double H1m0 = (gp1.perp() - setup_->chosenRofPhi()) * tt::deltaPhi(gp0.phi() - offset); + const double H0m1 = (gp0.perp() - setup_->chosenRofPhi()) * tt::deltaPhi(gp1.phi() - offset); + const double H3m2 = (gp1.perp() - setup_->chosenRofZ()) * gp0.z(); + const double H2m3 = (gp0.perp() - setup_->chosenRofZ()) * gp1.z(); + const double dinv2R = inv2R - (gp1.phi() - gp0.phi()) / dH; + const double dcot = cot - (gp1.z() - gp0.z()) / dH; + const double dphiT = phiT - (H1m0 - H0m1) / dH; + const double dzT = zT - (H3m2 - H2m3) / dH; + inv2R -= dinv2R; + cot -= dcot; + phiT -= dphiT; + zT -= dzT; + z0 = zT - cot * setup_->chosenRofZ(); + // adjust stub residuals by track parameter shifts + for (Stub* stub : stubs) { + const double dphi = digi(dphiT + stub->r_ * dinv2R, baseUphi_); + const double r = stub->r_ + digi(setup_->chosenRofPhi() - setup_->chosenRofZ(), baseUr_); + const double dz = digi(dzT + r * dcot, baseUz_); + stub->phi_ = digi(stub->phi_ + dphi, baseUphi_); + stub->z_ = digi(stub->z_ + dz, baseUz_); + } + } + // create fake seed stubs, since TrackBuilder doesn't output these stubs, required by the KF. + for (int seedingLayer = 0; seedingLayer < channelAssignment_->numSeedingLayers(); seedingLayer++) { + const int channelStub = numP + seedingLayer; + const tt::FrameStub& frameStub = streamsStub[offsetStub + channelStub][frame]; + const TTStubRef& ttStubRef = frameStub.first; + const int trackletLayerId = setup_->trackletLayerId(ttStubRef); + const int layerId = channelAssignment_->layerId(channel, channelStub); + const int stubId = TTBV(frameStub.second).val(channelAssignment_->tmWidthStubId()); + const bool barrel = setup_->barrel(ttStubRef); + double r; + if (barrel) { + const int index = layerId - setup_->offsetLayerId(); + const double layer = digi(setup_->hybridLayerR(index), baseUr_); + const double z = digi(z0 + layer * cot, baseUz_); + if (std::abs(z) < digi(setup_->tbBarrelHalfLength(), baseUz_) || index > 0) + r = digi(setup_->hybridLayerR(index) - setup_->chosenRofPhi(), baseUr_); + else { + r = digi(setup_->innerRadius() - setup_->chosenRofPhi(), baseUr_); + } + } else { + const int index = layerId - setup_->offsetLayerId() - setup_->offsetLayerDisks(); + const double side = cot < 0. ? -1. : 1.; + const double disk = digi(setup_->hybridDiskZ(index), baseUzT_); + const double invCot = digi(1. / digi(std::abs(cot), baseScot_), baseInvCot_); + const double offset = digi(setup_->chosenRofPhi(), baseUr_); + r = digi((disk - side * z0) * invCot - offset, baseUr_); + } + double phi = 0.; + double z = 0.; + // determine module type + bool psTilt; + if (barrel) { + const int indexLayerId = setup_->indexLayerId(ttStubRef); + const double limit = digi(setup_->tiltedLayerLimitZ(indexLayerId), baseUz_); + const double posR = digi(setup_->hybridLayerR(layerId - setup_->offsetLayerId()), baseUr_); + const double posZ = digi(posR * cot + z0, baseUz_); + psTilt = std::abs(posZ) < limit; + } else + psTilt = true; + stubs_.emplace_back(ttStubRef, trackletLayerId, stubId, r, phi, z, psTilt); + stubs.push_back(&stubs_.back()); + } + if (setup_->kfUseTTStubResiduals()) { + for (Stub* stub : stubs) { + const GlobalPoint gp = setup_->stubPos(stub->ttStubRef_); + stub->r_ = gp.perp() - setup_->chosenRofPhi(); + stub->phi_ = tt::deltaPhi(gp.phi() - region_ * setup_->baseRegion()); + stub->phi_ -= phiT + stub->r_ * inv2R; + stub->z_ = gp.z() - (z0 + gp.perp() * cot); + } + } + // non linear corrections + if (setup_->kfApplyNonLinearCorrection()) { + for (Stub* stub : stubs) { + const double d = inv2R * (stub->r_ + setup_->chosenRofPhi()); + const double dPhi = std::asin(d) - d; + stub->phi_ -= dPhi; + stub->z_ -= dPhi / inv2R * cot; + } + } + // check track validity + bool valid = true; + // kill truncated rtacks + if (setup_->enableTruncation() && frame >= setup_->numFramesHigh()) + valid = false; + // kill tracks outside of fiducial range + if (!dataFormats_->format(Variable::phiT, Process::tm).inRange(phiT, true)) + valid = false; + if (!dataFormats_->format(Variable::zT, Process::tm).inRange(zT, true)) + valid = false; + // stub range checks + for (Stub* stub : stubs) { + if (!dataFormats_->format(Variable::phi, Process::tm).inRange(stub->phi_, true)) + stub->valid_ = false; + if (!dataFormats_->format(Variable::z, Process::tm).inRange(stub->z_, true)) + stub->valid_ = false; + } + // layer check + std::set layers, layersPS; + for (Stub* stub : stubs) { + if (!stub->valid_) + continue; + const int layerId = setup_->layerId(stub->ttStubRef_); + layers.insert(layerId); + if (setup_->psModule(stub->ttStubRef_)) + layersPS.insert(layerId); + } + if (static_cast(layers.size()) < setup_->kfMinLayers() || + static_cast(layersPS.size()) < setup_->kfMinLayersPS()) + valid = false; + // create track + tracks_.emplace_back(ttTrackRef, valid, channel, inv2R, phiT, cot, zT, stubs); + input.push_back(&tracks_.back()); + } + } + } + + // fill output products + void TrackMultiplexer::produce(tt::StreamsTrack& streamsTrack, tt::StreamsStub& streamsStub) { + // base transform into high precision TMTT format + for (Track& track : tracks_) { + track.inv2R_ = redigi(track.inv2R_, baseUinv2R_, baseHinv2R_, setup_->widthDSPbu()); + track.phiT_ = redigi(track.phiT_, baseUphiT_, baseHphiT_, setup_->widthDSPbu()); + track.cot_ = redigi(track.cot_, baseUcot_, baseHcot_, setup_->widthDSPbu()); + track.zT_ = redigi(track.zT_, baseUzT_, baseHzT_, setup_->widthDSPbu()); + for (Stub* stub : track.stubs_) { + stub->r_ = redigi(stub->r_, baseUr_, baseHr_, setup_->widthDSPbu()); + stub->phi_ = redigi(stub->phi_, baseUphi_, baseHphi_, setup_->widthDSPbu()); + stub->z_ = redigi(stub->z_, baseUz_, baseHz_, setup_->widthDSPbu()); + } + } + // base transform into TMTT format + for (Track& track : tracks_) { + // store track parameter shifts + const double dinv2R = digi(track.inv2R_ - digi(track.inv2R_, baseLinv2R_), baseHinv2R_); + const double dphiT = digi(track.phiT_ - digi(track.phiT_, baseLphiT_), baseHphiT_); + const double dcot = track.cot_ - digi(digi(track.zT_, baseLzT_) / setup_->chosenRofZ(), baseHcot_); + const double dzT = digi(track.zT_ - digi(track.zT_, baseLzT_), baseHzT_); + // shift track parameter; + track.inv2R_ -= dinv2R; + track.phiT_ -= dphiT; + track.cot_ -= dcot; + track.zT_ -= dzT; + // range checks + if (!dataFormats_->format(Variable::inv2R, Process::tm).inRange(track.inv2R_, true)) + track.valid_ = false; + if (!dataFormats_->format(Variable::phiT, Process::tm).inRange(track.phiT_, true)) + track.valid_ = false; + if (!dataFormats_->format(Variable::zT, Process::tm).inRange(track.zT_, true)) + track.valid_ = false; + // adjust stub residuals by track parameter shifts + for (Stub* stub : track.stubs_) { + const double dphi = digi(dphiT + stub->r_ * dinv2R, baseHphi_); + const double r = stub->r_ + digi(setup_->chosenRofPhi() - setup_->chosenRofZ(), baseHr_); + const double dz = digi(dzT + r * dcot, baseHz_); + stub->phi_ = digi(stub->phi_ + dphi, baseLphi_); + stub->z_ = digi(stub->z_ + dz, baseLz_); + // range checks + if (!dataFormats_->format(Variable::phi, Process::tm).inRange(stub->phi_, true)) + stub->valid_ = false; + if (!dataFormats_->format(Variable::z, Process::tm).inRange(stub->z_, true)) + stub->valid_ = false; + } + } + // emualte clock domain crossing + static constexpr int ticksPerGap = 3; + static constexpr int gapPos = 1; + std::vector> streams(channelAssignment_->numChannelsTrack()); + for (int channel = 0; channel < channelAssignment_->numChannelsTrack(); channel++) { + int iTrack(0); + std::deque& stream = streams[channel]; + const std::vector& intput = input_[channel]; + for (int tick = 0; iTrack < (int)intput.size(); tick++) { + Track* track = tick % ticksPerGap != gapPos ? intput[iTrack++] : nullptr; + stream.push_back(track && track->valid_ ? track : nullptr); + } + } + // remove all gaps between end and last track + for (std::deque& stream : streams) + for (auto it = stream.end(); it != stream.begin();) + it = (*--it) ? stream.begin() : stream.erase(it); + // route into single channel + std::deque accepted; + std::vector> stacks(channelAssignment_->numChannelsTrack()); + // clock accurate firmware emulation, each while trip describes one clock tick, one stub in and one stub out per tick + while (!std::all_of(streams.begin(), streams.end(), [](const std::deque& tracks) { + return tracks.empty(); + }) || !std::all_of(stacks.begin(), stacks.end(), [](const std::deque& tracks) { return tracks.empty(); })) { + // fill input fifos + for (int channel = 0; channel < channelAssignment_->numChannelsTrack(); channel++) { + Track* track = pop_front(streams[channel]); + if (track) + stacks[channel].push_back(track); + } + // merge input fifos to one stream, prioritizing lower input channel over higher channel, affects DR + bool nothingToRoute(true); + for (int channel : channelAssignment_->tmMuxOrder()) { + Track* track = pop_front(stacks[channel]); + if (track) { + nothingToRoute = false; + accepted.push_back(track); + break; + } + } + if (nothingToRoute) + accepted.push_back(nullptr); + } + // truncate if desired + if (setup_->enableTruncation() && static_cast(accepted.size()) > setup_->numFramesHigh()) + accepted.resize(setup_->numFramesHigh()); + // remove all gaps between end and last track + for (auto it = accepted.end(); it != accepted.begin();) + it = (*--it) ? accepted.begin() : accepted.erase(it); + // store helper + auto frameTrack = [this](Track* track) { return track->valid_ ? track->frame(dataFormats_) : tt::FrameTrack(); }; + auto frameStub = [this](Track* track, int layer) { + const auto it = std::find_if( + track->stubs_.begin(), track->stubs_.end(), [layer](Stub* stub) { return stub->layer_ == layer; }); + if (!track->valid_ || it == track->stubs_.end() || !(*it)->valid_) + return tt::FrameStub(); + + return (*it)->frame(dataFormats_); + }; + const int offsetStub = region_ * channelAssignment_->tmNumLayers(); + // fill output tracks and stubs + streamsTrack[region_].reserve(accepted.size()); + for (int layer = 0; layer < channelAssignment_->tmNumLayers(); layer++) + streamsStub[offsetStub + layer].reserve(accepted.size()); + for (Track* track : accepted) { + if (!track) { // fill gaps + streamsTrack[region_].emplace_back(tt::FrameTrack()); + for (int layer = 0; layer < channelAssignment_->tmNumLayers(); layer++) + streamsStub[offsetStub + layer].emplace_back(tt::FrameStub()); + continue; + } + streamsTrack[region_].emplace_back(frameTrack(track)); + for (int layer = 0; layer < channelAssignment_->tmNumLayers(); layer++) + streamsStub[offsetStub + layer].emplace_back(frameStub(track, layer)); + } + } + + // remove and return first element of deque, returns nullptr if empty + template + T* TrackMultiplexer::pop_front(std::deque& ts) const { + T* t = nullptr; + if (!ts.empty()) { + t = ts.front(); + ts.pop_front(); + } + return t; + } + + // basetransformation of val from baseLow into baseHigh using widthMultiplier bit multiplication + double TrackMultiplexer::redigi(double val, double baseLow, double baseHigh, int widthMultiplier) const { + const double base = std::pow(2, 1 - widthMultiplier); + const double transform = digi(baseLow / baseHigh, base); + return (std::floor(val * transform / baseLow) + .5) * baseHigh; + } + +} // namespace trklet diff --git a/L1Trigger/TrackFindingTracklet/src/TrackletConfigBuilder.cc b/L1Trigger/TrackFindingTracklet/src/TrackletConfigBuilder.cc index 196747ab9e415..c84581a47a33d 100644 --- a/L1Trigger/TrackFindingTracklet/src/TrackletConfigBuilder.cc +++ b/L1Trigger/TrackFindingTracklet/src/TrackletConfigBuilder.cc @@ -1069,10 +1069,16 @@ void TrackletConfigBuilder::writeASMemories(std::ostream& os, std::ostream& memo if (max - min >= 2) { ext = "M"; - if (iReg == min) + if (iReg == min) { + if (iReg % 2 == 0) + continue; ext = "R"; - if (iReg == max) + } + if (iReg == max) { + if (iReg % 2 == 1) + continue; ext = "L"; + } } if (max - min == 1) { diff --git a/L1Trigger/TrackFindingTracklet/src/TrackletProcessorDisplaced.cc b/L1Trigger/TrackFindingTracklet/src/TrackletProcessorDisplaced.cc index 903c62cf0a124..0c8a1424264e0 100644 --- a/L1Trigger/TrackFindingTracklet/src/TrackletProcessorDisplaced.cc +++ b/L1Trigger/TrackFindingTracklet/src/TrackletProcessorDisplaced.cc @@ -23,10 +23,13 @@ using namespace trklet; // This module takes in collections of stubs within a phi region and a // displaced seed name and tries to create that displaced seed out of the stubs // -// Update: Claire Savard, Oct. 2024 +// Update: Claire Savard, Nov. 2024 TrackletProcessorDisplaced::TrackletProcessorDisplaced(string name, Settings const& settings, Globals* globals) - : TrackletCalculatorDisplaced(name, settings, globals), innerTable_(settings), innerThirdTable_(settings) { + : TrackletCalculatorDisplaced(name, settings, globals), + trpbuffer_(CircularBuffer(3), 0, 0, 0, 0), + innerTable_(settings), + innerThirdTable_(settings) { innerallstubs_.clear(); middleallstubs_.clear(); outerallstubs_.clear(); @@ -58,10 +61,9 @@ TrackletProcessorDisplaced::TrackletProcessorDisplaced(string name, Settings con // set TC index iTC_ = region; - constexpr int TCIndexMin = 128; - constexpr int TCIndexMax = 191; - TCIndex_ = (iSeed_ << 4) + iTC_; - assert(TCIndex_ >= TCIndexMin && TCIndex_ < TCIndexMax); + TCIndex_ = (iSeed_ << settings.nbitsseed()) + iTC_; + + maxStep_ = settings_.maxStep("TPD"); } void TrackletProcessorDisplaced::addOutputProjection(TrackletProjectionsMemory*& outputProj, MemoryBase* memory) { @@ -156,177 +158,249 @@ void TrackletProcessorDisplaced::addInput(MemoryBase* memory, string input) { } void TrackletProcessorDisplaced::execute(unsigned int iSector, double phimin, double phimax) { - unsigned int countall = 0; - unsigned int countsel = 0; - phimin_ = phimin; phimax_ = phimax; iSector_ = iSector; - // loop over the middle stubs in the potential seed - for (unsigned int midmem = 0; midmem < middleallstubs_.size(); midmem++) { - for (unsigned int i = 0; i < middleallstubs_[midmem]->nStubs(); i++) { - const Stub* midallstub = middleallstubs_[midmem]->getStub(i); + unsigned int countall = 0; + unsigned int countsel = 0; + int donecount = 0; + + // set the triplet engine units and buffer + TripletEngineUnit trpunit(&settings_, layerdisk1_, layerdisk2_, layerdisk3_, iSeed_, innervmstubs_, outervmstubs_); + trpunits_.resize(settings_.trpunits(iSeed_), trpunit); + trpbuffer_ = tuple, unsigned int, unsigned int, unsigned int, unsigned int>( + CircularBuffer(3), 0, 0, 0, middleallstubs_.size()); + + // reset the trpunits + for (auto& trpunit : trpunits_) { + trpunit.reset(); + } + + // reset the tebuffer + std::get<0>(trpbuffer_).reset(); + std::get<1>(trpbuffer_) = 0; + std::get<2>(trpbuffer_) = std::get<3>(trpbuffer_); + + TrpEData trpdata; + TrpEData trpdata__; + TrpEData trpdata___; + bool goodtrpdata = false; + bool goodtrpdata__ = false; + bool goodtrpdata___ = false; + + bool trpbuffernearfull; + for (unsigned int istep = 0; istep < maxStep_; istep++) { + CircularBuffer& trpdatabuffer = std::get<0>(trpbuffer_); + trpbuffernearfull = trpdatabuffer.nearfull(); + + // + // First block here checks if there is a trpunit with data that should be used + // to calculate the tracklet parameters + // + + // set pointer to the last filled trpunit + TripletEngineUnit* trpunitptr = nullptr; + for (auto& trpunit : trpunits_) { + trpunit.setNearFull(); + if (!trpunit.empty()) { + trpunitptr = &trpunit; + } + } + + if (trpunitptr != nullptr) { + auto stubtriplet = trpunitptr->read(); + + countall++; + + const Stub* innerFPGAStub = std::get<0>(stubtriplet); + const Stub* middleFPGAStub = std::get<1>(stubtriplet); + const Stub* outerFPGAStub = std::get<2>(stubtriplet); + + const L1TStub* innerStub = innerFPGAStub->l1tstub(); + const L1TStub* middleStub = middleFPGAStub->l1tstub(); + const L1TStub* outerStub = outerFPGAStub->l1tstub(); + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "TrackletProcessorDisplaced execute " << getName() << "[" << iSector_ << "]"; + } + + // check if the seed made from the 3 stubs is valid + bool accept = false; + if (iSeed_ == Seed::L2L3L4 || iSeed_ == Seed::L4L5L6) + accept = LLLSeeding(innerFPGAStub, innerStub, middleFPGAStub, middleStub, outerFPGAStub, outerStub); + else if (iSeed_ == Seed::L2L3D1) + accept = LLDSeeding(innerFPGAStub, innerStub, middleFPGAStub, middleStub, outerFPGAStub, outerStub); + else if (iSeed_ == Seed::D1D2L2) + accept = DDLSeeding(innerFPGAStub, innerStub, middleFPGAStub, middleStub, outerFPGAStub, outerStub); + + if (accept) + countsel++; + + if (trackletpars_->nTracklets() >= settings_.ntrackletmax()) { + edm::LogVerbatim("Tracklet") << "Will break on number of tracklets in " << getName(); + assert(0); + break; + } + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "TrackletProcessor execute done"; + } + } + + // + // The second block fills the trpunit if data in buffer and process TripletEngineUnit step + // + // + + bool notemptytrpbuffer = !trpdatabuffer.empty(); + for (auto& trpunit : trpunits_) { + if (trpunit.idle() && notemptytrpbuffer) { // only fill one idle unit every step + trpunit.init(std::get<0>(trpbuffer_).read()); + notemptytrpbuffer = false; //prevent initializing another triplet engine unit + } + trpunit.step(); + } + + // + // The third block here checks if we have input stubs to process + // + // + + if (goodtrpdata___) + trpdatabuffer.store(trpdata___); + goodtrpdata = false; + + unsigned int& istub = std::get<1>(trpbuffer_); + unsigned int& midmem = std::get<2>(trpbuffer_); + unsigned int midmemend = std::get<4>(trpbuffer_); + + if ((!trpbuffernearfull) && midmem < midmemend && istub < middleallstubs_[midmem]->nStubs()) { + const Stub* stub = middleallstubs_[midmem]->getStub(istub); if (settings_.debugTracklet()) { edm::LogVerbatim("Tracklet") << "In " << getName() << " have middle stub"; } // get r/z index of the middle stub - int indexz = (((1 << (midallstub->z().nbits() - 1)) + midallstub->z().value()) >> - (midallstub->z().nbits() - nbitszfinebintable_)); + int indexz = (((1 << (stub->z().nbits() - 1)) + stub->z().value()) >> (stub->z().nbits() - nbitszfinebintable_)); int indexr = -1; - bool negdisk = (midallstub->disk().value() < 0); // check if disk in negative z region - if (layerdisk1_ >= LayerDisk::D1) { // if a disk + bool negdisk = (stub->disk().value() < 0); // check if disk in negative z region + if (layerdisk1_ >= LayerDisk::D1) { // if a disk if (negdisk) indexz = (1 << nbitszfinebintable_) - indexz; - indexr = midallstub->r().value(); - if (midallstub->isPSmodule()) { - indexr = midallstub->r().value() >> (midallstub->r().nbits() - nbitsrfinebintable_); + indexr = stub->r().value(); + if (stub->isPSmodule()) { + indexr = stub->r().value() >> (stub->r().nbits() - nbitsrfinebintable_); } } else { // else a layer - indexr = (((1 << (midallstub->r().nbits() - 1)) + midallstub->r().value()) >> - (midallstub->r().nbits() - nbitsrfinebintable_)); + indexr = (((1 << (stub->r().nbits() - 1)) + stub->r().value()) >> (stub->r().nbits() - nbitsrfinebintable_)); } - assert(indexz >= 0); - assert(indexr >= 0); - assert(indexz < (1 << nbitszfinebintable_)); - assert(indexr < (1 << nbitsrfinebintable_)); - // create lookupbits that define projections from middle stub - unsigned int lutwidth = settings_.lutwidthtabextended(0, iSeed_); int lutval = -1; const auto& lutshift = innerTable_.nbits(); lutval = innerTable_.lookup((indexz << nbitsrfinebintable_) + indexr); int lutval2 = innerThirdTable_.lookup((indexz << nbitsrfinebintable_) + indexr); if (lutval != -1 && lutval2 != -1) lutval += (lutval2 << lutshift); - if (lutval == -1) - continue; - FPGAWord lookupbits(lutval, lutwidth, true, __LINE__, __FILE__); - - // get r/z bins for projection into outer layer/disk - int nbitsrzbin = N_RZBITS; - if (iSeed_ == Seed::D1D2L2) - nbitsrzbin--; - int rzbinfirst = lookupbits.bits(0, NFINERZBITS); - int next = lookupbits.bits(NFINERZBITS, 1); - int rzdiffmax = lookupbits.bits(NFINERZBITS + 1 + nbitsrzbin, NFINERZBITS); - - int start = lookupbits.bits(NFINERZBITS + 1, nbitsrzbin); // first rz bin projection - if (iSeed_ == Seed::D1D2L2 && negdisk) // if projecting into disk - start += (1 << nbitsrzbin); - int last = start + next; // last rz bin projection - - if (settings_.debugTracklet()) { - edm::LogVerbatim("Tracklet") << "Will look in r/z bins for outer stub " << start << " to " << last << endl; - } - // loop over outer stubs that the middle stub can project to - for (int ibin = start; ibin <= last; ibin++) { - for (unsigned int outmem = 0; outmem < outervmstubs_.size(); outmem++) { - for (unsigned int j = 0; j < outervmstubs_[outmem]->nVMStubsBinned(ibin); j++) { - if (settings_.debugTracklet()) - edm::LogVerbatim("Tracklet") << "In " << getName() << " have outer stub" << endl; - - const VMStubTE& outvmstub = outervmstubs_[outmem]->getVMStubTEBinned(ibin, j); - - // check if r/z of outer stub is within projection range - int rzbin = (outvmstub.vmbits().value() & (settings_.NLONGVMBINS() - 1)); - if (start != ibin) - rzbin += 8; - if (rzbin < rzbinfirst || rzbin - rzbinfirst > rzdiffmax) { - if (settings_.debugTracklet()) { - edm::LogVerbatim("Tracklet") << "Outer stub rejected because of wrong r/z bin"; - } - continue; - } - - // get r/z bins for projection into third layer/disk - int nbitsrzbin_ = N_RZBITS; - int next_ = lookupbits.bits(lutshift + NFINERZBITS, 1); - - int start_ = lookupbits.bits(lutshift + NFINERZBITS + 1, nbitsrzbin_); // first rz bin projection - if (iSeed_ == Seed::D1D2L2 && negdisk) // if projecting from disk into layer - start_ = settings_.NLONGVMBINS() - 1 - start_ - next_; - int last_ = start_ + next_; // last rz bin projection - - if (settings_.debugTracklet()) { - edm::LogVerbatim("Tracklet") - << "Will look in rz bins for inner stub " << start_ << " to " << last_ << endl; - } - - // loop over inner stubs that the middle stub can project to - for (int ibin_ = start_; ibin_ <= last_; ibin_++) { - for (unsigned int inmem = 0; inmem < innervmstubs_.size(); inmem++) { - for (unsigned int k = 0; k < innervmstubs_[inmem]->nVMStubsBinned(ibin_); k++) { - if (settings_.debugTracklet()) - edm::LogVerbatim("Tracklet") << "In " << getName() << " have inner stub" << endl; - - const VMStubTE& invmstub = innervmstubs_[inmem]->getVMStubTEBinned(ibin_, k); - - countall++; - - const Stub* innerFPGAStub = invmstub.stub(); - const Stub* middleFPGAStub = midallstub; - const Stub* outerFPGAStub = outvmstub.stub(); - - const L1TStub* innerStub = innerFPGAStub->l1tstub(); - const L1TStub* middleStub = middleFPGAStub->l1tstub(); - const L1TStub* outerStub = outerFPGAStub->l1tstub(); - - if (settings_.debugTracklet()) { - edm::LogVerbatim("Tracklet") - << "triplet seeding\n" - << innerFPGAStub->strbare() << middleFPGAStub->strbare() << outerFPGAStub->strbare() - << innerStub->stubword() << middleStub->stubword() << outerStub->stubword() - << innerFPGAStub->layerdisk() << middleFPGAStub->layerdisk() << outerFPGAStub->layerdisk(); - edm::LogVerbatim("Tracklet") - << "TrackletCalculatorDisplaced execute " << getName() << "[" << iSector_ << "]"; - } - - // check if the seed made from the 3 stubs is valid - bool accept = false; - if (iSeed_ == Seed::L2L3L4 || iSeed_ == Seed::L4L5L6) - accept = LLLSeeding(innerFPGAStub, innerStub, middleFPGAStub, middleStub, outerFPGAStub, outerStub); - else if (iSeed_ == Seed::L2L3D1) - accept = LLDSeeding(innerFPGAStub, innerStub, middleFPGAStub, middleStub, outerFPGAStub, outerStub); - else if (iSeed_ == Seed::D1D2L2) - accept = DDLSeeding(innerFPGAStub, innerStub, middleFPGAStub, middleStub, outerFPGAStub, outerStub); - - if (accept) - countsel++; - - if (settings_.debugTracklet()) { - edm::LogVerbatim("Tracklet") << "TrackletCalculatorDisplaced execute done"; - } - if (countall >= settings_.maxStep("TPD")) - break; - } - if (countall >= settings_.maxStep("TPD")) - break; - } - if (countall >= settings_.maxStep("TPD")) - break; - } - if (countall >= settings_.maxStep("TPD")) - break; + if (lutval != -1) { + unsigned int lutwidth = settings_.lutwidthtabextended(0, iSeed_); + FPGAWord lookupbits(lutval, lutwidth, true, __LINE__, __FILE__); + + // get r/z bins for projection into outer layer/disk + int nbitsrzbin_out = N_RZBITS; + if (iSeed_ == Seed::D1D2L2) + nbitsrzbin_out--; + int rzbinfirst_out = lookupbits.bits(0, NFINERZBITS); + int rzdiffmax_out = lookupbits.bits(NFINERZBITS + 1 + nbitsrzbin_out, NFINERZBITS); + int start_out = lookupbits.bits(NFINERZBITS + 1, nbitsrzbin_out); // first rz bin projection + int next_out = lookupbits.bits(NFINERZBITS, 1); + if (iSeed_ == Seed::D1D2L2 && negdisk) // if projecting into disk + start_out += (1 << nbitsrzbin_out); + int last_out = start_out + next_out; // last rz bin projection + + // get r/z bins for projection into third (inner) layer/disk + int nbitsrzbin_in = N_RZBITS; + int start_in = lookupbits.bits(lutshift + NFINERZBITS + 1, nbitsrzbin_in); // first rz bin projection + int next_in = lookupbits.bits(lutshift + NFINERZBITS, 1); + if (iSeed_ == Seed::D1D2L2 && negdisk) // if projecting from disk into layer + start_in = settings_.NLONGVMBINS() - 1 - start_in - next_in; + int last_in = start_in + next_in; // last rz bin projection + + // fill trpdata with projection info of middle stub + trpdata.stub_ = stub; + trpdata.rzbinfirst_out_ = rzbinfirst_out; + trpdata.rzdiffmax_out_ = rzdiffmax_out; + trpdata.start_out_ = start_out; + trpdata.start_in_ = start_in; + + // fill projection bins info for single engine unit + trpdata.projbin_out_.clear(); + trpdata.projbin_in_.clear(); + for (int ibin_out = start_out; ibin_out <= last_out; ibin_out++) { + for (unsigned int outmem = 0; outmem < outervmstubs_.size(); outmem++) { + int nstubs_out = outervmstubs_[outmem]->nVMStubsBinned(ibin_out); + if (nstubs_out > 0) + trpdata.projbin_out_.emplace_back(tuple(ibin_out - start_out, outmem, nstubs_out)); + } + } + for (int ibin_in = start_in; ibin_in <= last_in; ibin_in++) { + for (unsigned int inmem = 0; inmem < innervmstubs_.size(); inmem++) { + int nstubs_in = innervmstubs_[inmem]->nVMStubsBinned(ibin_in); + if (nstubs_in > 0) + trpdata.projbin_in_.emplace_back(tuple(ibin_in - start_in, inmem, nstubs_in)); } - if (countall >= settings_.maxStep("TPD")) - break; } - if (countall >= settings_.maxStep("TPD")) - break; + + if (!trpdata.projbin_in_.empty() && !trpdata.projbin_out_.empty()) { + goodtrpdata = true; + } } - if (countall >= settings_.maxStep("TPD")) - break; + + istub++; + if (istub >= middleallstubs_[midmem]->nStubs()) { + istub = 0; + midmem++; + } + + } else if ((!trpbuffernearfull) && midmem < midmemend && istub == 0) + midmem++; + + goodtrpdata___ = goodtrpdata__; + goodtrpdata__ = goodtrpdata; + + trpdata___ = trpdata__; + trpdata__ = trpdata; + + // + // stop looping over istep if done + // + + bool done = true; + + if (midmem < midmemend || (!trpdatabuffer.empty())) { + done = false; + } + + for (auto& trpunit : trpunits_) { + if (!(trpunit.idle() && trpunit.empty())) + done = false; } - if (countall >= settings_.maxStep("TPD")) + + if (done) { + donecount++; + } + + //FIXME This should be done cleaner... Not too hard, but need to check fully the TEBuffer and TEUnit buffer. + if (donecount > 4) { break; + } } if (settings_.writeMonitorData("TPD")) { - globals_->ofstream("trackletprocessordisplaced.txt") << getName() << " " << countall << " " << countsel << endl; + globals_->ofstream("trackletprocessordisplaced.txt") + << getName() << " " << countall << " " << countsel << std::endl; } } diff --git a/L1Trigger/TrackFindingTracklet/src/TripletEngineUnit.cc b/L1Trigger/TrackFindingTracklet/src/TripletEngineUnit.cc new file mode 100644 index 0000000000000..709cf34bfd468 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/TripletEngineUnit.cc @@ -0,0 +1,112 @@ +#include "L1Trigger/TrackFindingTracklet/interface/TripletEngineUnit.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" + +using namespace trklet; + +// TripletEngineUnit +// +// This script sets a processing unit for the TrackletProcessorDisplaced +// based on information from the middle stub and its projections in and out, +// and a new triplet seed is checked and created for each processing step +// +// Author: Claire Savard, Nov. 2024 + +TripletEngineUnit::TripletEngineUnit(const Settings* const settings, + unsigned int layerdisk1, + unsigned int layerdisk2, + unsigned int layerdisk3, + unsigned int iSeed, + std::vector innervmstubs, + std::vector outervmstubs) + : settings_(settings), candtriplets_(3) { + idle_ = true; + layerdisk1_ = layerdisk1; + layerdisk2_ = layerdisk2; + layerdisk3_ = layerdisk3; + iSeed_ = iSeed; + innervmstubs_ = innervmstubs; + outervmstubs_ = outervmstubs; +} + +void TripletEngineUnit::init(const TrpEData& trpdata) { + trpdata_ = trpdata; + istub_out_ = 0; + istub_in_ = 0; + nproj_out_ = 0; + nproj_in_ = 0; + idle_ = false; + + assert(!trpdata_.projbin_out_.empty() && !trpdata_.projbin_in_.empty()); + std::tie(next_out_, outmem_, nstub_out_) = trpdata_.projbin_out_[0]; + std::tie(next_in_, inmem_, nstub_in_) = trpdata_.projbin_in_[0]; +} + +void TripletEngineUnit::reset() { + idle_ = true; + goodtriplet_ = false; + goodtriplet__ = false; + candtriplets_.reset(); +} + +void TripletEngineUnit::step() { + if (goodtriplet__) { + candtriplets_.store(candtriplet__); + } + + goodtriplet__ = goodtriplet_; + candtriplet__ = candtriplet_; + + goodtriplet_ = false; + + if (idle_ || nearfull_) { + return; + } + + // get inner and outer projected stub for certain next value + int ibin_out = trpdata_.start_out_ + next_out_; + int ibin_in = trpdata_.start_in_ + next_in_; + const VMStubTE& outervmstub = outervmstubs_[outmem_]->getVMStubTEBinned(ibin_out, istub_out_); + const VMStubTE& innervmstub = innervmstubs_[inmem_]->getVMStubTEBinned(ibin_in, istub_in_); + + // check if r/z of outer stub is within projection range + int rzbin = (outervmstub.vmbits().value() & (settings_->NLONGVMBINS() - 1)); + if (trpdata_.start_out_ != ibin_out) + rzbin += 8; + if (rzbin < trpdata_.rzbinfirst_out_ || rzbin - trpdata_.rzbinfirst_out_ > trpdata_.rzdiffmax_out_) { + if (settings_->debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Outer stub rejected because of wrong r/z bin"; + } + } else { + candtriplet_ = + std::tuple(innervmstub.stub(), trpdata_.stub_, outervmstub.stub()); + goodtriplet_ = true; + } + + // go to next projection (looping through all inner stubs for each outer stub) + istub_in_++; + if (istub_in_ >= nstub_in_) { // if gone through all in stubs, move to next in proj bin + nproj_in_++; + istub_in_ = 0; + if (nproj_in_ >= trpdata_.projbin_in_.size()) { // if gone through all in proj bins, move to next out stub + istub_out_++; + nproj_in_ = 0; + if (istub_out_ >= nstub_out_) { // if gone through all out stubs, move to next out proj bin + nproj_out_++; + istub_out_ = 0; + if (nproj_out_ >= + trpdata_.projbin_out_.size()) { // if gone through all out proj bins, reset everything and stop engine unit + istub_in_ = 0; + istub_out_ = 0; + nproj_in_ = 0; + nproj_out_ = 0; + idle_ = true; + return; + } + // get next out proj bin + std::tie(next_out_, outmem_, nstub_out_) = trpdata_.projbin_out_[nproj_out_]; + } + } + // get next in proj bin + std::tie(next_in_, inmem_, nstub_in_) = trpdata_.projbin_in_[nproj_in_]; + } +} diff --git a/L1Trigger/TrackFindingTracklet/test/AnalyzerDR.cc b/L1Trigger/TrackFindingTracklet/test/AnalyzerDR.cc index 65fcef8b27244..6c34826d9434e 100644 --- a/L1Trigger/TrackFindingTracklet/test/AnalyzerDR.cc +++ b/L1Trigger/TrackFindingTracklet/test/AnalyzerDR.cc @@ -14,7 +14,7 @@ #include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" #include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" +#include "L1Trigger/TrackFindingTracklet/interface/DataFormats.h" #include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h" #include @@ -28,11 +28,6 @@ #include #include -using namespace std; -using namespace edm; -using namespace trackerTFP; -using namespace tt; - namespace trklet { /*! \class trklet::AnalyzerDR @@ -40,47 +35,43 @@ namespace trklet { * \author Thomas Schuh * \date 2023, Feb */ - class AnalyzerDR : public one::EDAnalyzer { + class AnalyzerDR : public edm::one::EDAnalyzer { public: - AnalyzerDR(const ParameterSet& iConfig); + AnalyzerDR(const edm::ParameterSet& iConfig); void beginJob() override {} - void beginRun(const Run& iEvent, const EventSetup& iSetup) override; - void analyze(const Event& iEvent, const EventSetup& iSetup) override; - void endRun(const Run& iEvent, const EventSetup& iSetup) override {} + void beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override; + void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override; + void endRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override {} void endJob() override; private: // - void formTracks(const StreamsTrack& streamsTrack, - const StreamsStub& streamsStubs, - vector>& tracks, + void formTracks(const tt::StreamsTrack& streamsTrack, + const tt::StreamsStub& streamsStubs, + std::vector>& tracks, int channel) const; // - void associate(const vector>& tracks, - const StubAssociation* ass, - set& tps, + void associate(const std::vector>& tracks, + const tt::StubAssociation* ass, + std::set& tps, int& sum, bool perfect = false) const; // ED input token of stubs - EDGetTokenT edGetTokenAcceptedStubs_; + edm::EDGetTokenT edGetTokenStubs_; // ED input token of tracks - EDGetTokenT edGetTokenAcceptedTracks_; - // ED input token of lost stubs - EDGetTokenT edGetTokenLostStubs_; - // ED input token of lost tracks - EDGetTokenT edGetTokenLostTracks_; + edm::EDGetTokenT edGetTokenTracks_; // ED input token of TTStubRef to TPPtr association for tracking efficiency - EDGetTokenT edGetTokenSelection_; + edm::EDGetTokenT edGetTokenSelection_; // ED input token of TTStubRef to recontructable TPPtr association - EDGetTokenT edGetTokenReconstructable_; + edm::EDGetTokenT edGetTokenReconstructable_; // Setup token - ESGetToken esGetTokenSetup_; + edm::ESGetToken esGetTokenSetup_; // DataFormats token - ESGetToken esGetTokenDataFormats_; + edm::ESGetToken esGetTokenDataFormats_; // ChannelAssignment token - ESGetToken esGetTokenChannelAssignment_; + edm::ESGetToken esGetTokenChannelAssignment_; // stores, calculates and provides run-time constants - const Setup* setup_ = nullptr; + const tt::Setup* setup_ = nullptr; // helper class to extract structured data from tt::Frames const DataFormats* dataFormats_ = nullptr; // helper class to assign tracklet track to channel @@ -95,39 +86,36 @@ namespace trklet { TProfile* prof_; TProfile* profChannel_; TH1F* hisChannel_; + TH1F* hisTracks_; // printout - stringstream log_; + std::stringstream log_; }; - AnalyzerDR::AnalyzerDR(const ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { + AnalyzerDR::AnalyzerDR(const edm::ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { usesResource("TFileService"); // book in- and output ED products - const string& label = iConfig.getParameter("LabelDR"); - const string& branchAcceptedStubs = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchAcceptedTracks = iConfig.getParameter("BranchAcceptedTracks"); - const string& branchLostStubs = iConfig.getParameter("BranchLostStubs"); - const string& branchLostTracks = iConfig.getParameter("BranchLostTracks"); - edGetTokenAcceptedStubs_ = consumes(InputTag(label, branchAcceptedStubs)); - edGetTokenAcceptedTracks_ = consumes(InputTag(label, branchAcceptedTracks)); - edGetTokenLostStubs_ = consumes(InputTag(label, branchLostStubs)); - edGetTokenLostTracks_ = consumes(InputTag(label, branchLostTracks)); + const std::string& label = iConfig.getParameter("OutputLabelDR"); + const std::string& branchStubs = iConfig.getParameter("BranchStubs"); + const std::string& branchTracks = iConfig.getParameter("BranchTracks"); + edGetTokenStubs_ = consumes(edm::InputTag(label, branchStubs)); + edGetTokenTracks_ = consumes(edm::InputTag(label, branchTracks)); if (useMCTruth_) { - const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); - const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); - edGetTokenSelection_ = consumes(inputTagSelecttion); - edGetTokenReconstructable_ = consumes(inputTagReconstructable); + const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); + const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); + edGetTokenSelection_ = consumes(inputTagSelecttion); + edGetTokenReconstructable_ = consumes(inputTagReconstructable); } // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); - esGetTokenChannelAssignment_ = esConsumes(); + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + esGetTokenChannelAssignment_ = esConsumes(); // log config - log_.setf(ios::fixed, ios::floatfield); + log_.setf(std::ios::fixed, std::ios::floatfield); log_.precision(4); } - void AnalyzerDR::beginRun(const Run& iEvent, const EventSetup& iSetup) { + void AnalyzerDR::beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) { // helper class to store configurations setup_ = &iSetup.getData(esGetTokenSetup_); // helper class to extract structured data from tt::Frames @@ -135,104 +123,82 @@ namespace trklet { // helper class to assign tracklet track to channel channelAssignment_ = &iSetup.getData(esGetTokenChannelAssignment_); // book histograms - Service fs; + edm::Service fs; TFileDirectory dir; dir = fs->mkdir("DR"); prof_ = dir.make("Counts", ";", 10, 0.5, 10.5); prof_->GetXaxis()->SetBinLabel(1, "Stubs"); prof_->GetXaxis()->SetBinLabel(2, "Tracks"); - prof_->GetXaxis()->SetBinLabel(3, "Lost Tracks"); prof_->GetXaxis()->SetBinLabel(4, "Matched Tracks"); prof_->GetXaxis()->SetBinLabel(5, "All Tracks"); prof_->GetXaxis()->SetBinLabel(6, "Found TPs"); prof_->GetXaxis()->SetBinLabel(7, "Found selected TPs"); - prof_->GetXaxis()->SetBinLabel(8, "Lost TPs"); prof_->GetXaxis()->SetBinLabel(9, "All TPs"); prof_->GetXaxis()->SetBinLabel(10, "Perfect TPs"); // channel occupancy constexpr int maxOcc = 180; - const int numChannels = channelAssignment_->numNodesDR(); + const int numChannels = 1; hisChannel_ = dir.make("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5); profChannel_ = dir.make("Prof Channel Occupancy", ";", numChannels, -.5, numChannels - .5); + hisTracks_ = dir.make("His Number of Tracks", ";", maxOcc, -.5, maxOcc - .5); } - void AnalyzerDR::analyze(const Event& iEvent, const EventSetup& iSetup) { + void AnalyzerDR::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { // read in ht products - Handle handleAcceptedStubs; - iEvent.getByToken(edGetTokenAcceptedStubs_, handleAcceptedStubs); - const StreamsStub& acceptedStubs = *handleAcceptedStubs; - Handle handleAcceptedTracks; - iEvent.getByToken(edGetTokenAcceptedTracks_, handleAcceptedTracks); - const StreamsTrack& acceptedTracks = *handleAcceptedTracks; - Handle handleLostStubs; - iEvent.getByToken(edGetTokenLostStubs_, handleLostStubs); - const StreamsStub& lostStubs = *handleLostStubs; - Handle handleLostTracks; - iEvent.getByToken(edGetTokenLostTracks_, handleLostTracks); - const StreamsTrack& lostTracks = *handleLostTracks; + edm::Handle handleStubs; + iEvent.getByToken(edGetTokenStubs_, handleStubs); + const tt::StreamsStub& streamsStub = *handleStubs; + edm::Handle handleTracks; + iEvent.getByToken(edGetTokenTracks_, handleTracks); + const tt::StreamsTrack& streamsTrack = *handleTracks; // read in MCTruth - const StubAssociation* selection = nullptr; - const StubAssociation* reconstructable = nullptr; + const tt::StubAssociation* selection = nullptr; + const tt::StubAssociation* reconstructable = nullptr; if (useMCTruth_) { - Handle handleSelection; - iEvent.getByToken(edGetTokenSelection_, handleSelection); + edm::Handle handleSelection; + iEvent.getByToken(edGetTokenSelection_, handleSelection); selection = handleSelection.product(); prof_->Fill(9, selection->numTPs()); - Handle handleReconstructable; - iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); + edm::Handle handleReconstructable; + iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); reconstructable = handleReconstructable.product(); } // analyze ht products and associate found tracks with reconstrucable TrackingParticles - set tpPtrs; - set tpPtrsSelection; - set tpPtrsPerfect; - set tpPtrsLost; + std::set tpPtrs; + std::set tpPtrsSelection; + std::set tpPtrsPerfect; int allMatched(0); int allTracks(0); for (int region = 0; region < setup_->numRegions(); region++) { - const int offset = region * channelAssignment_->numNodesDR(); int nStubs(0); int nTracks(0); - int nLost(0); - for (int channel = 0; channel < channelAssignment_->numNodesDR(); channel++) { - vector> tracks; - formTracks(acceptedTracks, acceptedStubs, tracks, offset + channel); - vector> lost; - formTracks(lostTracks, lostStubs, lost, offset + channel); - nTracks += tracks.size(); - nStubs += accumulate(tracks.begin(), tracks.end(), 0UL, [](auto sum, const vector& track) { - return sum + track.size(); - }); - nLost += lost.size(); - allTracks += tracks.size(); - if (!useMCTruth_) - continue; - int tmp(0); - associate(tracks, selection, tpPtrsSelection, tmp); - associate(tracks, selection, tpPtrsPerfect, tmp, true); - associate(lost, selection, tpPtrsLost, tmp); - associate(tracks, reconstructable, tpPtrs, allMatched); - const StreamTrack& stream = acceptedTracks[offset + channel]; - const auto end = - find_if(stream.rbegin(), stream.rend(), [](const FrameTrack& frame) { return frame.first.isNonnull(); }); - const int size = distance(stream.begin(), end.base()) - 1; - hisChannel_->Fill(size); - profChannel_->Fill(channel, size); - } + std::vector> tracks; + formTracks(streamsTrack, streamsStub, tracks, region); + nTracks += tracks.size(); + nStubs += std::accumulate(tracks.begin(), tracks.end(), 0, [](int sum, const std::vector& track) { + return sum + track.size(); + }); + allTracks += tracks.size(); + if (!useMCTruth_) + continue; + int tmp(0); + associate(tracks, selection, tpPtrsSelection, tmp); + associate(tracks, selection, tpPtrsPerfect, tmp, true); + associate(tracks, reconstructable, tpPtrs, allMatched); + const tt::StreamTrack& stream = streamsTrack[region]; + const auto end = std::find_if( + stream.rbegin(), stream.rend(), [](const tt::FrameTrack& frame) { return frame.first.isNonnull(); }); + const int size = std::distance(stream.begin(), end.base()) - 1; + hisTracks_->Fill(nTracks); + hisChannel_->Fill(size); + profChannel_->Fill(1, size); prof_->Fill(1, nStubs); prof_->Fill(2, nTracks); - prof_->Fill(3, nLost); } - vector recovered; - recovered.reserve(tpPtrsLost.size()); - set_intersection(tpPtrsLost.begin(), tpPtrsLost.end(), tpPtrs.begin(), tpPtrs.end(), back_inserter(recovered)); - for (const TPPtr& tpPtr : recovered) - tpPtrsLost.erase(tpPtr); prof_->Fill(4, allMatched); prof_->Fill(5, allTracks); prof_->Fill(6, tpPtrs.size()); prof_->Fill(7, tpPtrsSelection.size()); - prof_->Fill(8, tpPtrsLost.size()); prof_->Fill(10, tpPtrsPerfect.size()); nEvents_++; } @@ -240,67 +206,62 @@ namespace trklet { void AnalyzerDR::endJob() { if (nEvents_ == 0) return; - // printout SF summary + // printout summary const double totalTPs = prof_->GetBinContent(9); const double numStubs = prof_->GetBinContent(1); const double numTracks = prof_->GetBinContent(2); - const double numTracksLost = prof_->GetBinContent(3); const double totalTracks = prof_->GetBinContent(5); const double numTracksMatched = prof_->GetBinContent(4); const double numTPsAll = prof_->GetBinContent(6); const double numTPsEff = prof_->GetBinContent(7); - const double numTPsLost = prof_->GetBinContent(8); const double numTPsEffPerfect = prof_->GetBinContent(10); const double errStubs = prof_->GetBinError(1); const double errTracks = prof_->GetBinError(2); - const double errTracksLost = prof_->GetBinError(3); const double fracFake = (totalTracks - numTracksMatched) / totalTracks; const double fracDup = (numTracksMatched - numTPsAll) / totalTracks; const double eff = numTPsEff / totalTPs; - const double errEff = sqrt(eff * (1. - eff) / totalTPs / nEvents_); - const double effLoss = numTPsLost / totalTPs; - const double errEffLoss = sqrt(effLoss * (1. - effLoss) / totalTPs / nEvents_); + const double errEff = std::sqrt(eff * (1. - eff) / totalTPs / nEvents_); const double effPerfect = numTPsEffPerfect / totalTPs; - const double errEffPerfect = sqrt(effPerfect * (1. - effPerfect) / totalTPs / nEvents_); - const vector nums = {numStubs, numTracks, numTracksLost}; - const vector errs = {errStubs, errTracks, errTracksLost}; - const int wNums = ceil(log10(*max_element(nums.begin(), nums.end()))) + 5; - const int wErrs = ceil(log10(*max_element(errs.begin(), errs.end()))) + 5; - log_ << " DR SUMMARY " << endl; - log_ << "number of stubs per TFP = " << setw(wNums) << numStubs << " +- " << setw(wErrs) << errStubs << endl; - log_ << "number of tracks per TFP = " << setw(wNums) << numTracks << " +- " << setw(wErrs) << errTracks - << endl; - log_ << "number of lost tracks per TFP = " << setw(wNums) << numTracksLost << " +- " << setw(wErrs) << errTracksLost - << endl; - log_ << " current tracking efficiency = " << setw(wNums) << effPerfect << " +- " << setw(wErrs) << errEffPerfect - << endl; - log_ << " max tracking efficiency = " << setw(wNums) << eff << " +- " << setw(wErrs) << errEff << endl; - log_ << " lost tracking efficiency = " << setw(wNums) << effLoss << " +- " << setw(wErrs) << errEffLoss << endl; - log_ << " fake rate = " << setw(wNums) << fracFake << endl; - log_ << " duplicate rate = " << setw(wNums) << fracDup << endl; + const double errEffPerfect = std::sqrt(effPerfect * (1. - effPerfect) / totalTPs / nEvents_); + const std::vector nums = {numStubs, numTracks}; + const std::vector errs = {errStubs, errTracks}; + const int wNums = std::ceil(std::log10(*std::max_element(nums.begin(), nums.end()))) + 5; + const int wErrs = std::ceil(std::log10(*std::max_element(errs.begin(), errs.end()))) + 5; + log_ << " DR SUMMARY " << std::endl; + log_ << "number of stubs per TFP = " << std::setw(wNums) << numStubs << " +- " << std::setw(wErrs) << errStubs + << std::endl; + log_ << "number of tracks per TFP = " << std::setw(wNums) << numTracks << " +- " << std::setw(wErrs) + << errTracks << std::endl; + log_ << " current tracking efficiency = " << std::setw(wNums) << effPerfect << " +- " << std::setw(wErrs) + << errEffPerfect << std::endl; + log_ << " max tracking efficiency = " << std::setw(wNums) << eff << " +- " << std::setw(wErrs) << errEff + << std::endl; + log_ << " fake rate = " << std::setw(wNums) << fracFake << std::endl; + log_ << " duplicate rate = " << std::setw(wNums) << fracDup << std::endl; log_ << "============================================================="; - LogPrint("L1Trigger/TrackerTFP") << log_.str(); + edm::LogPrint(moduleDescription().moduleName()) << log_.str(); } // - void AnalyzerDR::formTracks(const StreamsTrack& streamsTrack, - const StreamsStub& streamsStubs, - vector>& tracks, + void AnalyzerDR::formTracks(const tt::StreamsTrack& streamsTrack, + const tt::StreamsStub& streamsStubs, + std::vector>& tracks, int channel) const { const int offset = channel * setup_->numLayers(); - const StreamTrack& streamTrack = streamsTrack[channel]; - const int numTracks = accumulate(streamTrack.begin(), streamTrack.end(), 0, [](int sum, const FrameTrack& frame) { - return sum + (frame.first.isNonnull() ? 1 : 0); - }); + const tt::StreamTrack& streamTrack = streamsTrack[channel]; + const int numTracks = + std::accumulate(streamTrack.begin(), streamTrack.end(), 0, [](int sum, const tt::FrameTrack& frame) { + return sum + (frame.first.isNonnull() ? 1 : 0); + }); tracks.reserve(numTracks); for (int frame = 0; frame < (int)streamTrack.size(); frame++) { - const FrameTrack& frameTrack = streamTrack[frame]; + const tt::FrameTrack& frameTrack = streamTrack[frame]; if (frameTrack.first.isNull()) continue; - vector ttStubRefs; + std::vector ttStubRefs; ttStubRefs.reserve(setup_->numLayers()); for (int layer = 0; layer < setup_->numLayers(); layer++) { - const FrameStub& stub = streamsStubs[offset + layer][frame]; + const tt::FrameStub& stub = streamsStubs[offset + layer][frame]; if (stub.first.isNonnull()) ttStubRefs.push_back(stub.first); } @@ -309,17 +270,17 @@ namespace trklet { } // - void AnalyzerDR::associate(const vector>& tracks, - const StubAssociation* ass, - set& tps, + void AnalyzerDR::associate(const std::vector>& tracks, + const tt::StubAssociation* ass, + std::set& tps, int& sum, bool perfect) const { - for (const vector& ttStubRefs : tracks) { - const vector& tpPtrs = perfect ? ass->associateFinal(ttStubRefs) : ass->associate(ttStubRefs); + for (const std::vector& ttStubRefs : tracks) { + const std::vector& tpPtrs = perfect ? ass->associateFinal(ttStubRefs) : ass->associate(ttStubRefs); if (tpPtrs.empty()) continue; sum++; - copy(tpPtrs.begin(), tpPtrs.end(), inserter(tps, tps.begin())); + std::copy(tpPtrs.begin(), tpPtrs.end(), std::inserter(tps, tps.begin())); } } diff --git a/L1Trigger/TrackFindingTracklet/test/AnalyzerDRin.cc b/L1Trigger/TrackFindingTracklet/test/AnalyzerDRin.cc deleted file mode 100644 index fcd9c02004c35..0000000000000 --- a/L1Trigger/TrackFindingTracklet/test/AnalyzerDRin.cc +++ /dev/null @@ -1,329 +0,0 @@ -#include "FWCore/Framework/interface/one/EDAnalyzer.h" -#include "FWCore/Framework/interface/Run.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/ServiceRegistry/interface/Service.h" -#include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "FWCore/Utilities/interface/EDGetToken.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/Utilities/interface/Exception.h" -#include "CommonTools/UtilAlgos/interface/TFileService.h" -#include "DataFormats/Common/interface/Handle.h" - -#include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" -#include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" -#include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace edm; -using namespace trackerTFP; -using namespace tt; - -namespace trklet { - - /*! \class trklet::AnalyzerDRin - * \brief Class to analyze hardware like structured TTStub Collection generated by DRin module - * \author Thomas Schuh - * \date 2023, Jan - */ - class AnalyzerDRin : public one::EDAnalyzer { - public: - AnalyzerDRin(const ParameterSet& iConfig); - void beginJob() override {} - void beginRun(const Run& iEvent, const EventSetup& iSetup) override; - void analyze(const Event& iEvent, const EventSetup& iSetup) override; - void endRun(const Run& iEvent, const EventSetup& iSetup) override {} - void endJob() override; - - private: - // - void formTracks(const StreamsTrack& streamsTrack, - const StreamsStub& streamsStubs, - vector>& tracks, - int channel) const; - // - void associate(const vector>& tracks, - const StubAssociation* ass, - set& tps, - int& sum, - bool perfect = false) const; - - // ED input token of stubs - EDGetTokenT edGetTokenAcceptedStubs_; - // ED input token of tracks - EDGetTokenT edGetTokenAcceptedTracks_; - // ED input token of lost stubs - EDGetTokenT edGetTokenLostStubs_; - // ED input token of lost tracks - EDGetTokenT edGetTokenLostTracks_; - // ED input token of TTStubRef to TPPtr association for tracking efficiency - EDGetTokenT edGetTokenSelection_; - // ED input token of TTStubRef to recontructable TPPtr association - EDGetTokenT edGetTokenReconstructable_; - // Setup token - ESGetToken esGetTokenSetup_; - // DataFormats token - ESGetToken esGetTokenDataFormats_; - // ChannelAssignment token - ESGetToken esGetTokenChannelAssignment_; - // stores, calculates and provides run-time constants - const Setup* setup_ = nullptr; - // helper class to extract structured data from tt::Frames - const DataFormats* dataFormats_ = nullptr; - // helper class to assign tracklet track to channel - const ChannelAssignment* channelAssignment_ = nullptr; - // enables analyze of TPs - bool useMCTruth_; - // - int nEvents_ = 0; - - // Histograms - - TProfile* prof_; - TProfile* profChannel_; - TH1F* hisChannel_; - - // printout - stringstream log_; - }; - - AnalyzerDRin::AnalyzerDRin(const ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { - usesResource("TFileService"); - // book in- and output ED products - const string& label = iConfig.getParameter("LabelDRin"); - const string& branchAcceptedStubs = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchAcceptedTracks = iConfig.getParameter("BranchAcceptedTracks"); - const string& branchLostStubs = iConfig.getParameter("BranchLostStubs"); - const string& branchLostTracks = iConfig.getParameter("BranchLostTracks"); - edGetTokenAcceptedStubs_ = consumes(InputTag(label, branchAcceptedStubs)); - edGetTokenAcceptedTracks_ = consumes(InputTag(label, branchAcceptedTracks)); - edGetTokenLostStubs_ = consumes(InputTag(label, branchLostStubs)); - edGetTokenLostTracks_ = consumes(InputTag(label, branchLostTracks)); - if (useMCTruth_) { - const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); - const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); - edGetTokenSelection_ = consumes(inputTagSelecttion); - edGetTokenReconstructable_ = consumes(inputTagReconstructable); - } - // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); - esGetTokenChannelAssignment_ = esConsumes(); - // log config - log_.setf(ios::fixed, ios::floatfield); - log_.precision(4); - } - - void AnalyzerDRin::beginRun(const Run& iEvent, const EventSetup& iSetup) { - // helper class to store configurations - setup_ = &iSetup.getData(esGetTokenSetup_); - // helper class to extract structured data from tt::Frames - dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); - // helper class to assign tracklet track to channel - channelAssignment_ = &iSetup.getData(esGetTokenChannelAssignment_); - // book histograms - Service fs; - TFileDirectory dir; - dir = fs->mkdir("DRin"); - prof_ = dir.make("Counts", ";", 10, 0.5, 10.5); - prof_->GetXaxis()->SetBinLabel(1, "Stubs"); - prof_->GetXaxis()->SetBinLabel(2, "Tracks"); - prof_->GetXaxis()->SetBinLabel(3, "Lost Tracks"); - prof_->GetXaxis()->SetBinLabel(4, "Matched Tracks"); - prof_->GetXaxis()->SetBinLabel(5, "All Tracks"); - prof_->GetXaxis()->SetBinLabel(6, "Found TPs"); - prof_->GetXaxis()->SetBinLabel(7, "Found selected TPs"); - prof_->GetXaxis()->SetBinLabel(8, "Lost TPs"); - prof_->GetXaxis()->SetBinLabel(9, "All TPs"); - prof_->GetXaxis()->SetBinLabel(10, "Perfect TPs"); - // channel occupancy - constexpr int maxOcc = 180; - const int numChannels = channelAssignment_->numNodesDR(); - hisChannel_ = dir.make("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5); - profChannel_ = dir.make("Prof Channel Occupancy", ";", numChannels, -.5, numChannels - .5); - } - - void AnalyzerDRin::analyze(const Event& iEvent, const EventSetup& iSetup) { - // read in ht products - Handle handleAcceptedStubs; - iEvent.getByToken(edGetTokenAcceptedStubs_, handleAcceptedStubs); - const StreamsStub& acceptedStubs = *handleAcceptedStubs; - Handle handleAcceptedTracks; - iEvent.getByToken(edGetTokenAcceptedTracks_, handleAcceptedTracks); - const StreamsTrack& acceptedTracks = *handleAcceptedTracks; - Handle handleLostStubs; - iEvent.getByToken(edGetTokenLostStubs_, handleLostStubs); - const StreamsStub& lostStubs = *handleLostStubs; - Handle handleLostTracks; - iEvent.getByToken(edGetTokenLostTracks_, handleLostTracks); - const StreamsTrack& lostTracks = *handleLostTracks; - // read in MCTruth - const StubAssociation* selection = nullptr; - const StubAssociation* reconstructable = nullptr; - if (useMCTruth_) { - Handle handleSelection; - iEvent.getByToken(edGetTokenSelection_, handleSelection); - selection = handleSelection.product(); - prof_->Fill(9, selection->numTPs()); - Handle handleReconstructable; - iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); - reconstructable = handleReconstructable.product(); - } - // analyze ht products and associate found tracks with reconstrucable TrackingParticles - set tpPtrs; - set tpPtrsSelection; - set tpPtrsPerfect; - set tpPtrsLost; - int allMatched(0); - int allTracks(0); - for (int region = 0; region < setup_->numRegions(); region++) { - const int offset = region * channelAssignment_->numNodesDR(); - int nStubs(0); - int nTracks(0); - int nLost(0); - for (int channel = 0; channel < channelAssignment_->numNodesDR(); channel++) { - vector> tracks; - formTracks(acceptedTracks, acceptedStubs, tracks, offset + channel); - vector> lost; - formTracks(lostTracks, lostStubs, lost, offset + channel); - nTracks += tracks.size(); - nStubs += accumulate(tracks.begin(), tracks.end(), 0UL, [](auto sum, const vector& track) { - return sum + track.size(); - }); - nLost += lost.size(); - allTracks += tracks.size(); - if (!useMCTruth_) - continue; - int tmp(0); - associate(tracks, selection, tpPtrsSelection, tmp); - associate(tracks, selection, tpPtrsPerfect, tmp, true); - associate(lost, selection, tpPtrsLost, tmp); - associate(tracks, reconstructable, tpPtrs, allMatched); - const StreamTrack& stream = acceptedTracks[offset + channel]; - const auto end = - find_if(stream.rbegin(), stream.rend(), [](const FrameTrack& frame) { return frame.first.isNonnull(); }); - const int size = distance(stream.begin(), end.base()) - 1; - hisChannel_->Fill(size); - profChannel_->Fill(channel, size); - } - prof_->Fill(1, nStubs); - prof_->Fill(2, nTracks); - prof_->Fill(3, nLost); - } - vector recovered; - recovered.reserve(tpPtrsLost.size()); - set_intersection(tpPtrsLost.begin(), tpPtrsLost.end(), tpPtrs.begin(), tpPtrs.end(), back_inserter(recovered)); - for (const TPPtr& tpPtr : recovered) - tpPtrsLost.erase(tpPtr); - prof_->Fill(4, allMatched); - prof_->Fill(5, allTracks); - prof_->Fill(6, tpPtrs.size()); - prof_->Fill(7, tpPtrsSelection.size()); - prof_->Fill(8, tpPtrsLost.size()); - prof_->Fill(10, tpPtrsPerfect.size()); - nEvents_++; - } - - void AnalyzerDRin::endJob() { - if (nEvents_ == 0) - return; - // printout SF summary - const double totalTPs = prof_->GetBinContent(9); - const double numStubs = prof_->GetBinContent(1); - const double numTracks = prof_->GetBinContent(2); - const double numTracksLost = prof_->GetBinContent(3); - const double totalTracks = prof_->GetBinContent(5); - const double numTracksMatched = prof_->GetBinContent(4); - const double numTPsAll = prof_->GetBinContent(6); - const double numTPsEff = prof_->GetBinContent(7); - const double numTPsLost = prof_->GetBinContent(8); - const double numTPsEffPerfect = prof_->GetBinContent(10); - const double errStubs = prof_->GetBinError(1); - const double errTracks = prof_->GetBinError(2); - const double errTracksLost = prof_->GetBinError(3); - const double fracFake = (totalTracks - numTracksMatched) / totalTracks; - const double fracDup = (numTracksMatched - numTPsAll) / totalTracks; - const double eff = numTPsEff / totalTPs; - const double errEff = sqrt(eff * (1. - eff) / totalTPs / nEvents_); - const double effLoss = numTPsLost / totalTPs; - const double errEffLoss = sqrt(effLoss * (1. - effLoss) / totalTPs / nEvents_); - const double effPerfect = numTPsEffPerfect / totalTPs; - const double errEffPerfect = sqrt(effPerfect * (1. - effPerfect) / totalTPs / nEvents_); - const vector nums = {numStubs, numTracks, numTracksLost}; - const vector errs = {errStubs, errTracks, errTracksLost}; - const int wNums = ceil(log10(*max_element(nums.begin(), nums.end()))) + 5; - const int wErrs = ceil(log10(*max_element(errs.begin(), errs.end()))) + 5; - log_ << " DRin SUMMARY " << endl; - log_ << "number of stubs per TFP = " << setw(wNums) << numStubs << " +- " << setw(wErrs) << errStubs << endl; - log_ << "number of tracks per TFP = " << setw(wNums) << numTracks << " +- " << setw(wErrs) << errTracks - << endl; - log_ << "number of lost tracks per TFP = " << setw(wNums) << numTracksLost << " +- " << setw(wErrs) << errTracksLost - << endl; - log_ << " current tracking efficiency = " << setw(wNums) << effPerfect << " +- " << setw(wErrs) << errEffPerfect - << endl; - log_ << " max tracking efficiency = " << setw(wNums) << eff << " +- " << setw(wErrs) << errEff << endl; - log_ << " lost tracking efficiency = " << setw(wNums) << effLoss << " +- " << setw(wErrs) << errEffLoss << endl; - log_ << " fake rate = " << setw(wNums) << fracFake << endl; - log_ << " duplicate rate = " << setw(wNums) << fracDup << endl; - log_ << "============================================================="; - LogPrint("L1Trigger/TrackerTFP") << log_.str(); - } - - // - void AnalyzerDRin::formTracks(const StreamsTrack& streamsTrack, - const StreamsStub& streamsStubs, - vector>& tracks, - int channel) const { - const int offset = channel * setup_->numLayers(); - const StreamTrack& streamTrack = streamsTrack[channel]; - const int numTracks = accumulate(streamTrack.begin(), streamTrack.end(), 0, [](int sum, const FrameTrack& frame) { - return sum + (frame.first.isNonnull() ? 1 : 0); - }); - tracks.reserve(numTracks); - for (int frame = 0; frame < (int)streamTrack.size(); frame++) { - const FrameTrack& frameTrack = streamTrack[frame]; - if (frameTrack.first.isNull()) - continue; - vector ttStubRefs; - ttStubRefs.reserve(setup_->numLayers()); - for (int layer = 0; layer < setup_->numLayers(); layer++) { - const FrameStub& stub = streamsStubs[offset + layer][frame]; - if (stub.first.isNonnull()) - ttStubRefs.push_back(stub.first); - } - tracks.push_back(ttStubRefs); - } - } - - // - void AnalyzerDRin::associate(const vector>& tracks, - const StubAssociation* ass, - set& tps, - int& sum, - bool perfect) const { - for (const vector& ttStubRefs : tracks) { - const vector& tpPtrs = perfect ? ass->associateFinal(ttStubRefs) : ass->associate(ttStubRefs); - if (tpPtrs.empty()) - continue; - sum++; - copy(tpPtrs.begin(), tpPtrs.end(), inserter(tps, tps.begin())); - } - } - -} // namespace trklet - -DEFINE_FWK_MODULE(trklet::AnalyzerDRin); diff --git a/L1Trigger/TrackFindingTracklet/test/AnalyzerDemonstrator.cc b/L1Trigger/TrackFindingTracklet/test/AnalyzerDemonstrator.cc index cd0e596601bfb..87484c91d15c6 100644 --- a/L1Trigger/TrackFindingTracklet/test/AnalyzerDemonstrator.cc +++ b/L1Trigger/TrackFindingTracklet/test/AnalyzerDemonstrator.cc @@ -17,82 +17,82 @@ #include #include -using namespace std; -using namespace edm; -using namespace tt; -using namespace trackerTFP; - namespace trklet { /*! \class trklet::AnalyzerDemonstrator - * \brief Class to demontrate correctness of track trigger emulators - * by comparing FW with SW + * \brief calls questasim to simulate the f/w and compares the results with clock-and-bit-accurate emulation. + * At the end the number of passing events (not a single bit error) are reported. * \author Thomas Schuh * \date 2022, March */ - class AnalyzerDemonstrator : public one::EDAnalyzer { + class AnalyzerDemonstrator : public edm::one::EDAnalyzer { public: - AnalyzerDemonstrator(const ParameterSet& iConfig); + AnalyzerDemonstrator(const edm::ParameterSet& iConfig); void beginJob() override {} - void beginRun(const Run& iEvent, const EventSetup& iSetup) override; - void analyze(const Event& iEvent, const EventSetup& iSetup) override; - void endRun(const Run& iEvent, const EventSetup& iSetup) override {} + void beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override; + void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override; + void endRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override {} void endJob() override; private: // - void convert(const Event& iEvent, - const EDGetTokenT& tokenTracks, - const EDGetTokenT& tokenStubs, - vector>& bits) const; + void convert(const edm::Event& iEvent, + const edm::EDGetTokenT& tokenTracks, + const edm::EDGetTokenT& tokenStubs, + std::vector>& bits, + bool TB = false) const; // template - void convert(const T& collection, vector>& bits) const; + void convert(const T& collection, std::vector>& bits) const; // ED input token of Tracks - EDGetTokenT edGetTokenStubsIn_; - EDGetTokenT edGetTokenStubsOut_; + edm::EDGetTokenT edGetTokenStubsIn_; + edm::EDGetTokenT edGetTokenStubsOut_; // ED input token of Stubs - EDGetTokenT edGetTokenTracksIn_; - EDGetTokenT edGetTokenTracksOut_; + edm::EDGetTokenT edGetTokenTracksIn_; + edm::EDGetTokenT edGetTokenTracksOut_; // Setup token - ESGetToken esGetTokenSetup_; + edm::ESGetToken esGetTokenSetup_; // ChannelAssignment token - ESGetToken esGetTokenChannelAssignment_; + edm::ESGetToken esGetTokenChannelAssignment_; // Demonstrator token - ESGetToken esGetTokenDemonstrator_; + edm::ESGetToken esGetTokenDemonstrator_; // - const Setup* setup_ = nullptr; + const tt::Setup* setup_ = nullptr; // const ChannelAssignment* channelAssignment_ = nullptr; // - const Demonstrator* demonstrator_ = nullptr; + const trackerTFP::Demonstrator* demonstrator_ = nullptr; // int nEvents_ = 0; // int nEventsSuccessful_ = 0; + // + bool TBin_; + bool TBout_; }; - AnalyzerDemonstrator::AnalyzerDemonstrator(const ParameterSet& iConfig) { + AnalyzerDemonstrator::AnalyzerDemonstrator(const edm::ParameterSet& iConfig) { // book in- and output ED products - const string& labelIn = iConfig.getParameter("LabelIn"); - const string& labelOut = iConfig.getParameter("LabelOut"); - const string& branchStubs = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchTracks = iConfig.getParameter("BranchAcceptedTracks"); - edGetTokenStubsIn_ = consumes(InputTag(labelIn, branchStubs)); - edGetTokenStubsOut_ = consumes(InputTag(labelOut, branchStubs)); - if (labelOut != "TrackFindingTrackletProducerKFout") - edGetTokenStubsOut_ = consumes(InputTag(labelOut, branchStubs)); - if (labelIn != "TrackFindingTrackletProducerIRin") - edGetTokenTracksIn_ = consumes(InputTag(labelIn, branchTracks)); - if (labelOut != "TrackFindingTrackletProducerIRin") - edGetTokenTracksOut_ = consumes(InputTag(labelOut, branchTracks)); + const std::string& labelIn = iConfig.getParameter("LabelIn"); + const std::string& labelOut = iConfig.getParameter("LabelOut"); + const std::string& branchStubs = iConfig.getParameter("BranchStubs"); + const std::string& branchTracks = iConfig.getParameter("BranchTracks"); + edGetTokenStubsIn_ = consumes(edm::InputTag(labelIn, branchStubs)); + edGetTokenStubsOut_ = consumes(edm::InputTag(labelOut, branchStubs)); + if (labelIn != "ProducerIRin") + edGetTokenTracksIn_ = consumes(edm::InputTag(labelIn, branchTracks)); + if (labelOut != "ProducerIRin") + edGetTokenTracksOut_ = consumes(edm::InputTag(labelOut, branchTracks)); // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenChannelAssignment_ = esConsumes(); - esGetTokenDemonstrator_ = esConsumes(); + esGetTokenSetup_ = esConsumes(); + esGetTokenChannelAssignment_ = esConsumes(); + esGetTokenDemonstrator_ = esConsumes(); + // + TBin_ = labelIn == "l1tTTTracksFromTrackletEmulation"; + TBout_ = labelOut == "l1tTTTracksFromTrackletEmulation"; } - void AnalyzerDemonstrator::beginRun(const Run& iEvent, const EventSetup& iSetup) { + void AnalyzerDemonstrator::beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) { // setup_ = &iSetup.getData(esGetTokenSetup_); // @@ -101,50 +101,55 @@ namespace trklet { demonstrator_ = &iSetup.getData(esGetTokenDemonstrator_); } - void AnalyzerDemonstrator::analyze(const Event& iEvent, const EventSetup& iSetup) { + void AnalyzerDemonstrator::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { nEvents_++; - vector> input; - vector> output; - convert(iEvent, edGetTokenTracksIn_, edGetTokenStubsIn_, input); - convert(iEvent, edGetTokenTracksOut_, edGetTokenStubsOut_, output); + std::vector> input; + std::vector> output; + convert(iEvent, edGetTokenTracksIn_, edGetTokenStubsIn_, input, TBin_); + convert(iEvent, edGetTokenTracksOut_, edGetTokenStubsOut_, output, TBout_); if (demonstrator_->analyze(input, output)) nEventsSuccessful_++; } // - void AnalyzerDemonstrator::convert(const Event& iEvent, - const EDGetTokenT& tokenTracks, - const EDGetTokenT& tokenStubs, - vector>& bits) const { + void AnalyzerDemonstrator::convert(const edm::Event& iEvent, + const edm::EDGetTokenT& tokenTracks, + const edm::EDGetTokenT& tokenStubs, + std::vector>& bits, + bool TB) const { const bool tracks = !tokenTracks.isUninitialized(); const bool stubs = !tokenStubs.isUninitialized(); - Handle handleStubs; - Handle handleTracks; + edm::Handle handleStubs; + edm::Handle handleTracks; + int numChannelStubs(0); + if (stubs) { + iEvent.getByToken(tokenStubs, handleStubs); + numChannelStubs = handleStubs->size(); + } int numChannelTracks(0); if (tracks) { - iEvent.getByToken(tokenTracks, handleTracks); + iEvent.getByToken(tokenTracks, handleTracks); numChannelTracks = handleTracks->size(); } numChannelTracks /= setup_->numRegions(); - int numChannelStubs(0); - vector numChannelsStubs(numChannelTracks, 0); - if (stubs) { - iEvent.getByToken(tokenStubs, handleStubs); - numChannelStubs = handleStubs->size() / setup_->numRegions(); - const int numChannel = tracks ? numChannelStubs / numChannelTracks : numChannelStubs; - numChannelsStubs = vector(numChannelTracks, numChannel); - } + numChannelStubs /= (setup_->numRegions() * (tracks ? numChannelTracks : 1)); + if (TB) + numChannelStubs = channelAssignment_->numChannelsStub(); bits.reserve(numChannelTracks + numChannelStubs); for (int region = 0; region < setup_->numRegions(); region++) { if (tracks) { const int offsetTracks = region * numChannelTracks; for (int channelTracks = 0; channelTracks < numChannelTracks; channelTracks++) { - const int offsetStubs = - region * numChannelStubs + - accumulate(numChannelsStubs.begin(), next(numChannelsStubs.begin(), channelTracks), 0); - convert(handleTracks->at(offsetTracks + channelTracks), bits); + int offsetStubs = (region * numChannelTracks + channelTracks) * numChannelStubs; + if (TB) { + numChannelStubs = + channelAssignment_->numProjectionLayers(channelTracks) + channelAssignment_->numSeedingLayers(); + offsetStubs = channelAssignment_->offsetStub(offsetTracks + channelTracks); + } + if (tracks) + convert(handleTracks->at(offsetTracks + channelTracks), bits); if (stubs) { - for (int channelStubs = 0; channelStubs < numChannelsStubs[channelTracks]; channelStubs++) + for (int channelStubs = 0; channelStubs < numChannelStubs; channelStubs++) convert(handleStubs->at(offsetStubs + channelStubs), bits); } } @@ -158,17 +163,17 @@ namespace trklet { // template - void AnalyzerDemonstrator::convert(const T& collection, vector>& bits) const { + void AnalyzerDemonstrator::convert(const T& collection, std::vector>& bits) const { bits.emplace_back(); - vector& bvs = bits.back(); + std::vector& bvs = bits.back(); bvs.reserve(collection.size()); transform(collection.begin(), collection.end(), back_inserter(bvs), [](const auto& frame) { return frame.second; }); } void AnalyzerDemonstrator::endJob() { - stringstream log; + std::stringstream log; log << "Successrate: " << nEventsSuccessful_ << " / " << nEvents_ << " = " << nEventsSuccessful_ / (double)nEvents_; - LogPrint("L1Trigger/TrackerTFP") << log.str(); + edm::LogPrint(moduleDescription().moduleName()) << log.str(); } } // namespace trklet diff --git a/L1Trigger/TrackFindingTracklet/test/AnalyzerKF.cc b/L1Trigger/TrackFindingTracklet/test/AnalyzerKF.cc new file mode 100644 index 0000000000000..18652032cbc89 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/test/AnalyzerKF.cc @@ -0,0 +1,420 @@ +#include "FWCore/Framework/interface/one/EDAnalyzer.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "CommonTools/UtilAlgos/interface/TFileService.h" +#include "DataFormats/Common/interface/Handle.h" + +#include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" +#include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackFindingTracklet/interface/DataFormats.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace trklet { + + /*! \class trklet::AnalyzerKF + * \brief Class to analyze hardware like structured TTTrack Collection generated by Kalman Filter + * \author Thomas Schuh + * \date 2020, Sep + */ + class AnalyzerKF : public edm::one::EDAnalyzer { + public: + AnalyzerKF(const edm::ParameterSet& iConfig); + void beginJob() override {} + void beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override; + void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override; + void endRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override {} + void endJob() override; + + private: + // + void associate(const std::vector& tracks, + const std::vector>& stubs, + int region, + const tt::StubAssociation* ass, + std::set& tps, + int& sum, + const std::vector& his, + const std::vector& prof, + bool perfect = true) const; + // + void analyzeTPz0(const tt::StubAssociation* sa); + // ED input token of accepted Tracks + edm::EDGetTokenT edGetTokenStubs_; + // ED input token of accepted Stubs + edm::EDGetTokenT edGetTokenTracks_; + // ED input token for number of accepted States + edm::EDGetTokenT edGetTokenNumStatesAccepted_; + // ED input token for number of lost States + edm::EDGetTokenT edGetTokenNumStatesTruncated_; + // ED input token of TTStubRef to TPPtr association for tracking efficiency + edm::EDGetTokenT edGetTokenSelection_; + // ED input token of TTStubRef to recontructable TPPtr association + edm::EDGetTokenT edGetTokenReconstructable_; + // Setup token + edm::ESGetToken esGetTokenSetup_; + // DataFormats token + edm::ESGetToken esGetTokenDataFormats_; + // stores, calculates and provides run-time constants + const tt::Setup* setup_ = nullptr; + // + const DataFormats* dataFormats_ = nullptr; + // enables analyze of TPs + bool useMCTruth_; + // + int nEvents_ = 0; + // + std::string label_; + + // Histograms + + TProfile* prof_; + TProfile* profChannel_; + TH1F* hisChannel_; + std::vector hisRes_; + std::vector profRes_; + TH1F* hisEffD0_; + TH1F* hisEffD0Total_; + TEfficiency* effD0_; + TH1F* hisEffEta_; + TH1F* hisEffEtaTotal_; + TEfficiency* effEta_; + TH1F* hisEffInv2R_; + TH1F* hisEffInv2RTotal_; + TEfficiency* effInv2R_; + TH1F* hisEffPT_; + TH1F* hisEffPTTotal_; + TEfficiency* effPT_; + TH1F* hisTracks_; + TH1F* hisLayers_; + TH1F* hisNumLayers_; + TProfile* profNumLayers_; + + // printout + std::stringstream log_; + }; + + AnalyzerKF::AnalyzerKF(const edm::ParameterSet& iConfig) + : useMCTruth_(iConfig.getParameter("UseMCTruth")), nEvents_(0), hisRes_(9), profRes_(5) { + usesResource("TFileService"); + // book in- and output ED products + label_ = iConfig.getParameter("OutputLabelKF"); + const std::string& branchStubs = iConfig.getParameter("BranchStubs"); + const std::string& branchTracks = iConfig.getParameter("BranchTracks"); + const std::string& branchTruncated = iConfig.getParameter("BranchTruncated"); + edGetTokenStubs_ = consumes(edm::InputTag(label_, branchStubs)); + edGetTokenTracks_ = consumes(edm::InputTag(label_, branchTracks)); + edGetTokenNumStatesAccepted_ = consumes(edm::InputTag(label_, branchTracks)); + edGetTokenNumStatesTruncated_ = consumes(edm::InputTag(label_, branchTruncated)); + if (useMCTruth_) { + const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); + const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); + edGetTokenSelection_ = consumes(inputTagSelecttion); + edGetTokenReconstructable_ = consumes(inputTagReconstructable); + } + // book ES products + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + // log config + log_.setf(std::ios::fixed, std::ios::floatfield); + log_.precision(4); + } + + void AnalyzerKF::beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) { + // helper class to store configurations + setup_ = &iSetup.getData(esGetTokenSetup_); + dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); + // book histograms + edm::Service fs; + TFileDirectory dir; + dir = fs->mkdir("KF"); + prof_ = dir.make("Counts", ";", 14, 0.5, 14.5); + prof_->GetXaxis()->SetBinLabel(1, "Stubs"); + prof_->GetXaxis()->SetBinLabel(2, "Tracks"); + prof_->GetXaxis()->SetBinLabel(4, "Matched Tracks"); + prof_->GetXaxis()->SetBinLabel(5, "All Tracks"); + prof_->GetXaxis()->SetBinLabel(6, "Found TPs"); + prof_->GetXaxis()->SetBinLabel(7, "Found selected TPs"); + prof_->GetXaxis()->SetBinLabel(9, "All TPs"); + prof_->GetXaxis()->SetBinLabel(10, "states"); + prof_->GetXaxis()->SetBinLabel(12, "max tp"); + prof_->GetXaxis()->SetBinLabel(13, "All electron TPs"); + prof_->GetXaxis()->SetBinLabel(14, "max electron tp"); + // channel occupancy + constexpr int maxOcc = 180; + const int numChannels = 1; + hisChannel_ = dir.make("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5); + profChannel_ = dir.make("Prof Channel Occupancy", ";", numChannels, -.5, numChannels - .5); + // resoultions + static const std::vector names = {"phi0", "inv2R", "z0", "cot", "d0"}; + static const std::vector ranges = {.01, .004, 5., .4, 5.}; + for (int i = 0; i < 5; i++) { + hisRes_[i] = dir.make(("HisRes" + names[i]).c_str(), ";", 100, -ranges[i], ranges[i]); + profRes_[i] = dir.make(("ProfRes" + names[i]).c_str(), ";", 32, 0, 2.4); + } + for (int i = 5; i < 9; i++) { + const std::string name = (i < 7 ? names[2] : names[3]) + (i % 2 == 1 ? "plus" : "minus"); + const double range = (i < 7 ? ranges[2] : ranges[3]); + hisRes_[i] = dir.make(("HisRes" + name).c_str(), ";", 100, -range, range); + } + // Efficiencies + const double rangeD0 = 10.; + hisEffD0_ = dir.make("HisTPD0", ";", 32, -rangeD0 / 2., rangeD0 / 2.); + hisEffD0Total_ = dir.make("HisTPD0Total", ";", 32, -rangeD0 / 2., rangeD0 / 2.); + effD0_ = dir.make("EffD0", ";", 32, -rangeD0 / 2., rangeD0 / 2.); + hisEffEtaTotal_ = dir.make("HisTPEtaTotal", ";", 48, -2.4, 2.4); + hisEffEta_ = dir.make("HisTPEta", ";", 48, -2.4, 2.4); + effEta_ = dir.make("EffEta", ";", 48, -2.4, 2.4); + const double rangeInv2R = dataFormats_->format(Variable::inv2R, Process::dr).range(); + hisEffInv2R_ = dir.make("HisTPInv2R", ";", 32, -rangeInv2R / 2., rangeInv2R / 2.); + hisEffInv2RTotal_ = dir.make("HisTPInv2RTotal", ";", 32, -rangeInv2R / 2., rangeInv2R / 2.); + effInv2R_ = dir.make("EffInv2R", ";", 32, -rangeInv2R / 2., rangeInv2R / 2.); + hisEffPT_ = dir.make("HisTPPT", ";", 100, 0, 100); + hisEffPTTotal_ = dir.make("HisTPPTTotal", ";", 100, 0, 100); + effPT_ = dir.make("EffPT", ";", 100, 0, 100); + // tracks + hisTracks_ = dir.make("HisTracks", ";", 40, 0., 400); + // layers + hisLayers_ = dir.make("HisLayers", ";", 8, 0, 8); + hisNumLayers_ = dir.make("HisNumLayers", ";", 9, 0, 9); + profNumLayers_ = dir.make("Prof NumLayers", ";", 32, 0, 2.4); + } + + void AnalyzerKF::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + static const int numLayers = setup_->numLayers(); + auto fill = [this](const TPPtr& tpPtr, TH1F* hisEta, TH1F* hisInv2R, TH1F* hisPT, TH1F* hisD0) { + hisEta->Fill(tpPtr->eta()); + hisInv2R->Fill(tpPtr->charge() / tpPtr->pt() * setup_->invPtToDphi()); + hisPT->Fill(tpPtr->pt()); + hisD0->Fill(tpPtr->d0()); + }; + // read in kf products + edm::Handle handleStubs; + iEvent.getByToken(edGetTokenStubs_, handleStubs); + const tt::StreamsStub& allStubs = *handleStubs; + edm::Handle handleTracks; + iEvent.getByToken(edGetTokenTracks_, handleTracks); + const tt::StreamsTrack& allTracks = *handleTracks; + edm::Handle handleNumStatesAccepted; + iEvent.getByToken(edGetTokenNumStatesAccepted_, handleNumStatesAccepted); + edm::Handle handleNumStatesTruncated; + iEvent.getByToken(edGetTokenNumStatesTruncated_, handleNumStatesTruncated); + // read in MCTruth + const tt::StubAssociation* selection = nullptr; + const tt::StubAssociation* reconstructable = nullptr; + if (useMCTruth_) { + edm::Handle handleSelection; + iEvent.getByToken(edGetTokenSelection_, handleSelection); + selection = handleSelection.product(); + prof_->Fill(9, selection->numTPs()); + edm::Handle handleReconstructable; + iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); + reconstructable = handleReconstructable.product(); + for (const auto& p : selection->getTrackingParticleToTTStubsMap()) + fill(p.first, hisEffEtaTotal_, hisEffInv2RTotal_, hisEffPTTotal_, hisEffD0Total_); + } + // analyze kf products and associate found tracks with reconstrucable TrackingParticles + std::set tpPtrs; + std::set tpPtrsSelection; + std::set tpPtrsMax; + int numMatched(0); + int numTracks(0); + for (int region = 0; region < setup_->numRegions(); region++) { + int nRegionStubs(0); + int nRegionTracks(0); + const int offset = region * numLayers; + const tt::StreamTrack& channelTracks = allTracks[region]; + hisChannel_->Fill(channelTracks.size()); + profChannel_->Fill(1, channelTracks.size()); + std::vector tracks; + std::vector stubs; + std::vector> tracksStubs(channelTracks.size(), std::vector(numLayers, nullptr)); + tracks.reserve(channelTracks.size()); + stubs.reserve(channelTracks.size() * numLayers); + for (int frame = 0; frame < (int)channelTracks.size(); frame++) { + tracks.emplace_back(channelTracks[frame], dataFormats_); + const double eta = std::abs(std::asinh(tracks.back().cot())); + int nLayers(0); + for (int layer = 0; layer < numLayers; layer++) { + const tt::FrameStub& fs = allStubs[offset + layer][frame]; + if (fs.first.isNull()) + continue; + stubs.emplace_back(fs, dataFormats_); + tracksStubs[frame][layer] = &stubs.back(); + hisLayers_->Fill(layer); + nLayers++; + } + hisNumLayers_->Fill(nLayers); + profNumLayers_->Fill(eta, nLayers); + } + nRegionStubs += stubs.size(); + nRegionTracks += tracks.size(); + if (!useMCTruth_) + continue; + int tmp(0); + associate(tracks, tracksStubs, region, selection, tpPtrsSelection, tmp, hisRes_, profRes_); + associate(tracks, + tracksStubs, + region, + reconstructable, + tpPtrs, + numMatched, + std::vector(), + std::vector()); + associate( + tracks, tracksStubs, region, selection, tpPtrsMax, tmp, std::vector(), std::vector(), false); + numTracks += nRegionTracks; + prof_->Fill(1, nRegionStubs); + prof_->Fill(2, nRegionTracks); + } + for (const TPPtr& tpPtr : tpPtrsSelection) + fill(tpPtr, hisEffEta_, hisEffInv2R_, hisEffPT_, hisEffD0_); + prof_->Fill(4, numMatched); + prof_->Fill(5, numTracks); + prof_->Fill(6, tpPtrs.size()); + prof_->Fill(7, tpPtrsSelection.size()); + prof_->Fill(10, *handleNumStatesAccepted); + prof_->Fill(11, *handleNumStatesTruncated); + prof_->Fill(12, tpPtrsMax.size()); + hisTracks_->Fill(numTracks); + nEvents_++; + } + + void AnalyzerKF::endJob() { + if (nEvents_ == 0) + return; + // effi + effD0_->SetPassedHistogram(*hisEffD0_, "f"); + effD0_->SetTotalHistogram(*hisEffD0Total_, "f"); + effEta_->SetPassedHistogram(*hisEffEta_, "f"); + effEta_->SetTotalHistogram(*hisEffEtaTotal_, "f"); + effInv2R_->SetPassedHistogram(*hisEffInv2R_, "f"); + effInv2R_->SetTotalHistogram(*hisEffInv2RTotal_, "f"); + effPT_->SetPassedHistogram(*hisEffPT_, "f"); + effPT_->SetTotalHistogram(*hisEffPTTotal_, "f"); + // printout SF summary + const double totalTPs = prof_->GetBinContent(9); + const double numStubs = prof_->GetBinContent(1); + const double numTracks = prof_->GetBinContent(2); + const double totalTracks = prof_->GetBinContent(5); + const double numTracksMatched = prof_->GetBinContent(4); + const double numTPsAll = prof_->GetBinContent(6); + const double numTPsEff = prof_->GetBinContent(7); + const double numTPsEffMax = prof_->GetBinContent(12); + const double errStubs = prof_->GetBinError(1); + const double errTracks = prof_->GetBinError(2); + const double fracFake = (totalTracks - numTracksMatched) / totalTracks; + const double fracDup = (numTracksMatched - numTPsAll) / totalTracks; + const double eff = numTPsEff / totalTPs; + const double errEff = std::sqrt(eff * (1. - eff) / totalTPs / nEvents_); + const double effMax = numTPsEffMax / totalTPs; + const double errEffMax = std::sqrt(effMax * (1. - effMax) / totalTPs / nEvents_); + const int numStates = prof_->GetBinContent(10); + const int numStatesLost = prof_->GetBinContent(11); + const double fracSatest = numStates / (double)(numStates + numStatesLost); + const std::vector nums = {numStubs, numTracks}; + const std::vector errs = {errStubs, errTracks}; + const int wNums = std::ceil(std::log10(*std::max_element(nums.begin(), nums.end()))) + 5; + const int wErrs = std::ceil(std::log10(*std::max_element(errs.begin(), errs.end()))) + 5; + log_ << " KF SUMMARY " << std::endl; + log_ << "number of stubs per TFP = " << std::setw(wNums) << numStubs << " +- " << std::setw(wErrs) << errStubs + << std::endl; + log_ << "number of tracks per TFP = " << std::setw(wNums) << numTracks << " +- " << std::setw(wErrs) + << errTracks << std::endl; + log_ << " tracking efficiency = " << std::setw(wNums) << eff << " +- " << std::setw(wErrs) << errEff + << std::endl; + log_ << " max tracking efficiency = " << std::setw(wNums) << effMax << " +- " << std::setw(wErrs) << errEffMax + << std::endl; + log_ << " fake rate = " << std::setw(wNums) << fracFake << std::endl; + log_ << " duplicate rate = " << std::setw(wNums) << fracDup << std::endl; + log_ << " state assessment fraction = " << std::setw(wNums) << fracSatest << std::endl; + log_ << " number of states per TFP = " << std::setw(wNums) << (numStates + numStatesLost) / setup_->numRegions() + << std::endl; + log_ << "============================================================="; + edm::LogPrint(moduleDescription().moduleName()) << log_.str(); + } + + // + void AnalyzerKF::associate(const std::vector& tracks, + const std::vector>& tracksStubs, + int region, + const tt::StubAssociation* ass, + std::set& tps, + int& sum, + const std::vector& his, + const std::vector& prof, + bool perfect) const { + for (int frame = 0; frame < static_cast(tracks.size()); frame++) { + const TrackKF& track = tracks[frame]; + const std::vector& stubs = tracksStubs[frame]; + std::vector ttStubRefs; + ttStubRefs.reserve(stubs.size()); + TTBV hitPattern(0, setup_->numLayers()); + int layer(-1); + for (StubKF* stub : stubs) { + layer++; + if (!stub) + continue; + hitPattern.set(layer); + ttStubRefs.push_back(stub->frame().first); + } + const std::vector& tpPtrs = perfect ? ass->associateFinal(ttStubRefs) : ass->associate(ttStubRefs); + if (tpPtrs.empty()) + continue; + sum++; + std::copy(tpPtrs.begin(), tpPtrs.end(), std::inserter(tps, tps.begin())); + if (his.empty()) + continue; + const double cot = track.cot(); + const double z0 = track.zT() - setup_->chosenRofZ() * cot; + const double inv2R = track.inv2R(); + const double phi0 = tt::deltaPhi(track.phiT() - setup_->chosenRofPhi() * inv2R + + region * dataFormats_->format(Variable::phiT, Process::kf).range()); + for (const TPPtr& tpPtr : tpPtrs) { + const double tpPhi0 = tpPtr->phi(); + const double tpCot = std::sinh(tpPtr->eta()); + const double tpInv2R = -setup_->invPtToDphi() * tpPtr->charge() / tpPtr->pt(); + const math::XYZPointD& v = tpPtr->vertex(); + const double tpZ0 = v.z() - tpCot * (v.x() * cos(tpPhi0) + v.y() * sin(tpPhi0)); + const double dCot = tpCot - cot; + const double dZ0 = tpZ0 - z0; + const double dInv2R = tpInv2R - inv2R; + const double dPhi0 = tt::deltaPhi(tpPhi0 - phi0); + const double dD0 = tpPtr->d0() + track.frame().first->d0(); + const std::vector ds = {dPhi0, dInv2R / setup_->invPtToDphi(), dZ0, dCot, dD0}; + for (int i = 0; i < (int)ds.size(); i++) { + his[i]->Fill(ds[i]); + prof[i]->Fill(std::abs(tpPtr->eta()), std::abs(ds[i])); + } + if (tpCot < 0) { + his[6]->Fill(dZ0); + his[8]->Fill(dCot); + } else { + his[5]->Fill(dZ0); + his[7]->Fill(dCot); + } + } + } + } + +} // namespace trklet + +DEFINE_FWK_MODULE(trklet::AnalyzerKF); diff --git a/L1Trigger/TrackFindingTracklet/test/AnalyzerKFin.cc b/L1Trigger/TrackFindingTracklet/test/AnalyzerKFin.cc deleted file mode 100644 index 101b77fe41996..0000000000000 --- a/L1Trigger/TrackFindingTracklet/test/AnalyzerKFin.cc +++ /dev/null @@ -1,320 +0,0 @@ -#include "FWCore/Framework/interface/one/EDAnalyzer.h" -#include "FWCore/Framework/interface/Run.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/ServiceRegistry/interface/Service.h" -#include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "FWCore/Utilities/interface/EDGetToken.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/Utilities/interface/Exception.h" -#include "CommonTools/UtilAlgos/interface/TFileService.h" -#include "DataFormats/Common/interface/Handle.h" - -#include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" -#include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" -#include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h" - -#include -#include - -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace edm; -using namespace trackerTFP; -using namespace tt; - -namespace trklet { - - /*! \class trklet::AnalyzerKFin - * \brief Class to analyze hardware like structured TTStub Collection generated by Tracklet - * \author Thomas Schuh - * \date 2020, Nov - */ - class AnalyzerKFin : public one::EDAnalyzer { - public: - AnalyzerKFin(const ParameterSet& iConfig); - void beginJob() override {} - void beginRun(const Run& iEvent, const EventSetup& iSetup) override; - void analyze(const Event& iEvent, const EventSetup& iSetup) override; - void endRun(const Run& iEvent, const EventSetup& iSetup) override {} - void endJob() override; - - private: - // - void formTracks(const StreamsTrack& streamsTrack, - const StreamsStub& streamsStubs, - vector>& tracks, - int channel) const; - // - void associate(const vector>& tracks, - const StubAssociation* ass, - set& tps, - int& sum, - bool perfect = false) const; - // ED input token of stubs - EDGetTokenT edGetTokenAcceptedStubs_; - // ED input token of tracks - EDGetTokenT edGetTokenAcceptedTracks_; - // ED input token of lost stubs - EDGetTokenT edGetTokenLostStubs_; - // ED input token of lost tracks - EDGetTokenT edGetTokenLostTracks_; - // ED input token of TTStubRef to TPPtr association for tracking efficiency - EDGetTokenT edGetTokenSelection_; - // ED input token of TTStubRef to recontructable TPPtr association - EDGetTokenT edGetTokenReconstructable_; - // Setup token - ESGetToken esGetTokenSetup_; - // DataFormats token - ESGetToken esGetTokenDataFormats_; - // stores, calculates and provides run-time constants - const Setup* setup_ = nullptr; - // helper class to extract structured data from tt::Frames - const DataFormats* dataFormats_ = nullptr; - // enables analyze of TPs - bool useMCTruth_; - // - int nEvents_ = 0; - - // Histograms - - TProfile* prof_; - TProfile* profChannel_; - TH1F* hisChannel_; - - // printout - stringstream log_; - }; - - AnalyzerKFin::AnalyzerKFin(const ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { - usesResource("TFileService"); - // book in- and output ED products - const string& label = iConfig.getParameter("LabelKFin"); - const string& branchAcceptedStubs = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchAcceptedTracks = iConfig.getParameter("BranchAcceptedTracks"); - const string& branchLostStubs = iConfig.getParameter("BranchLostStubs"); - const string& branchLostTracks = iConfig.getParameter("BranchLostTracks"); - edGetTokenAcceptedStubs_ = consumes(InputTag(label, branchAcceptedStubs)); - edGetTokenAcceptedTracks_ = consumes(InputTag(label, branchAcceptedTracks)); - edGetTokenLostStubs_ = consumes(InputTag(label, branchLostStubs)); - edGetTokenLostTracks_ = consumes(InputTag(label, branchLostTracks)); - if (useMCTruth_) { - const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); - const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); - edGetTokenSelection_ = consumes(inputTagSelecttion); - edGetTokenReconstructable_ = consumes(inputTagReconstructable); - } - // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); - // log config - log_.setf(ios::fixed, ios::floatfield); - log_.precision(4); - } - - void AnalyzerKFin::beginRun(const Run& iEvent, const EventSetup& iSetup) { - // helper class to store configurations - setup_ = &iSetup.getData(esGetTokenSetup_); - // helper class to extract structured data from tt::Frames - dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); - // book histograms - Service fs; - TFileDirectory dir; - dir = fs->mkdir("KFin"); - prof_ = dir.make("Counts", ";", 10, 0.5, 10.5); - prof_->GetXaxis()->SetBinLabel(1, "Stubs"); - prof_->GetXaxis()->SetBinLabel(2, "Tracks"); - prof_->GetXaxis()->SetBinLabel(3, "Lost Tracks"); - prof_->GetXaxis()->SetBinLabel(4, "Matched Tracks"); - prof_->GetXaxis()->SetBinLabel(5, "All Tracks"); - prof_->GetXaxis()->SetBinLabel(6, "Found TPs"); - prof_->GetXaxis()->SetBinLabel(7, "Found selected TPs"); - prof_->GetXaxis()->SetBinLabel(8, "Lost TPs"); - prof_->GetXaxis()->SetBinLabel(9, "All TPs"); - prof_->GetXaxis()->SetBinLabel(10, "Perfect TPs"); - // channel occupancy - constexpr int maxOcc = 180; - const int numChannels = setup_->kfNumWorker(); - hisChannel_ = dir.make("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5); - profChannel_ = dir.make("Prof Channel Occupancy", ";", numChannels, -.5, numChannels - .5); - } - - void AnalyzerKFin::analyze(const Event& iEvent, const EventSetup& iSetup) { - // read in ht products - Handle handleAcceptedStubs; - iEvent.getByToken(edGetTokenAcceptedStubs_, handleAcceptedStubs); - const StreamsStub& acceptedStubs = *handleAcceptedStubs; - Handle handleAcceptedTracks; - iEvent.getByToken(edGetTokenAcceptedTracks_, handleAcceptedTracks); - const StreamsTrack& acceptedTracks = *handleAcceptedTracks; - Handle handleLostStubs; - iEvent.getByToken(edGetTokenLostStubs_, handleLostStubs); - const StreamsStub& lostStubs = *handleLostStubs; - Handle handleLostTracks; - iEvent.getByToken(edGetTokenLostTracks_, handleLostTracks); - const StreamsTrack& lostTracks = *handleLostTracks; - // read in MCTruth - const StubAssociation* selection = nullptr; - const StubAssociation* reconstructable = nullptr; - if (useMCTruth_) { - Handle handleSelection; - iEvent.getByToken(edGetTokenSelection_, handleSelection); - selection = handleSelection.product(); - prof_->Fill(9, selection->numTPs()); - Handle handleReconstructable; - iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); - reconstructable = handleReconstructable.product(); - } - // analyze ht products and associate found tracks with reconstrucable TrackingParticles - set tpPtrs; - set tpPtrsSelection; - set tpPtrsPerfect; - set tpPtrsLost; - int allMatched(0); - int allTracks(0); - for (int region = 0; region < setup_->numRegions(); region++) { - const int offset = region * setup_->kfNumWorker(); - int nStubs(0); - int nTracks(0); - int nLost(0); - for (int channel = 0; channel < setup_->kfNumWorker(); channel++) { - vector> tracks; - formTracks(acceptedTracks, acceptedStubs, tracks, offset + channel); - vector> lost; - formTracks(lostTracks, lostStubs, lost, offset + channel); - nTracks += tracks.size(); - nStubs += accumulate(tracks.begin(), tracks.end(), 0UL, [](auto sum, const vector& track) { - return sum + track.size(); - }); - nLost += lost.size(); - allTracks += tracks.size(); - if (!useMCTruth_) - continue; - int tmp(0); - associate(tracks, selection, tpPtrsSelection, tmp); - associate(tracks, selection, tpPtrsPerfect, tmp, true); - associate(lost, selection, tpPtrsLost, tmp); - associate(tracks, reconstructable, tpPtrs, allMatched); - const StreamTrack& stream = acceptedTracks[offset + channel]; - const auto end = - find_if(stream.rbegin(), stream.rend(), [](const FrameTrack& frame) { return frame.first.isNonnull(); }); - const int size = distance(stream.begin(), end.base()) - 1; - hisChannel_->Fill(size); - profChannel_->Fill(channel, size); - } - prof_->Fill(1, nStubs); - prof_->Fill(2, nTracks); - prof_->Fill(3, nLost); - } - vector recovered; - recovered.reserve(tpPtrsLost.size()); - set_intersection(tpPtrsLost.begin(), tpPtrsLost.end(), tpPtrs.begin(), tpPtrs.end(), back_inserter(recovered)); - for (const TPPtr& tpPtr : recovered) - tpPtrsLost.erase(tpPtr); - prof_->Fill(4, allMatched); - prof_->Fill(5, allTracks); - prof_->Fill(6, tpPtrs.size()); - prof_->Fill(7, tpPtrsSelection.size()); - prof_->Fill(8, tpPtrsLost.size()); - prof_->Fill(10, tpPtrsPerfect.size()); - nEvents_++; - } - - void AnalyzerKFin::endJob() { - if (nEvents_ == 0) - return; - // printout SF summary - const double totalTPs = prof_->GetBinContent(9); - const double numStubs = prof_->GetBinContent(1); - const double numTracks = prof_->GetBinContent(2); - const double numTracksLost = prof_->GetBinContent(3); - const double totalTracks = prof_->GetBinContent(5); - const double numTracksMatched = prof_->GetBinContent(4); - const double numTPsAll = prof_->GetBinContent(6); - const double numTPsEff = prof_->GetBinContent(7); - const double numTPsLost = prof_->GetBinContent(8); - const double numTPsEffPerfect = prof_->GetBinContent(10); - const double errStubs = prof_->GetBinError(1); - const double errTracks = prof_->GetBinError(2); - const double errTracksLost = prof_->GetBinError(3); - const double fracFake = (totalTracks - numTracksMatched) / totalTracks; - const double fracDup = (numTracksMatched - numTPsAll) / totalTracks; - const double eff = numTPsEff / totalTPs; - const double errEff = sqrt(eff * (1. - eff) / totalTPs / nEvents_); - const double effLoss = numTPsLost / totalTPs; - const double errEffLoss = sqrt(effLoss * (1. - effLoss) / totalTPs / nEvents_); - const double effPerfect = numTPsEffPerfect / totalTPs; - const double errEffPerfect = sqrt(effPerfect * (1. - effPerfect) / totalTPs / nEvents_); - const vector nums = {numStubs, numTracks, numTracksLost}; - const vector errs = {errStubs, errTracks, errTracksLost}; - const int wNums = ceil(log10(*max_element(nums.begin(), nums.end()))) + 5; - const int wErrs = ceil(log10(*max_element(errs.begin(), errs.end()))) + 5; - log_ << " KFin SUMMARY " << endl; - log_ << "number of stubs per TFP = " << setw(wNums) << numStubs << " +- " << setw(wErrs) << errStubs << endl; - log_ << "number of tracks per TFP = " << setw(wNums) << numTracks << " +- " << setw(wErrs) << errTracks - << endl; - log_ << "number of lost tracks per TFP = " << setw(wNums) << numTracksLost << " +- " << setw(wErrs) << errTracksLost - << endl; - log_ << " current tracking efficiency = " << setw(wNums) << effPerfect << " +- " << setw(wErrs) << errEffPerfect - << endl; - log_ << " max tracking efficiency = " << setw(wNums) << eff << " +- " << setw(wErrs) << errEff << endl; - log_ << " lost tracking efficiency = " << setw(wNums) << effLoss << " +- " << setw(wErrs) << errEffLoss << endl; - log_ << " fake rate = " << setw(wNums) << fracFake << endl; - log_ << " duplicate rate = " << setw(wNums) << fracDup << endl; - log_ << "============================================================="; - LogPrint("L1Trigger/TrackerTFP") << log_.str(); - } - - // - void AnalyzerKFin::formTracks(const StreamsTrack& streamsTrack, - const StreamsStub& streamsStubs, - vector>& tracks, - int channel) const { - const int offset = channel * setup_->numLayers(); - const StreamTrack& streamTrack = streamsTrack[channel]; - const int numTracks = accumulate(streamTrack.begin(), streamTrack.end(), 0, [](int sum, const FrameTrack& frame) { - return sum + (frame.first.isNonnull() ? 1 : 0); - }); - tracks.reserve(numTracks); - for (int frame = 0; frame < (int)streamTrack.size(); frame++) { - const FrameTrack& frameTrack = streamTrack[frame]; - if (frameTrack.first.isNull()) - continue; - vector ttStubRefs; - ttStubRefs.reserve(setup_->numLayers()); - for (int layer = 0; layer < setup_->numLayers(); layer++) { - const FrameStub& stub = streamsStubs[offset + layer][frame]; - if (stub.first.isNonnull()) - ttStubRefs.push_back(stub.first); - } - tracks.push_back(ttStubRefs); - } - } - - // - void AnalyzerKFin::associate(const vector>& tracks, - const StubAssociation* ass, - set& tps, - int& sum, - bool perfect) const { - for (const vector& ttStubRefs : tracks) { - const vector& tpPtrs = perfect ? ass->associateFinal(ttStubRefs) : ass->associate(ttStubRefs); - if (tpPtrs.empty()) - continue; - sum++; - copy(tpPtrs.begin(), tpPtrs.end(), inserter(tps, tps.begin())); - } - } - -} // namespace trklet - -DEFINE_FWK_MODULE(trklet::AnalyzerKFin); diff --git a/L1Trigger/TrackFindingTracklet/test/AnalyzerKFout.cc b/L1Trigger/TrackFindingTracklet/test/AnalyzerKFout.cc deleted file mode 100644 index d8325b661e5b3..0000000000000 --- a/L1Trigger/TrackFindingTracklet/test/AnalyzerKFout.cc +++ /dev/null @@ -1,254 +0,0 @@ -#include "FWCore/Framework/interface/one/EDAnalyzer.h" -#include "FWCore/Framework/interface/Run.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/ServiceRegistry/interface/Service.h" -#include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "FWCore/Utilities/interface/EDGetToken.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/Utilities/interface/Exception.h" -#include "CommonTools/UtilAlgos/interface/TFileService.h" -#include "DataFormats/Common/interface/Handle.h" - -#include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" -#include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" -#include "L1Trigger/TrackerTFP/interface/LayerEncoding.h" -#include "L1Trigger/TrackerTFP/interface/KalmanFilterFormats.h" - -#include -#include - -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace edm; -using namespace tt; -using namespace trackerTFP; - -namespace trklet { - - /*! \class trklet::AnalyzerKFout - * \brief Class to analyze hardware like structured Track Collection generated by Kalman Filter output module - * \author Thomas Schuh - * \date 2021, Aug - */ - class AnalyzerKFout : public one::EDAnalyzer { - public: - AnalyzerKFout(const ParameterSet& iConfig); - void beginJob() override {} - void beginRun(const Run& iEvent, const EventSetup& iSetup) override; - void analyze(const Event& iEvent, const EventSetup& iSetup) override; - void endRun(const Run& iEvent, const EventSetup& iSetup) override {} - void endJob() override; - - private: - // - void associate(const set& ttTracks, const StubAssociation* ass, set& tps, int& sum) const; - - // ED input token of accepted Stubs - EDGetTokenT edGetTokenAccepted_; - // ED input token of lost Tracks - EDGetTokenT edGetTokenLost_; - // ED input token of TTStubRef to TPPtr association for tracking efficiency - EDGetTokenT edGetTokenSelection_; - // ED input token of TTStubRef to recontructable TPPtr association - EDGetTokenT edGetTokenReconstructable_; - // Setup token - ESGetToken esGetTokenSetup_; - // DataFormats token - ESGetToken esGetTokenDataFormats_; - // stores, calculates and provides run-time constants - const Setup* setup_ = nullptr; - // enables analyze of TPs - bool useMCTruth_; - // - int nEvents_ = 0; - - // Histograms - - TProfile* prof_; - TProfile* profChannel_; - TH1F* hisChannel_; - - // printout - stringstream log_; - }; - - AnalyzerKFout::AnalyzerKFout(const ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { - usesResource("TFileService"); - // book in- and output ED products - const string& label = iConfig.getParameter("LabelKFout"); - const string& branchAccepted = iConfig.getParameter("BranchAcceptedTracks"); - const string& branchLost = iConfig.getParameter("BranchLostTracks"); - edGetTokenAccepted_ = consumes(InputTag(label, branchAccepted)); - edGetTokenLost_ = consumes(InputTag(label, branchLost)); - if (useMCTruth_) { - const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); - const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); - edGetTokenSelection_ = consumes(inputTagSelecttion); - edGetTokenReconstructable_ = consumes(inputTagReconstructable); - } - // book ES products - esGetTokenSetup_ = esConsumes(); - // log config - log_.setf(ios::fixed, ios::floatfield); - log_.precision(4); - } - - void AnalyzerKFout::beginRun(const Run& iEvent, const EventSetup& iSetup) { - // helper class to store configurations - setup_ = &iSetup.getData(esGetTokenSetup_); - // book histograms - Service fs; - TFileDirectory dir; - dir = fs->mkdir("KFout"); - prof_ = dir.make("Counts", ";", 9, 0.5, 9.5); - prof_->GetXaxis()->SetBinLabel(1, "Stubs"); - prof_->GetXaxis()->SetBinLabel(2, "Tracks"); - prof_->GetXaxis()->SetBinLabel(3, "Lost Tracks"); - prof_->GetXaxis()->SetBinLabel(4, "Matched Tracks"); - prof_->GetXaxis()->SetBinLabel(5, "All Tracks"); - prof_->GetXaxis()->SetBinLabel(6, "Found TPs"); - prof_->GetXaxis()->SetBinLabel(7, "Found selected TPs"); - prof_->GetXaxis()->SetBinLabel(8, "Lost TPs"); - prof_->GetXaxis()->SetBinLabel(9, "All TPs"); - // channel occupancy - constexpr int maxOcc = 180; - const int numChannels = setup_->tfpNumChannel(); - hisChannel_ = dir.make("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5); - profChannel_ = dir.make("Prof Channel Occupancy", ";", numChannels, -.5, numChannels - .5); - } - - void AnalyzerKFout::analyze(const Event& iEvent, const EventSetup& iSetup) { - // read in kf products - Handle handleAccepted; - iEvent.getByToken(edGetTokenAccepted_, handleAccepted); - Handle handleLost; - iEvent.getByToken(edGetTokenLost_, handleLost); - // read in MCTruth - const StubAssociation* selection = nullptr; - const StubAssociation* reconstructable = nullptr; - if (useMCTruth_) { - Handle handleSelection; - iEvent.getByToken(edGetTokenSelection_, handleSelection); - selection = handleSelection.product(); - prof_->Fill(9, selection->numTPs()); - Handle handleReconstructable; - iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); - reconstructable = handleReconstructable.product(); - } - // analyze kfout products and associate found tracks with reconstrucable TrackingParticles - set tpPtrs; - set tpPtrsSelection; - set tpPtrsLost; - int allMatched(0); - int allTracks(0); - for (int region = 0; region < setup_->numRegions(); region++) { - int nStubsRegion(0); - int nTracksRegion(0); - int nLostRegion(0); - for (int channel = 0; channel < setup_->tfpNumChannel(); channel++) { - const int index = region * setup_->tfpNumChannel() + channel; - const StreamTrack& accepted = handleAccepted->at(index); - const StreamTrack& lost = handleLost->at(index); - hisChannel_->Fill(accepted.size()); - profChannel_->Fill(channel, accepted.size()); - set tracks; - for (const FrameTrack& frame : accepted) - if (frame.first.isNonnull()) - tracks.insert(frame.first); - nTracksRegion += tracks.size(); - nStubsRegion += accumulate(tracks.begin(), tracks.end(), 0UL, [](auto sum, const TTTrackRef& ttTrackRef) { - return sum + ttTrackRef->getStubRefs().size(); - }); - set tracksLost; - for (const FrameTrack& frame : lost) - if (frame.first.isNonnull()) - tracksLost.insert(frame.first); - nLostRegion += tracksLost.size(); - allTracks += tracks.size(); - int tmp(0); - associate(tracks, selection, tpPtrsSelection, tmp); - associate(tracksLost, selection, tpPtrsLost, tmp); - associate(tracks, reconstructable, tpPtrs, allMatched); - } - prof_->Fill(1, nStubsRegion); - prof_->Fill(2, nTracksRegion); - prof_->Fill(3, nLostRegion); - } - deque tpPtrsRealLost; - set_difference(tpPtrsLost.begin(), tpPtrsLost.end(), tpPtrs.begin(), tpPtrs.end(), back_inserter(tpPtrsRealLost)); - prof_->Fill(4, allMatched); - prof_->Fill(5, allTracks); - prof_->Fill(6, tpPtrs.size()); - prof_->Fill(7, tpPtrsSelection.size()); - prof_->Fill(8, tpPtrsRealLost.size()); - nEvents_++; - } - - void AnalyzerKFout::endJob() { - if (nEvents_ == 0) - return; - // printout SF summary - const double totalTPs = prof_->GetBinContent(9); - const double numStubs = prof_->GetBinContent(1); - const double numTracks = prof_->GetBinContent(2); - const double numTracksLost = prof_->GetBinContent(3); - const double totalTracks = prof_->GetBinContent(5); - const double numTracksMatched = prof_->GetBinContent(4); - const double numTPsAll = prof_->GetBinContent(6); - const double numTPsEff = prof_->GetBinContent(7); - const double numTPsLost = prof_->GetBinContent(8); - const double errStubs = prof_->GetBinError(1); - const double errTracks = prof_->GetBinError(2); - const double errTracksLost = prof_->GetBinError(3); - const double fracFake = (totalTracks - numTracksMatched) / totalTracks; - const double fracDup = (numTracksMatched - numTPsAll) / totalTracks; - const double eff = numTPsEff / totalTPs; - const double errEff = sqrt(eff * (1. - eff) / totalTPs / nEvents_); - const double effLoss = numTPsLost / totalTPs; - const double errEffLoss = sqrt(effLoss * (1. - effLoss) / totalTPs / nEvents_); - const vector nums = {numStubs, numTracks, numTracksLost}; - const vector errs = {errStubs, errTracks, errTracksLost}; - const int wNums = ceil(log10(*max_element(nums.begin(), nums.end()))) + 5; - const int wErrs = ceil(log10(*max_element(errs.begin(), errs.end()))) + 5; - log_ << " KFout SUMMARY " << endl; - //log_ << "number of stubs per TFP = " << setw(wNums) << numStubs << " +- " << setw(wErrs) << errStubs << endl; - log_ << "number of tracks per TFP = " << setw(wNums) << numTracks << " +- " << setw(wErrs) << errTracks - << endl; - log_ << "number of lost tracks per TFP = " << setw(wNums) << numTracksLost << " +- " << setw(wErrs) << errTracksLost - << endl; - log_ << " tracking efficiency = " << setw(wNums) << eff << " +- " << setw(wErrs) << errEff << endl; - log_ << " lost tracking efficiency = " << setw(wNums) << effLoss << " +- " << setw(wErrs) << errEffLoss << endl; - log_ << " fake rate = " << setw(wNums) << fracFake << endl; - log_ << " duplicate rate = " << setw(wNums) << fracDup << endl; - log_ << "============================================================="; - LogPrint("L1Trigger/TrackerTFP") << log_.str(); - } - - // - void AnalyzerKFout::associate(const set& ttTracks, - const StubAssociation* ass, - set& tps, - int& sum) const { - for (const TTTrackRef& ttTrack : ttTracks) { - const vector& ttStubRefs = ttTrack->getStubRefs(); - const vector& tpPtrs = ass->associate(ttStubRefs); - if (tpPtrs.empty()) - continue; - sum++; - copy(tpPtrs.begin(), tpPtrs.end(), inserter(tps, tps.begin())); - } - } - -} // namespace trklet - -DEFINE_FWK_MODULE(trklet::AnalyzerKFout); diff --git a/L1Trigger/TrackFindingTracklet/test/AnalyzerTBout.cc b/L1Trigger/TrackFindingTracklet/test/AnalyzerTBout.cc deleted file mode 100644 index d4a89e1a96100..0000000000000 --- a/L1Trigger/TrackFindingTracklet/test/AnalyzerTBout.cc +++ /dev/null @@ -1,429 +0,0 @@ -#include "FWCore/Framework/interface/one/EDAnalyzer.h" -#include "FWCore/Framework/interface/Run.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/ServiceRegistry/interface/Service.h" -#include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "FWCore/Utilities/interface/EDGetToken.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/Utilities/interface/Exception.h" -#include "CommonTools/UtilAlgos/interface/TFileService.h" -#include "DataFormats/Common/interface/Handle.h" - -#include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" -#include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" -#include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h" -#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace edm; -using namespace trackerTFP; -using namespace tt; - -namespace trklet { - - // stub resolution plots helper - enum Resolution { Phi, Z, NumResolution }; - constexpr initializer_list AllResolution = {Phi, Z}; - constexpr auto NameResolution = {"Phi", "Z"}; - inline string name(Resolution r) { return string(*(NameResolution.begin() + r)); } - - /*! \class trklet::AnalyzerTBout - * \brief Class to analyze hardware like structured TTStub Collection generated by Tracklet - * \author Thomas Schuh - * \date 2021, Nov - */ - class AnalyzerTBout : public one::EDAnalyzer { - public: - AnalyzerTBout(const ParameterSet& iConfig); - void beginJob() override {} - void beginRun(const Run& iEvent, const EventSetup& iSetup) override; - void analyze(const Event& iEvent, const EventSetup& iSetup) override; - void endRun(const Run& iEvent, const EventSetup& iSetup) override {} - void endJob() override; - - private: - // - void formTracks(const StreamsTrack& streamsTrack, - const StreamsStub& streamsStubs, - vector>& tracks, - int channel); - // - void associate(const vector>& tracks, const StubAssociation* ass, set& tps, int& sum) const; - // - void fill(const FrameTrack& frameTrack, const FrameStub& frameStub); - - // ED input token of dtc stubs - EDGetTokenT edGetTokenTTDTC_; - // ED input token of stubs - EDGetTokenT edGetTokenAcceptedStubs_; - // ED input token of tracks - EDGetTokenT edGetTokenAcceptedTracks_; - // ED input token of lost stubs - EDGetTokenT edGetTokenLostStubs_; - // ED input token of lost tracks - EDGetTokenT edGetTokenLostTracks_; - // ED input token of TTStubRef to TPPtr association for tracking efficiency - EDGetTokenT edGetTokenSelection_; - // ED input token of TTStubRef to recontructable TPPtr association - EDGetTokenT edGetTokenReconstructable_; - // Setup token - ESGetToken esGetTokenSetup_; - // DataFormats token - ESGetToken esGetTokenDataFormats_; - // ChannelAssignment token - ESGetToken esGetTokenChannelAssignment_; - // stores, calculates and provides run-time constants - const Setup* setup_ = nullptr; - // - const Settings settings_; - // helper class to extract structured data from tt::Frames - const DataFormats* dataFormats_ = nullptr; - // helper class to assign tracklet track to channel - const ChannelAssignment* channelAssignment_ = nullptr; - // enables analyze of TPs - bool useMCTruth_; - // - int nEvents_ = 0; - // - vector> regionStubs_; - // - int region_; - - // Histograms - - TProfile* prof_; - TProfile* profChannel_; - TH1F* hisChannel_; - vector hisResolution_; - vector profResolution_; - vector hisResolutionMe_; - vector hisResolutionThey_; - vector his2Resolution_; - - // printout - stringstream log_; - }; - - AnalyzerTBout::AnalyzerTBout(const ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { - usesResource("TFileService"); - // book in- and output ED products - const InputTag& inputTag = iConfig.getParameter("InputTagDTC"); - const string& label = iConfig.getParameter("LabelTBout"); - const string& branchAcceptedStubs = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchAcceptedTracks = iConfig.getParameter("BranchAcceptedTracks"); - const string& branchLostStubs = iConfig.getParameter("BranchLostStubs"); - const string& branchLostTracks = iConfig.getParameter("BranchLostTracks"); - edGetTokenTTDTC_ = consumes(inputTag); - edGetTokenAcceptedStubs_ = consumes(InputTag(label, branchAcceptedStubs)); - edGetTokenAcceptedTracks_ = consumes(InputTag(label, branchAcceptedTracks)); - edGetTokenLostStubs_ = consumes(InputTag(label, branchLostStubs)); - edGetTokenLostTracks_ = consumes(InputTag(label, branchLostTracks)); - if (useMCTruth_) { - const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); - const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); - edGetTokenSelection_ = consumes(inputTagSelecttion); - edGetTokenReconstructable_ = consumes(inputTagReconstructable); - } - // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); - esGetTokenChannelAssignment_ = esConsumes(); - // log config - log_.setf(ios::fixed, ios::floatfield); - log_.precision(4); - } - - void AnalyzerTBout::beginRun(const Run& iEvent, const EventSetup& iSetup) { - // helper class to store configurations - setup_ = &iSetup.getData(esGetTokenSetup_); - // helper class to extract structured data from tt::Frames - dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); - // helper class to assign tracklet track to channel - channelAssignment_ = &iSetup.getData(esGetTokenChannelAssignment_); - // book histograms - Service fs; - TFileDirectory dir; - dir = fs->mkdir("TBout"); - prof_ = dir.make("Counts", ";", 9, 0.5, 9.5); - prof_->GetXaxis()->SetBinLabel(1, "Stubs"); - prof_->GetXaxis()->SetBinLabel(2, "Tracks"); - prof_->GetXaxis()->SetBinLabel(3, "Lost Tracks"); - prof_->GetXaxis()->SetBinLabel(4, "Matched Tracks"); - prof_->GetXaxis()->SetBinLabel(5, "All Tracks"); - prof_->GetXaxis()->SetBinLabel(6, "Found TPs"); - prof_->GetXaxis()->SetBinLabel(7, "Found selected TPs"); - prof_->GetXaxis()->SetBinLabel(8, "Lost TPs"); - prof_->GetXaxis()->SetBinLabel(9, "All TPs"); - // channel occupancy - constexpr int maxOcc = 180; - const int numChannels = channelAssignment_->numChannelsStub() * setup_->numRegions(); - hisChannel_ = dir.make("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5); - profChannel_ = dir.make("Prof Channel Occupancy", ";", numChannels, -.5, numChannels - .5); - // stub parameter resolutions - constexpr int bins = 400; - constexpr int binsHis = 100; - constexpr double maxZ = 300.; - constexpr double maxR = 120.; - constexpr array ranges{{.01, 5.}}; - hisResolution_.reserve(NumResolution); - profResolution_.reserve(NumResolution); - for (Resolution r : AllResolution) { - hisResolution_.emplace_back(dir.make(("HisRes" + name(r)).c_str(), ";", binsHis, -ranges[r], ranges[r])); - profResolution_.emplace_back( - dir.make(("ProfRes" + name(r)).c_str(), ";;", bins, -maxZ, maxZ, bins, 0., maxR)); - hisResolutionMe_.emplace_back( - dir.make(("HisResMe" + name(r)).c_str(), ";", binsHis, -ranges[r], ranges[r])); - hisResolutionThey_.emplace_back( - dir.make(("HisResThey" + name(r)).c_str(), ";", binsHis, -ranges[r], ranges[r])); - his2Resolution_.emplace_back( - dir.make(("His2" + name(r)).c_str(), ";;", bins, -ranges[r], ranges[r], bins, -ranges[r], ranges[r])); - } - regionStubs_ = vector>(setup_->numRegions()); - } - - void AnalyzerTBout::analyze(const Event& iEvent, const EventSetup& iSetup) { - // read in TTDTC - Handle handleTTDTC; - iEvent.getByToken(edGetTokenTTDTC_, handleTTDTC); - const TTDTC& ttDTC = *handleTTDTC; - for (deque& region : regionStubs_) - region.clear(); - for (int r : ttDTC.tfpRegions()) { - for (int c : ttDTC.tfpChannels()) { - const StreamStub& s = ttDTC.stream(r, c); - copy_if( - s.begin(), s.end(), back_inserter(regionStubs_[r]), [](const FrameStub& f) { return f.first.isNonnull(); }); - } - } - // read in TBout products - Handle handleAcceptedStubs; - iEvent.getByToken(edGetTokenAcceptedStubs_, handleAcceptedStubs); - const StreamsStub& acceptedStubs = *handleAcceptedStubs; - Handle handleAcceptedTracks; - iEvent.getByToken(edGetTokenAcceptedTracks_, handleAcceptedTracks); - const StreamsTrack& acceptedTracks = *handleAcceptedTracks; - Handle handleLostStubs; - iEvent.getByToken(edGetTokenLostStubs_, handleLostStubs); - const StreamsStub& lostStubs = *handleLostStubs; - Handle handleLostTracks; - iEvent.getByToken(edGetTokenLostTracks_, handleLostTracks); - const StreamsTrack& lostTracks = *handleLostTracks; - // read in MCTruth - const StubAssociation* selection = nullptr; - const StubAssociation* reconstructable = nullptr; - if (useMCTruth_) { - Handle handleSelection; - iEvent.getByToken(edGetTokenSelection_, handleSelection); - selection = handleSelection.product(); - prof_->Fill(9, selection->numTPs()); - Handle handleReconstructable; - iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); - reconstructable = handleReconstructable.product(); - } - // analyze ht products and associate found tracks with reconstrucable TrackingParticles - set tpPtrs; - set tpPtrsSelection; - set tpPtrsLost; - int allMatched(0); - int allTracks(0); - for (region_ = 0; region_ < setup_->numRegions(); region_++) { - const int offset = region_ * channelAssignment_->numChannelsTrack(); - int nStubs(0); - int nTracks(0); - int nLost(0); - for (int channel = 0; channel < channelAssignment_->numChannelsTrack(); channel++) { - vector> tracks; - formTracks(acceptedTracks, acceptedStubs, tracks, offset + channel); - vector> lost; - formTracks(lostTracks, lostStubs, lost, offset + channel); - nTracks += tracks.size(); - nStubs += - accumulate(tracks.begin(), tracks.end(), 0, [](int sum, const auto& v) { return sum + (int)v.size(); }); - nLost += lost.size(); - allTracks += tracks.size(); - if (!useMCTruth_) - continue; - int tmp(0); - associate(tracks, selection, tpPtrsSelection, tmp); - associate(lost, selection, tpPtrsLost, tmp); - associate(tracks, reconstructable, tpPtrs, allMatched); - } - prof_->Fill(1, nStubs); - prof_->Fill(2, nTracks); - prof_->Fill(3, nLost); - } - vector recovered; - recovered.reserve(tpPtrsLost.size()); - set_intersection(tpPtrsLost.begin(), tpPtrsLost.end(), tpPtrs.begin(), tpPtrs.end(), back_inserter(recovered)); - for (const TPPtr& tpPtr : recovered) - tpPtrsLost.erase(tpPtr); - prof_->Fill(4, allMatched); - prof_->Fill(5, allTracks); - prof_->Fill(6, tpPtrs.size()); - prof_->Fill(7, tpPtrsSelection.size()); - prof_->Fill(8, tpPtrsLost.size()); - nEvents_++; - } - - void AnalyzerTBout::endJob() { - if (nEvents_ == 0) - return; - // printout TBout summary - const double totalTPs = prof_->GetBinContent(9); - const double numStubs = prof_->GetBinContent(1); - const double numTracks = prof_->GetBinContent(2); - const double numTracksLost = prof_->GetBinContent(3); - const double totalTracks = prof_->GetBinContent(5); - const double numTracksMatched = prof_->GetBinContent(4); - const double numTPsAll = prof_->GetBinContent(6); - const double numTPsEff = prof_->GetBinContent(7); - const double numTPsLost = prof_->GetBinContent(8); - const double errStubs = prof_->GetBinError(1); - const double errTracks = prof_->GetBinError(2); - const double errTracksLost = prof_->GetBinError(3); - const double fracFake = (totalTracks - numTracksMatched) / totalTracks; - const double fracDup = (numTracksMatched - numTPsAll) / totalTracks; - const double eff = numTPsEff / totalTPs; - const double errEff = sqrt(eff * (1. - eff) / totalTPs / nEvents_); - const double effLoss = numTPsLost / totalTPs; - const double errEffLoss = sqrt(effLoss * (1. - effLoss) / totalTPs / nEvents_); - const vector nums = {numStubs, numTracks, numTracksLost}; - const vector errs = {errStubs, errTracks, errTracksLost}; - const int wNums = ceil(log10(*max_element(nums.begin(), nums.end()))) + 5; - const int wErrs = ceil(log10(*max_element(errs.begin(), errs.end()))) + 5; - log_ << " TBout SUMMARY " << endl; - log_ << "number of stubs per TFP = " << setw(wNums) << numStubs << " +- " << setw(wErrs) << errStubs << endl; - log_ << "number of tracks per TFP = " << setw(wNums) << numTracks << " +- " << setw(wErrs) << errTracks - << endl; - log_ << "number of lost tracks per TFP = " << setw(wNums) << numTracksLost << " +- " << setw(wErrs) << errTracksLost - << endl; - log_ << " max tracking efficiency = " << setw(wNums) << eff << " +- " << setw(wErrs) << errEff << endl; - log_ << " lost tracking efficiency = " << setw(wNums) << effLoss << " +- " << setw(wErrs) << errEffLoss << endl; - log_ << " fake rate = " << setw(wNums) << fracFake << endl; - log_ << " duplicate rate = " << setw(wNums) << fracDup << endl; - log_ << "============================================================="; - LogPrint("L1Trigger/TrackerTFP") << log_.str(); - } - - // - void AnalyzerTBout::formTracks(const StreamsTrack& streamsTrack, - const StreamsStub& streamsStubs, - vector>& tracks, - int channel) { - const int seedType = channel % channelAssignment_->numChannelsTrack(); - const int offset = channelAssignment_->offsetStub(channel); - const StreamTrack& streamTrack = streamsTrack[channel]; - const int numTracks = accumulate(streamTrack.begin(), streamTrack.end(), 0, [](int sum, const FrameTrack& frame) { - return sum + (frame.first.isNonnull() ? 1 : 0); - }); - tracks.reserve(numTracks); - for (int frame = 0; frame < (int)streamTrack.size(); frame++) { - const FrameTrack& frameTrack = streamTrack[frame]; - if (frameTrack.first.isNull()) - continue; - vector ttStubRefs; - const int numProjectionLayers = channelAssignment_->numProjectionLayers(seedType); - const int numSeedingLayers = channelAssignment_->seedingLayers(seedType).size(); - ttStubRefs.reserve(numProjectionLayers + numSeedingLayers); - for (int channel = 0; channel < numProjectionLayers + numSeedingLayers; channel++) { - const FrameStub& stub = streamsStubs[offset + channel][frame]; - if (stub.first.isNull()) - continue; - if (channel < numProjectionLayers) - this->fill(frameTrack, stub); - ttStubRefs.push_back(stub.first); - } - tracks.push_back(ttStubRefs); - } - } - - // - void AnalyzerTBout::associate(const vector>& tracks, - const StubAssociation* ass, - set& tps, - int& sum) const { - for (const vector& ttStubRefs : tracks) { - const vector& tpPtrs = ass->associate(ttStubRefs); - if (tpPtrs.empty()) - continue; - sum++; - copy(tpPtrs.begin(), tpPtrs.end(), inserter(tps, tps.begin())); - } - } - - // - void AnalyzerTBout::fill(const FrameTrack& frameTrack, const FrameStub& frameStub) { - // get dtc stub frame - const deque& region = regionStubs_[region_]; - const auto it = - find_if(region.begin(), region.end(), [&frameStub](const FrameStub& f) { return f.first == frameStub.first; }); - if (it == region.end()) - throw cms::Exception("LgociError.") << "Stub on track was not in DTC collection."; - const GlobalPoint ttPos = setup_->stubPos(frameStub.first); - const GlobalPoint pos = setup_->stubPos(true, *it, region_); - static constexpr int widthPhi = 12; - static constexpr int widthZ = 9; - static constexpr int widthR = 7; - const bool barrel = setup_->barrel(frameStub.first); - const int layerIdTracklet = setup_->trackletLayerId(frameStub.first); - static const double baseR = settings_.kz(); - const double basePhi = barrel ? settings_.kphi1() : settings_.kphi(layerIdTracklet); - const double baseZ = settings_.kz(layerIdTracklet); - static const double baseInvR = settings_.kphi1() / settings_.kr() * pow(2, settings_.rinv_shift()); - static const double basePhi0 = settings_.kphi1() * pow(2, settings_.phi0_shift()); - static const double baseZ0 = settings_.kz() * pow(2, settings_.z0_shift()); - static const double baseTanL = settings_.kz() / settings_.kr() * pow(2, settings_.t_shift()); - const int widthRZ = barrel ? widthZ : widthR; - const double baseRZ = barrel ? baseZ : baseR; - // calc residuals - const double rInv = (frameTrack.first->rInv() / baseInvR + .5) * baseInvR; - const double phi0 = (frameTrack.first->phi() / basePhi0 + .5) * basePhi0; - const double z0 = (frameTrack.first->z0() / baseZ0 + .5) * baseZ0; - const double tanL = (frameTrack.first->tanL() / baseTanL + .5) * baseTanL; - const double phi = deltaPhi(pos.phi() - (phi0 - rInv * pos.perp() / 2.)); - const double r = pos.perp() - (pos.z() - z0) / tanL; - const double z = pos.z() - (z0 + tanL * pos.perp()); - const double rz = barrel ? z : r; - const int phii = floor(phi / basePhi); - const int rzi = floor(rz / baseRZ); - const double phid = (phii + .5) * basePhi; - const double rzd = (rzi + .5) * baseRZ; - // parse residuals - TTBV hw(frameStub.second); - const TTBV hwRZ(hw, widthRZ, 0, true); - hw >>= widthRZ; - const TTBV hwPhi(hw, widthPhi, 0, true); - const double hwPhid = hwPhi.val(basePhi); - const double hwRZd = hwRZ.val(baseRZ); - const vector resolutions = {phid - hwPhid, rzd - hwRZd}; - for (Resolution r : AllResolution) { - hisResolution_[r]->Fill(resolutions[r]); - profResolution_[r]->Fill(ttPos.z(), ttPos.perp(), abs(resolutions[r])); - } - hisResolutionMe_[0]->Fill(phid); - hisResolutionMe_[1]->Fill(rzd); - hisResolutionThey_[0]->Fill(hwPhid); - hisResolutionThey_[1]->Fill(hwRZd); - his2Resolution_[0]->Fill(phid, hwPhid); - his2Resolution_[1]->Fill(rzd, hwRZd); - } - -} // namespace trklet - -DEFINE_FWK_MODULE(trklet::AnalyzerTBout); diff --git a/L1Trigger/TrackFindingTracklet/test/AnalyzerTM.cc b/L1Trigger/TrackFindingTracklet/test/AnalyzerTM.cc new file mode 100644 index 0000000000000..842ec6c8b08c9 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/test/AnalyzerTM.cc @@ -0,0 +1,288 @@ +#include "FWCore/Framework/interface/one/EDAnalyzer.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "CommonTools/UtilAlgos/interface/TFileService.h" +#include "DataFormats/Common/interface/Handle.h" + +#include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" +#include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackFindingTracklet/interface/DataFormats.h" +#include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace trklet { + + /*! \class trklet::AnalyzerTM + * \brief Class to analyze hardware like structured TTStub Collection generated by TM module + * \author Thomas Schuh + * \date 2023, Jan + */ + class AnalyzerTM : public edm::one::EDAnalyzer { + public: + AnalyzerTM(const edm::ParameterSet& iConfig); + void beginJob() override {} + void beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override; + void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override; + void endRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override {} + void endJob() override; + + private: + // + void formTracks(const tt::StreamsTrack& streamsTrack, + const tt::StreamsStub& streamsStubs, + std::vector>& tracks, + int channel) const; + // + void associate(const std::vector>& tracks, + const tt::StubAssociation* ass, + std::set& tps, + int& sum, + bool perfect = false) const; + + // ED input token of stubs + edm::EDGetTokenT edGetTokenStubs_; + // ED input token of tracks + edm::EDGetTokenT edGetTokenTracks_; + // ED input token of TTStubRef to TPPtr association for tracking efficiency + edm::EDGetTokenT edGetTokenSelection_; + // ED input token of TTStubRef to recontructable TPPtr association + edm::EDGetTokenT edGetTokenReconstructable_; + // Setup token + edm::ESGetToken esGetTokenSetup_; + // DataFormats token + edm::ESGetToken esGetTokenDataFormats_; + // ChannelAssignment token + edm::ESGetToken esGetTokenChannelAssignment_; + // stores, calculates and provides run-time constants + const tt::Setup* setup_ = nullptr; + // helper class to extract structured data from tt::Frames + const DataFormats* dataFormats_ = nullptr; + // helper class to assign tracklet track to channel + const ChannelAssignment* channelAssignment_ = nullptr; + // enables analyze of TPs + bool useMCTruth_; + // + int nEvents_ = 0; + + // Histograms + + TProfile* prof_; + TProfile* profChannel_; + TH1F* hisChannel_; + + // printout + std::stringstream log_; + }; + + AnalyzerTM::AnalyzerTM(const edm::ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { + usesResource("TFileService"); + // book in- and output ED products + const std::string& label = iConfig.getParameter("OutputLabelTM"); + const std::string& branchStubs = iConfig.getParameter("BranchStubs"); + const std::string& branchTracks = iConfig.getParameter("BranchTracks"); + edGetTokenStubs_ = consumes(edm::InputTag(label, branchStubs)); + edGetTokenTracks_ = consumes(edm::InputTag(label, branchTracks)); + if (useMCTruth_) { + const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); + const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); + edGetTokenSelection_ = consumes(inputTagSelecttion); + edGetTokenReconstructable_ = consumes(inputTagReconstructable); + } + // book ES products + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + esGetTokenChannelAssignment_ = esConsumes(); + // log config + log_.setf(std::ios::fixed, std::ios::floatfield); + log_.precision(4); + } + + void AnalyzerTM::beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) { + // helper class to store configurations + setup_ = &iSetup.getData(esGetTokenSetup_); + // helper class to extract structured data from tt::Frames + dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); + // helper class to assign tracklet track to channel + channelAssignment_ = &iSetup.getData(esGetTokenChannelAssignment_); + // book histograms + edm::Service fs; + TFileDirectory dir; + dir = fs->mkdir("TM"); + prof_ = dir.make("Counts", ";", 10, 0.5, 10.5); + prof_->GetXaxis()->SetBinLabel(1, "Stubs"); + prof_->GetXaxis()->SetBinLabel(2, "Tracks"); + prof_->GetXaxis()->SetBinLabel(4, "Matched Tracks"); + prof_->GetXaxis()->SetBinLabel(5, "All Tracks"); + prof_->GetXaxis()->SetBinLabel(6, "Found TPs"); + prof_->GetXaxis()->SetBinLabel(7, "Found selected TPs"); + prof_->GetXaxis()->SetBinLabel(9, "All TPs"); + prof_->GetXaxis()->SetBinLabel(10, "Perfect TPs"); + // channel occupancy + constexpr int maxOcc = 180; + const int numChannels = 1; + hisChannel_ = dir.make("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5); + profChannel_ = dir.make("Prof Channel Occupancy", ";", numChannels, -.5, numChannels - .5); + } + + void AnalyzerTM::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + // read in ht products + edm::Handle handleStubs; + iEvent.getByToken(edGetTokenStubs_, handleStubs); + const tt::StreamsStub& streamsStub = *handleStubs; + edm::Handle handleTracks; + iEvent.getByToken(edGetTokenTracks_, handleTracks); + const tt::StreamsTrack& streamsTrack = *handleTracks; + // read in MCTruth + const tt::StubAssociation* selection = nullptr; + const tt::StubAssociation* reconstructable = nullptr; + if (useMCTruth_) { + edm::Handle handleSelection; + iEvent.getByToken(edGetTokenSelection_, handleSelection); + selection = handleSelection.product(); + prof_->Fill(9, selection->numTPs()); + edm::Handle handleReconstructable; + iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); + reconstructable = handleReconstructable.product(); + } + // analyze ht products and associate found tracks with reconstrucable TrackingParticles + std::set tpPtrs; + std::set tpPtrsSelection; + std::set tpPtrsPerfect; + int allMatched(0); + int allTracks(0); + for (int region = 0; region < setup_->numRegions(); region++) { + int nStubs(0); + int nTracks(0); + std::vector> tracks; + formTracks(streamsTrack, streamsStub, tracks, region); + nTracks += tracks.size(); + nStubs += std::accumulate(tracks.begin(), tracks.end(), 0, [](int sum, const std::vector& track) { + return sum + track.size(); + }); + allTracks += tracks.size(); + if (!useMCTruth_) + continue; + int tmp(0); + associate(tracks, selection, tpPtrsSelection, tmp); + associate(tracks, selection, tpPtrsPerfect, tmp, true); + associate(tracks, reconstructable, tpPtrs, allMatched); + const tt::StreamTrack& stream = streamsTrack[region]; + const auto end = std::find_if( + stream.rbegin(), stream.rend(), [](const tt::FrameTrack& frame) { return frame.first.isNonnull(); }); + const int size = std::distance(stream.begin(), end.base()) - 1; + hisChannel_->Fill(size); + profChannel_->Fill(1, size); + prof_->Fill(1, nStubs); + prof_->Fill(2, nTracks); + } + prof_->Fill(4, allMatched); + prof_->Fill(5, allTracks); + prof_->Fill(6, tpPtrs.size()); + prof_->Fill(7, tpPtrsSelection.size()); + prof_->Fill(10, tpPtrsPerfect.size()); + nEvents_++; + } + + void AnalyzerTM::endJob() { + if (nEvents_ == 0) + return; + // printout summary + const double totalTPs = prof_->GetBinContent(9); + const double numStubs = prof_->GetBinContent(1); + const double numTracks = prof_->GetBinContent(2); + const double totalTracks = prof_->GetBinContent(5); + const double numTracksMatched = prof_->GetBinContent(4); + const double numTPsAll = prof_->GetBinContent(6); + const double numTPsEff = prof_->GetBinContent(7); + const double numTPsEffPerfect = prof_->GetBinContent(10); + const double errStubs = prof_->GetBinError(1); + const double errTracks = prof_->GetBinError(2); + const double fracFake = (totalTracks - numTracksMatched) / totalTracks; + const double fracDup = (numTracksMatched - numTPsAll) / totalTracks; + const double eff = numTPsEff / totalTPs; + const double errEff = std::sqrt(eff * (1. - eff) / totalTPs / nEvents_); + const double effPerfect = numTPsEffPerfect / totalTPs; + const double errEffPerfect = std::sqrt(effPerfect * (1. - effPerfect) / totalTPs / nEvents_); + const std::vector nums = {numStubs, numTracks}; + const std::vector errs = {errStubs, errTracks}; + const int wNums = std::ceil(std::log10(*std::max_element(nums.begin(), nums.end()))) + 5; + const int wErrs = std::ceil(std::log10(*std::max_element(errs.begin(), errs.end()))) + 5; + log_ << " TM SUMMARY " << std::endl; + log_ << "number of stubs per TFP = " << std::setw(wNums) << numStubs << " +- " << std::setw(wErrs) << errStubs + << std::endl; + log_ << "number of tracks per TFP = " << std::setw(wNums) << numTracks << " +- " << std::setw(wErrs) + << errTracks << std::endl; + log_ << " current tracking efficiency = " << std::setw(wNums) << effPerfect << " +- " << std::setw(wErrs) + << errEffPerfect << std::endl; + log_ << " max tracking efficiency = " << std::setw(wNums) << eff << " +- " << std::setw(wErrs) << errEff + << std::endl; + log_ << " fake rate = " << std::setw(wNums) << fracFake << std::endl; + log_ << " duplicate rate = " << std::setw(wNums) << fracDup << std::endl; + log_ << "============================================================="; + edm::LogPrint(moduleDescription().moduleName()) << log_.str(); + } + + // + void AnalyzerTM::formTracks(const tt::StreamsTrack& streamsTrack, + const tt::StreamsStub& streamsStubs, + std::vector>& tracks, + int channel) const { + static const int numLayers = channelAssignment_->tmNumLayers(); + const int offset = channel * numLayers; + const tt::StreamTrack& streamTrack = streamsTrack[channel]; + const int numTracks = + std::accumulate(streamTrack.begin(), streamTrack.end(), 0, [](int sum, const tt::FrameTrack& frame) { + return sum + (frame.first.isNonnull() ? 1 : 0); + }); + tracks.reserve(numTracks); + for (int frame = 0; frame < static_cast(streamTrack.size()); frame++) { + const tt::FrameTrack& frameTrack = streamTrack[frame]; + if (frameTrack.first.isNull()) + continue; + std::vector ttStubRefs; + ttStubRefs.reserve(numLayers); + for (int layer = 0; layer < numLayers; layer++) { + const tt::FrameStub& stub = streamsStubs[offset + layer][frame]; + if (stub.first.isNonnull()) + ttStubRefs.push_back(stub.first); + } + tracks.push_back(ttStubRefs); + } + } + + // + void AnalyzerTM::associate(const std::vector>& tracks, + const tt::StubAssociation* ass, + std::set& tps, + int& sum, + bool perfect) const { + for (const std::vector& ttStubRefs : tracks) { + const std::vector& tpPtrs = perfect ? ass->associateFinal(ttStubRefs) : ass->associate(ttStubRefs); + if (tpPtrs.empty()) + continue; + sum++; + std::copy(tpPtrs.begin(), tpPtrs.end(), std::inserter(tps, tps.begin())); + } + } + +} // namespace trklet + +DEFINE_FWK_MODULE(trklet::AnalyzerTM); diff --git a/L1Trigger/TrackFindingTracklet/test/AnalyzerTracklet.cc b/L1Trigger/TrackFindingTracklet/test/AnalyzerTracklet.cc index 0306313194801..158ef24074af8 100644 --- a/L1Trigger/TrackFindingTracklet/test/AnalyzerTracklet.cc +++ b/L1Trigger/TrackFindingTracklet/test/AnalyzerTracklet.cc @@ -14,7 +14,8 @@ #include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" #include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" +#include "L1Trigger/TrackFindingTracklet/interface/DataFormats.h" +#include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h" #include #include @@ -27,11 +28,6 @@ #include #include -using namespace std; -using namespace edm; -using namespace trackerTFP; -using namespace tt; - namespace trklet { /*! \class trklet::AnalyzerTracklet @@ -39,37 +35,41 @@ namespace trklet { * \author Thomas Schuh * \date 2020, Oct */ - class AnalyzerTracklet : public one::EDAnalyzer { + class AnalyzerTracklet : public edm::one::EDAnalyzer { public: - AnalyzerTracklet(const ParameterSet& iConfig); + AnalyzerTracklet(const edm::ParameterSet& iConfig); void beginJob() override {} - void beginRun(const Run& iEvent, const EventSetup& iSetup) override; - void analyze(const Event& iEvent, const EventSetup& iSetup) override; - void endRun(const Run& iEvent, const EventSetup& iSetup) override {} + void beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override; + void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override; + void endRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override {} void endJob() override; private: // gets all TPs associated too any of the tracks & number of tracks matching at least one TP - void associate(const vector>& tracks, - const StubAssociation* ass, - set& tps, + void associate(const std::vector>& tracks, + const tt::StubAssociation* ass, + std::set& tps, int& nMatchTrk, bool perfect = false) const; // ED input token of tracks - EDGetTokenT edGetToken_; + edm::EDGetTokenT edGetToken_; // ED input token of TTStubRef to TPPtr association for tracking efficiency - EDGetTokenT edGetTokenSelection_; + edm::EDGetTokenT edGetTokenSelection_; // ED input token of TTStubRef to recontructable TPPtr association - EDGetTokenT edGetTokenReconstructable_; + edm::EDGetTokenT edGetTokenReconstructable_; // Setup token - ESGetToken esGetTokenSetup_; + edm::ESGetToken esGetTokenSetup_; // DataFormats token - ESGetToken esGetTokenDataFormats_; + edm::ESGetToken esGetTokenDataFormats_; + // ChannelAssignment token + edm::ESGetToken esGetTokenChannelAssignment_; // stores, calculates and provides run-time constants - const Setup* setup_ = nullptr; + const tt::Setup* setup_ = nullptr; // helper class to extract structured data from tt::Frames const DataFormats* dataFormats_ = nullptr; + // helper class to assign tracks to channel + const ChannelAssignment* channelAssignment_ = nullptr; // enables analyze of TPs bool useMCTruth_; // @@ -87,36 +87,39 @@ namespace trklet { TEfficiency* eff_; // printout - stringstream log_; + std::stringstream log_; }; - AnalyzerTracklet::AnalyzerTracklet(const ParameterSet& iConfig) + AnalyzerTracklet::AnalyzerTracklet(const edm::ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { usesResource("TFileService"); // book in- and output ED products - const InputTag& inputTag = iConfig.getParameter("InputTag"); - edGetToken_ = consumes(inputTag); + const edm::InputTag& inputTag = iConfig.getParameter("InputTag"); + edGetToken_ = consumes(inputTag); if (useMCTruth_) { - const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); - const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); - edGetTokenSelection_ = consumes(inputTagSelecttion); - edGetTokenReconstructable_ = consumes(inputTagReconstructable); + const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); + const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); + edGetTokenSelection_ = consumes(inputTagSelecttion); + edGetTokenReconstructable_ = consumes(inputTagReconstructable); } // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + esGetTokenChannelAssignment_ = esConsumes(); // log config - log_.setf(ios::fixed, ios::floatfield); + log_.setf(std::ios::fixed, std::ios::floatfield); log_.precision(4); } - void AnalyzerTracklet::beginRun(const Run& iEvent, const EventSetup& iSetup) { + void AnalyzerTracklet::beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) { // helper class to store configurations setup_ = &iSetup.getData(esGetTokenSetup_); // helper class to extract structured data from tt::Frames dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); + // helper class to assign tracks to channel + channelAssignment_ = &iSetup.getData(esGetTokenChannelAssignment_); // book histograms - Service fs; + edm::Service fs; TFileDirectory dir; dir = fs->mkdir("Tracklet"); prof_ = dir.make("Counts", ";", 10, 0.5, 10.5); @@ -132,7 +135,7 @@ namespace trklet { prof_->GetXaxis()->SetBinLabel(10, "Perfectly Found selected TPs"); // channel occupancy constexpr int maxOcc = 180; - const int numChannels = setup_->numRegions(); + const int numChannels = channelAssignment_->numSeedTypes(); hisChannel_ = dir.make("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5); profChannel_ = dir.make("Prof Channel Occupancy", ";", numChannels, -.5, numChannels - .5); // Efficiencies @@ -141,29 +144,29 @@ namespace trklet { eff_ = dir.make("EffEta", ";", 128, -2.5, 2.5); } - void AnalyzerTracklet::analyze(const Event& iEvent, const EventSetup& iSetup) { + void AnalyzerTracklet::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { auto fill = [](const TPPtr& tpPtr, TH1F* his) { his->Fill(tpPtr->eta()); }; // read in tracklet products - Handle handle; - iEvent.getByToken(edGetToken_, handle); + edm::Handle handle; + iEvent.getByToken(edGetToken_, handle); // read in MCTruth - const StubAssociation* selection = nullptr; - const StubAssociation* reconstructable = nullptr; + const tt::StubAssociation* selection = nullptr; + const tt::StubAssociation* reconstructable = nullptr; if (useMCTruth_) { - Handle handleSelection; - iEvent.getByToken(edGetTokenSelection_, handleSelection); + edm::Handle handleSelection; + iEvent.getByToken(edGetTokenSelection_, handleSelection); selection = handleSelection.product(); prof_->Fill(9, selection->numTPs()); - Handle handleReconstructable; - iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); + edm::Handle handleReconstructable; + iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); reconstructable = handleReconstructable.product(); for (const auto& p : selection->getTrackingParticleToTTStubsMap()) fill(p.first, hisEffTotal_); } // - const TTTracks& ttTracks = *handle.product(); - vector> ttTrackRefsRegions(setup_->numRegions()); - vector nTTTracksRegions(setup_->numRegions(), 0); + const tt::TTTracks& ttTracks = *handle.product(); + std::vector> ttTrackRefsRegions(setup_->numRegions()); + std::vector nTTTracksRegions(setup_->numRegions(), 0); for (const TTTrack& ttTrack : ttTracks) nTTTracksRegions[ttTrack.phiSector()]++; for (int region = 0; region < setup_->numRegions(); region++) @@ -172,31 +175,37 @@ namespace trklet { for (const TTTrack& ttTrack : ttTracks) ttTrackRefsRegions[ttTrack.phiSector()].emplace_back(TTTrackRef(handle, i++)); for (int region = 0; region < setup_->numRegions(); region++) { - const vector& ttTrackRefs = ttTrackRefsRegions[region]; + const std::vector& ttTrackRefs = ttTrackRefsRegions[region]; const int nStubs = - accumulate(ttTrackRefs.begin(), ttTrackRefs.end(), 0, [](int sum, const TTTrackRef& ttTrackRef) { + std::accumulate(ttTrackRefs.begin(), ttTrackRefs.end(), 0, [](int sum, const TTTrackRef& ttTrackRef) { return sum + ttTrackRef->getStubRefs().size(); }); const int nTracks = ttTrackRefs.size(); - hisChannel_->Fill(nTracks); - profChannel_->Fill(region, nTracks); prof_->Fill(1, nStubs); prof_->Fill(2, nTracks); // no access to lost tracks prof_->Fill(3, 0); + for (int seedType = 0; seedType < channelAssignment_->numSeedTypes(); seedType++) { + const int nTracks = std::accumulate( + ttTrackRefs.begin(), ttTrackRefs.end(), 0, [seedType](int sum, const TTTrackRef& ttTrackRef) { + return sum + (static_cast(ttTrackRef->trackSeedType()) == seedType ? 1 : 0); + }); + hisChannel_->Fill(nTracks); + profChannel_->Fill(seedType, nTracks); + } } // analyze tracklet products and associate found tracks with reconstrucable TrackingParticles - set tpPtrs; - set tpPtrsSelection; - set tpPtrsPerfect; + std::set tpPtrs; + std::set tpPtrsSelection; + std::set tpPtrsPerfect; int nAllMatched(0); // convert vector of tracks to vector of vector of associated stubs - vector> tracks; + std::vector> tracks; tracks.reserve(ttTracks.size()); - transform( - ttTracks.begin(), ttTracks.end(), back_inserter(tracks), [](const TTTrack& ttTrack) { - return ttTrack.getStubRefs(); - }); + std::transform(ttTracks.begin(), + ttTracks.end(), + std::back_inserter(tracks), + [](const TTTrack& ttTrack) { return ttTrack.getStubRefs(); }); if (useMCTruth_) { int tmp(0); associate(tracks, selection, tpPtrsSelection, tmp); @@ -235,37 +244,40 @@ namespace trklet { const double fracFake = (totalTracks - numTracksMatched) / totalTracks; const double fracDup = (numTracksMatched - numTPsAll) / totalTracks; const double eff = numTPsEff / totalTPs; - const double errEff = sqrt(eff * (1. - eff) / totalTPs / nEvents_); + const double errEff = std::sqrt(eff * (1. - eff) / totalTPs / nEvents_); const double effPerfect = numTPsEffPerfect / totalTPs; - const double errEffPerfect = sqrt(effPerfect * (1. - effPerfect) / totalTPs / nEvents_); - const vector nums = {numStubs, numTracks}; - const vector errs = {errStubs, errTracks}; - const int wNums = ceil(log10(*max_element(nums.begin(), nums.end()))) + 5; - const int wErrs = ceil(log10(*max_element(errs.begin(), errs.end()))) + 5; - log_ << " Tracklet SUMMARY " << endl; - log_ << "number of stubs per TFP = " << setw(wNums) << numStubs << " +- " << setw(wErrs) << errStubs << endl; - log_ << "number of tracks per TFP = " << setw(wNums) << numTracks << " +- " << setw(wErrs) << errTracks << endl; - log_ << "current tracking efficiency = " << setw(wNums) << effPerfect << " +- " << setw(wErrs) << errEffPerfect - << endl; - log_ << "max tracking efficiency = " << setw(wNums) << eff << " +- " << setw(wErrs) << errEff << endl; - log_ << " fake rate = " << setw(wNums) << fracFake << endl; - log_ << " duplicate rate = " << setw(wNums) << fracDup << endl; + const double errEffPerfect = std::sqrt(effPerfect * (1. - effPerfect) / totalTPs / nEvents_); + const std::vector nums = {numStubs, numTracks}; + const std::vector errs = {errStubs, errTracks}; + const int wNums = std::ceil(std::log10(*std::max_element(nums.begin(), nums.end()))) + 5; + const int wErrs = std::ceil(std::log10(*std::max_element(errs.begin(), errs.end()))) + 5; + log_ << " Tracklet SUMMARY " << std::endl; + log_ << "number of stubs per TFP = " << std::setw(wNums) << numStubs << " +- " << std::setw(wErrs) << errStubs + << std::endl; + log_ << "number of tracks per TFP = " << std::setw(wNums) << numTracks << " +- " << std::setw(wErrs) << errTracks + << std::endl; + log_ << "current tracking efficiency = " << std::setw(wNums) << effPerfect << " +- " << std::setw(wErrs) + << errEffPerfect << std::endl; + log_ << "max tracking efficiency = " << std::setw(wNums) << eff << " +- " << std::setw(wErrs) << errEff + << std::endl; + log_ << " fake rate = " << std::setw(wNums) << fracFake << std::endl; + log_ << " duplicate rate = " << std::setw(wNums) << fracDup << std::endl; log_ << "============================================================="; - LogPrint("L1Trigger/TrackFindingTracklet") << log_.str(); + edm::LogPrint(moduleDescription().moduleName()) << log_.str(); } // gets all TPs associated too any of the tracks & number of tracks matching at least one TP - void AnalyzerTracklet::associate(const vector>& tracks, - const StubAssociation* ass, - set& tps, + void AnalyzerTracklet::associate(const std::vector>& tracks, + const tt::StubAssociation* ass, + std::set& tps, int& nMatchTrk, bool perfect) const { - for (const vector& ttStubRefs : tracks) { - const vector& tpPtrs = perfect ? ass->associateFinal(ttStubRefs) : ass->associate(ttStubRefs); + for (const std::vector& ttStubRefs : tracks) { + const std::vector& tpPtrs = perfect ? ass->associateFinal(ttStubRefs) : ass->associate(ttStubRefs); if (tpPtrs.empty()) continue; nMatchTrk++; - copy(tpPtrs.begin(), tpPtrs.end(), inserter(tps, tps.begin())); + std::copy(tpPtrs.begin(), tpPtrs.end(), std::inserter(tps, tps.begin())); } } diff --git a/L1Trigger/TrackFindingTracklet/test/HybridTracksNewKF_cfg.py b/L1Trigger/TrackFindingTracklet/test/HybridTracksNewKF_cfg.py index b9e05c5a39e41..80796c9611458 100644 --- a/L1Trigger/TrackFindingTracklet/test/HybridTracksNewKF_cfg.py +++ b/L1Trigger/TrackFindingTracklet/test/HybridTracksNewKF_cfg.py @@ -12,48 +12,42 @@ process = cms.Process( "Demo" ) process.load( 'FWCore.MessageService.MessageLogger_cfi' ) process.load( 'Configuration.EventContent.EventContent_cff' ) -process.load( 'Configuration.Geometry.GeometryExtendedRun4D88Reco_cff' ) -process.load( 'Configuration.Geometry.GeometryExtendedRun4D88_cff' ) +process.load( 'Configuration.Geometry.GeometryExtendedRun4D98Reco_cff' ) +process.load( 'Configuration.Geometry.GeometryExtendedRun4D98_cff' ) process.load( 'Configuration.StandardSequences.MagneticField_cff' ) process.load( 'Configuration.StandardSequences.FrontierConditions_GlobalTag_cff' ) process.load( 'L1Trigger.TrackTrigger.TrackTrigger_cff' ) from Configuration.AlCa.GlobalTag import GlobalTag -process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic', '') +process.GlobalTag = GlobalTag(process.GlobalTag, '133X_mcRun4_realistic_v1', '') # load code that associates stubs with mctruth process.load( 'SimTracker.TrackTriggerAssociation.StubAssociator_cff' ) # load code that produces DTCStubs -process.load( 'L1Trigger.TrackerDTC.ProducerED_cff' ) +process.load( 'L1Trigger.TrackerDTC.DTC_cff' ) # load code that analyzes DTCStubs process.load( 'L1Trigger.TrackerDTC.Analyzer_cff' ) # L1 tracking => hybrid emulation process.load("L1Trigger.TrackFindingTracklet.L1HybridEmulationTracks_cff") -from L1Trigger.TrackFindingTracklet.Customize_cff import * -fwConfig( process ) #--- Load code that analyzes hybrid emulation process.load( 'L1Trigger.TrackFindingTracklet.Analyzer_cff' ) # load code that fits hybrid tracks process.load( 'L1Trigger.TrackFindingTracklet.Producer_cff' ) - -# load and configure TrackTriggerAssociation -process.load( 'SimTracker.TrackTriggerAssociation.TrackTriggerAssociator_cff' ) -process.TTTrackAssociatorFromPixelDigis.TTTracks = cms.VInputTag( cms.InputTag( - process.TrackFindingTrackletProducer_params.LabelKFout.value(), - process.TrackFindingTrackletProducer_params.BranchAcceptedTTTracks.value() -) ) +from L1Trigger.TrackFindingTracklet.Customize_cff import * +fwConfig( process ) +oldKFConfig( process ) +process.l1tTTTracksFromTrackletEmulation.readMoreMcTruth = False # build schedule -process.mc = cms.Sequence( process.StubAssociator ) -process.dtc = cms.Sequence( process.TrackerDTCProducer + process.TrackerDTCAnalyzer ) -process.tracklet = cms.Sequence( process.L1THybridTracks + process.TrackFindingTrackletAnalyzerTracklet ) -process.TBout = cms.Sequence( process.TrackFindingTrackletProducerTBout + process.TrackFindingTrackletAnalyzerTBout ) -process.drin = cms.Sequence( process.TrackFindingTrackletProducerDRin + process.TrackFindingTrackletAnalyzerDRin ) -process.dr = cms.Sequence( process.TrackFindingTrackletProducerDR + process.TrackFindingTrackletAnalyzerDR ) -process.kfin = cms.Sequence( process.TrackFindingTrackletProducerKFin + process.TrackFindingTrackletAnalyzerKFin ) -process.kf = cms.Sequence( process.TrackFindingTrackletProducerKF + process.TrackFindingTrackletAnalyzerKF ) -process.kfout = cms.Sequence( process.TrackFindingTrackletProducerKFout + process.TrackFindingTrackletAnalyzerKFout ) -process.tt = cms.Path( process.mc + process.dtc + process.tracklet + process.TBout + process.drin + process.dr + process.kfin + process.kf + process.kfout) +process.mc = cms.Sequence( process.StubAssociator ) +process.dtc = cms.Sequence( process.ProducerDTC + process.AnalyzerDTC ) +process.tracklet = cms.Sequence( process.L1THybridTracks + process.AnalyzerTracklet ) +process.tm = cms.Sequence( process.ProducerTM + process.AnalyzerTM ) +process.dr = cms.Sequence( process.ProducerDR + process.AnalyzerDR ) +process.kf = cms.Sequence( process.ProducerKF + process.AnalyzerKF ) +process.tq = cms.Sequence( process.ProducerTQ + process.AnalyzerTQ ) +process.tfp = cms.Sequence( process.ProducerTFP + process.AnalyzerTFP ) +process.tt = cms.Path( process.mc + process.dtc + process.tracklet + process.tm + process.dr + process.kf + process.tq + process.tfp ) process.schedule = cms.Schedule( process.tt ) # create options @@ -64,8 +58,10 @@ #from MCsamples.Scripts.getCMSlocaldata_cfi import * #from MCsamples.RelVal_1260_D88.PU200_TTbar_14TeV_cfi import * #inputMC = getCMSdataFromCards() -inputMC = ["/store/mc/CMSSW_12_6_0/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_125X_mcRun4_realistic_v5_2026D88PU200RV183v2-v1/30000/0959f326-3f52-48d8-9fcf-65fc41de4e27.root"] -options.register( 'inputMC', inputMC, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.string, "Files to be processed" ) +Samples = [ + '/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/0b2b0b0b-f312-48a8-9d46-ccbadc69bbfd.root' +] +options.register( 'inputMC', Samples, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.string, "Files to be processed" ) # specify number of events to process. options.register( 'Events',100,VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.int, "Number of Events to analyze" ) options.parseArguments() @@ -75,12 +71,13 @@ process.source = cms.Source( "PoolSource", fileNames = cms.untracked.vstring( options.inputMC ), - #skipEvents = cms.untracked.uint32( 250 ), + #skipEvents = cms.untracked.uint32( 3537 ), secondaryFileNames = cms.untracked.vstring(), duplicateCheckMode = cms.untracked.string( 'noDuplicateCheck' ) ) process.Timing = cms.Service( "Timing", summaryOnly = cms.untracked.bool( True ) ) process.MessageLogger.cerr.enableStatistics = False +process.MessageLogger.L1track = dict(limit = -1) process.TFileService = cms.Service( "TFileService", fileName = cms.string( "Hist.root" ) ) if ( False ): diff --git a/L1Trigger/TrackFindingTracklet/test/HybridTracks_cfg.py b/L1Trigger/TrackFindingTracklet/test/HybridTracks_cfg.py index e782d84048448..1a6726a9cd36a 100644 --- a/L1Trigger/TrackFindingTracklet/test/HybridTracks_cfg.py +++ b/L1Trigger/TrackFindingTracklet/test/HybridTracks_cfg.py @@ -15,8 +15,8 @@ process.load('Configuration.EventContent.EventContent_cff') process.load('Configuration.StandardSequences.MagneticField_cff') -process.load('Configuration.Geometry.GeometryExtendedRun4D88Reco_cff') -process.load('Configuration.Geometry.GeometryExtendedRun4D88_cff') +process.load( 'Configuration.Geometry.GeometryExtendedRun4D98Reco_cff' ) +process.load( 'Configuration.Geometry.GeometryExtendedRun4D98_cff' ) process.load('Configuration.StandardSequences.EndOfProcess_cff') process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') @@ -30,16 +30,21 @@ # input # ---------------------------------------------------------------------------------- -process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(10)) -inputMC = ["/store/mc/CMSSW_12_6_0/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_125X_mcRun4_realistic_v5_2026D88PU200RV183v2-v1/30000/0959f326-3f52-48d8-9fcf-65fc41de4e27.root"] -process.source = cms.Source("PoolSource", fileNames = cms.untracked.vstring(*inputMC)) +# create options +import FWCore.ParameterSet.VarParsing as VarParsing +options = VarParsing.VarParsing( 'analysis' ) +options.register( 'Events',100,VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.int, "Number of Events to analyze" ) +options.parseArguments() +process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(options.Events) ) +inputMC = ["/store/relval/CMSSW_14_0_0_pre2/RelValSingleMuFlatPt2To100/GEN-SIM-DIGI-RAW/133X_mcRun4_realistic_v1_STD_2026D98_noPU_RV229-v1/2580000/00b68219-8585-406f-88d0-84da05a13280.root"] +process.source = cms.Source("PoolSource", fileNames = cms.untracked.vstring(*inputMC), skipEvents = cms.untracked.uint32( 17 )) # ---------------------------------------------------------------------------------- # DTC emulation # ---------------------------------------------------------------------------------- -process.load( 'L1Trigger.TrackerDTC.ProducerED_cff' ) -process.dtc = cms.Path( process.TrackerDTCProducer ) +process.load( 'L1Trigger.TrackerDTC.DTC_cff' ) +process.dtc = cms.Path( process.ProducerDTC ) # ---------------------------------------------------------------------------------- # L1 tracking @@ -59,6 +64,8 @@ #process.TTTracksEmulation = cms.Path(process.L1TPromptExtendedHybridTracks) #process.TTTracksEmulationWithTruth = cms.Path(process.L1TPromptExtendedHybridTracksWithAssociators) +process.MessageLogger.L1track = dict(limit = -1) + # ---------------------------------------------------------------------------------- # output module # ---------------------------------------------------------------------------------- diff --git a/L1Trigger/TrackFindingTracklet/test/L1TrackNtupleMaker.cc b/L1Trigger/TrackFindingTracklet/test/L1TrackNtupleMaker.cc index 789a10020b25b..c8eed2e688c1e 100644 --- a/L1Trigger/TrackFindingTracklet/test/L1TrackNtupleMaker.cc +++ b/L1Trigger/TrackFindingTracklet/test/L1TrackNtupleMaker.cc @@ -55,6 +55,8 @@ //////////////// // PHYSICS TOOLS +#include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackerTFP/interface/LayerEncoding.h" #include "L1Trigger/TrackFindingTracklet/interface/HitPatternHelper.h" #include "CommonTools/UtilAlgos/interface/TFileService.h" #include "CLHEP/Units/PhysicalConstants.h" @@ -65,6 +67,7 @@ #include #include #include +#include #include #include #include @@ -128,23 +131,25 @@ class L1TrackNtupleMaker : public one::EDAnalyzer > > ttClusterToken_; - edm::EDGetTokenT > > ttStubToken_; - edm::EDGetTokenT > ttClusterMCTruthToken_; - edm::EDGetTokenT > ttStubMCTruthToken_; + edm::EDGetTokenT>> ttClusterToken_; + edm::EDGetTokenT>> ttStubToken_; + edm::EDGetTokenT> ttClusterMCTruthToken_; + edm::EDGetTokenT> ttStubMCTruthToken_; - edm::EDGetTokenT > > ttTrackToken_; - edm::EDGetTokenT > ttTrackMCTruthToken_; + edm::EDGetTokenT>> ttTrackToken_; + edm::EDGetTokenT> ttTrackMCTruthToken_; - edm::EDGetTokenT > TrackingParticleToken_; - edm::EDGetTokenT > TrackingVertexToken_; + edm::EDGetTokenT> TrackingParticleToken_; + edm::EDGetTokenT> TrackingVertexToken_; - edm::EDGetTokenT > GenJetToken_; + edm::EDGetTokenT> GenJetToken_; edm::ESGetToken getTokenTrackerGeom_; edm::ESGetToken getTokenTrackerTopo_; edm::ESGetToken getTokenBField_; edm::ESGetToken getTokenHPHSetup_; + edm::ESGetToken getTokenSetup_; + edm::ESGetToken getTokenLayerEncoding_; //----------------------------------------------------------------------------------------------- // tree & branches for mini-ntuple @@ -178,6 +183,7 @@ class L1TrackNtupleMaker : public one::EDAnalyzer* m_trk_nLost2Sstub_hitpattern; std::vector* m_trk_nLoststub_V1_hitpattern; // Same as the definiton of "nlaymiss_interior" in TrackQuality.cc std::vector* m_trk_nLoststub_V2_hitpattern; // A tighter version of "nlaymiss_interior" + std::vector* m_trk_charge; std::vector* m_trk_phiSector; std::vector* m_trk_etaSector; std::vector* m_trk_genuine; @@ -191,17 +197,18 @@ class L1TrackNtupleMaker : public one::EDAnalyzer* m_trk_matchtp_eta; std::vector* m_trk_matchtp_phi; std::vector* m_trk_matchtp_z0; - std::vector* m_trk_matchtp_dxy; + std::vector* m_trk_matchtp_lxy; std::vector* m_trk_matchtp_d0; std::vector* m_trk_injet; //is the track within dR<0.4 of a genjet with pt > 30 GeV? std::vector* m_trk_injet_highpt; //is the track within dR<0.4 of a genjet with pt > 100 GeV? std::vector* m_trk_injet_vhighpt; //is the track within dR<0.4 of a genjet with pt > 200 GeV? + std::vector>* m_trk_layers; // all tracking particles std::vector* m_tp_pt; std::vector* m_tp_eta; std::vector* m_tp_phi; - std::vector* m_tp_dxy; + std::vector* m_tp_lxy; std::vector* m_tp_d0; std::vector* m_tp_z0; std::vector* m_tp_d0_prod; @@ -234,6 +241,7 @@ class L1TrackNtupleMaker : public one::EDAnalyzer* m_matchtrk_dhits; std::vector* m_matchtrk_seed; std::vector* m_matchtrk_hitpattern; + std::vector* m_matchtrk_charge; std::vector* m_matchtrk_injet; std::vector* m_matchtrk_injet_highpt; std::vector* m_matchtrk_injet_vhighpt; @@ -303,20 +311,22 @@ L1TrackNtupleMaker::L1TrackNtupleMaker(edm::ParameterSet const& iConfig) : confi TrackingVertexInputTag = iConfig.getParameter("TrackingVertexInputTag"); GenJetInputTag = iConfig.getParameter("GenJetInputTag"); - ttTrackToken_ = consumes > >(L1TrackInputTag); - ttTrackMCTruthToken_ = consumes >(MCTruthTrackInputTag); - ttStubToken_ = consumes > >(L1StubInputTag); - ttClusterMCTruthToken_ = consumes >(MCTruthClusterInputTag); - ttStubMCTruthToken_ = consumes >(MCTruthStubInputTag); + ttTrackToken_ = consumes>>(L1TrackInputTag); + ttTrackMCTruthToken_ = consumes>(MCTruthTrackInputTag); + ttStubToken_ = consumes>>(L1StubInputTag); + ttClusterMCTruthToken_ = consumes>(MCTruthClusterInputTag); + ttStubMCTruthToken_ = consumes>(MCTruthStubInputTag); - TrackingParticleToken_ = consumes >(TrackingParticleInputTag); - TrackingVertexToken_ = consumes >(TrackingVertexInputTag); - GenJetToken_ = consumes >(GenJetInputTag); + TrackingParticleToken_ = consumes>(TrackingParticleInputTag); + TrackingVertexToken_ = consumes>(TrackingVertexInputTag); + GenJetToken_ = consumes>(GenJetInputTag); getTokenTrackerGeom_ = esConsumes(); getTokenTrackerTopo_ = esConsumes(); getTokenBField_ = esConsumes(); getTokenHPHSetup_ = esConsumes(); + getTokenSetup_ = esConsumes(); + getTokenLayerEncoding_ = esConsumes(); } ///////////// @@ -355,6 +365,7 @@ void L1TrackNtupleMaker::endJob() { delete m_trk_nLost2Sstub_hitpattern; delete m_trk_nLoststub_V1_hitpattern; delete m_trk_nLoststub_V2_hitpattern; + delete m_trk_charge; delete m_trk_phiSector; delete m_trk_etaSector; delete m_trk_genuine; @@ -368,7 +379,7 @@ void L1TrackNtupleMaker::endJob() { delete m_trk_matchtp_eta; delete m_trk_matchtp_phi; delete m_trk_matchtp_z0; - delete m_trk_matchtp_dxy; + delete m_trk_matchtp_lxy; delete m_trk_matchtp_d0; delete m_trk_injet; delete m_trk_injet_highpt; @@ -377,7 +388,7 @@ void L1TrackNtupleMaker::endJob() { delete m_tp_pt; delete m_tp_eta; delete m_tp_phi; - delete m_tp_dxy; + delete m_tp_lxy; delete m_tp_d0; delete m_tp_z0; delete m_tp_d0_prod; @@ -409,6 +420,7 @@ void L1TrackNtupleMaker::endJob() { delete m_matchtrk_lhits; delete m_matchtrk_seed; delete m_matchtrk_hitpattern; + delete m_matchtrk_charge; delete m_matchtrk_injet; delete m_matchtrk_injet_highpt; delete m_matchtrk_injet_vhighpt; @@ -476,6 +488,7 @@ void L1TrackNtupleMaker::beginJob() { m_trk_nLost2Sstub_hitpattern = new std::vector; m_trk_nLoststub_V1_hitpattern = new std::vector; m_trk_nLoststub_V2_hitpattern = new std::vector; + m_trk_charge = new std::vector; m_trk_phiSector = new std::vector; m_trk_etaSector = new std::vector; m_trk_genuine = new std::vector; @@ -489,16 +502,17 @@ void L1TrackNtupleMaker::beginJob() { m_trk_matchtp_eta = new std::vector; m_trk_matchtp_phi = new std::vector; m_trk_matchtp_z0 = new std::vector; - m_trk_matchtp_dxy = new std::vector; + m_trk_matchtp_lxy = new std::vector; m_trk_matchtp_d0 = new std::vector; m_trk_injet = new std::vector; m_trk_injet_highpt = new std::vector; m_trk_injet_vhighpt = new std::vector; + m_trk_layers = new std::vector>; m_tp_pt = new std::vector; m_tp_eta = new std::vector; m_tp_phi = new std::vector; - m_tp_dxy = new std::vector; + m_tp_lxy = new std::vector; m_tp_d0 = new std::vector; m_tp_z0 = new std::vector; m_tp_d0_prod = new std::vector; @@ -530,6 +544,7 @@ void L1TrackNtupleMaker::beginJob() { m_matchtrk_lhits = new std::vector; m_matchtrk_seed = new std::vector; m_matchtrk_hitpattern = new std::vector; + m_matchtrk_charge = new std::vector; m_matchtrk_injet = new std::vector; m_matchtrk_injet_highpt = new std::vector; m_matchtrk_injet_vhighpt = new std::vector; @@ -590,6 +605,7 @@ void L1TrackNtupleMaker::beginJob() { eventTree->Branch("trk_nLost2Sstub_hitpattern", &m_trk_nLost2Sstub_hitpattern); eventTree->Branch("trk_nLoststub_V1_hitpattern", &m_trk_nLoststub_V1_hitpattern); eventTree->Branch("trk_nLoststub_V2_hitpattern", &m_trk_nLoststub_V2_hitpattern); + eventTree->Branch("trk_charge", &m_trk_charge); eventTree->Branch("trk_phiSector", &m_trk_phiSector); eventTree->Branch("trk_etaSector", &m_trk_etaSector); eventTree->Branch("trk_genuine", &m_trk_genuine); @@ -603,19 +619,20 @@ void L1TrackNtupleMaker::beginJob() { eventTree->Branch("trk_matchtp_eta", &m_trk_matchtp_eta); eventTree->Branch("trk_matchtp_phi", &m_trk_matchtp_phi); eventTree->Branch("trk_matchtp_z0", &m_trk_matchtp_z0); - eventTree->Branch("trk_matchtp_dxy", &m_trk_matchtp_dxy); + eventTree->Branch("trk_matchtp_lxy", &m_trk_matchtp_lxy); eventTree->Branch("trk_matchtp_d0", &m_trk_matchtp_d0); if (TrackingInJets) { eventTree->Branch("trk_injet", &m_trk_injet); eventTree->Branch("trk_injet_highpt", &m_trk_injet_highpt); eventTree->Branch("trk_injet_vhighpt", &m_trk_injet_vhighpt); } + eventTree->Branch("m_trk_layers", &m_trk_layers); } eventTree->Branch("tp_pt", &m_tp_pt); eventTree->Branch("tp_eta", &m_tp_eta); eventTree->Branch("tp_phi", &m_tp_phi); - eventTree->Branch("tp_dxy", &m_tp_dxy); + eventTree->Branch("tp_lxy", &m_tp_lxy); eventTree->Branch("tp_d0", &m_tp_d0); eventTree->Branch("tp_z0", &m_tp_z0); eventTree->Branch("tp_d0_prod", &m_tp_d0_prod); @@ -649,6 +666,7 @@ void L1TrackNtupleMaker::beginJob() { eventTree->Branch("matchtrk_dhits", &m_matchtrk_dhits); eventTree->Branch("matchtrk_seed", &m_matchtrk_seed); eventTree->Branch("matchtrk_hitpattern", &m_matchtrk_hitpattern); + eventTree->Branch("matchtrk_charge", &m_matchtrk_charge); if (TrackingInJets) { eventTree->Branch("matchtrk_injet", &m_matchtrk_injet); eventTree->Branch("matchtrk_injet_highpt", &m_matchtrk_injet_highpt); @@ -733,6 +751,7 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup m_trk_nLost2Sstub_hitpattern->clear(); m_trk_nLoststub_V1_hitpattern->clear(); m_trk_nLoststub_V2_hitpattern->clear(); + m_trk_charge->clear(); m_trk_phiSector->clear(); m_trk_etaSector->clear(); m_trk_genuine->clear(); @@ -746,17 +765,18 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup m_trk_matchtp_eta->clear(); m_trk_matchtp_phi->clear(); m_trk_matchtp_z0->clear(); - m_trk_matchtp_dxy->clear(); + m_trk_matchtp_lxy->clear(); m_trk_matchtp_d0->clear(); m_trk_injet->clear(); m_trk_injet_highpt->clear(); m_trk_injet_vhighpt->clear(); + m_trk_layers->clear(); } m_tp_pt->clear(); m_tp_eta->clear(); m_tp_phi->clear(); - m_tp_dxy->clear(); + m_tp_lxy->clear(); m_tp_d0->clear(); m_tp_z0->clear(); m_tp_d0_prod->clear(); @@ -788,6 +808,7 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup m_matchtrk_dhits->clear(); m_matchtrk_seed->clear(); m_matchtrk_hitpattern->clear(); + m_matchtrk_charge->clear(); m_matchtrk_injet->clear(); m_matchtrk_injet_highpt->clear(); m_matchtrk_injet_vhighpt->clear(); @@ -827,25 +848,25 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup // ----------------------------------------------------------------------------------------------- // L1 tracks - edm::Handle > > TTTrackHandle; + edm::Handle>> TTTrackHandle; iEvent.getByToken(ttTrackToken_, TTTrackHandle); // L1 stubs - edm::Handle > > TTStubHandle; + edm::Handle>> TTStubHandle; if (SaveStubs) iEvent.getByToken(ttStubToken_, TTStubHandle); // MC truth association maps - edm::Handle > MCTruthTTClusterHandle; + edm::Handle> MCTruthTTClusterHandle; iEvent.getByToken(ttClusterMCTruthToken_, MCTruthTTClusterHandle); - edm::Handle > MCTruthTTStubHandle; + edm::Handle> MCTruthTTStubHandle; iEvent.getByToken(ttStubMCTruthToken_, MCTruthTTStubHandle); - edm::Handle > MCTruthTTTrackHandle; + edm::Handle> MCTruthTTTrackHandle; iEvent.getByToken(ttTrackMCTruthToken_, MCTruthTTTrackHandle); // tracking particles - edm::Handle > TrackingParticleHandle; - edm::Handle > TrackingVertexHandle; + edm::Handle> TrackingParticleHandle; + edm::Handle> TrackingVertexHandle; iEvent.getByToken(TrackingParticleToken_, TrackingParticleHandle); //iEvent.getByToken(TrackingVertexToken_, TrackingVertexHandle); @@ -858,10 +879,14 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup edm::ESHandle bFieldHandle = iSetup.getHandle(getTokenBField_); edm::ESHandle hphHandle = iSetup.getHandle(getTokenHPHSetup_); + edm::ESHandle handleSetup = iSetup.getHandle(getTokenSetup_); + edm::ESHandle handleLayerEncoding = iSetup.getHandle(getTokenLayerEncoding_); const TrackerTopology* const tTopo = tTopoHandle.product(); const TrackerGeometry* const theTrackerGeom = tGeomHandle.product(); const hph::Setup* hphSetup = hphHandle.product(); + const tt::Setup* setup = handleSetup.product(); + const trackerTFP::LayerEncoding* layerEncoding = handleLayerEncoding.product(); // ---------------------------------------------------------------------------------------------- // loop over L1 stubs @@ -880,14 +905,14 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup continue; // Get the DetSets of the Clusters - edmNew::DetSet > stubs = (*TTStubHandle)[stackDetid]; + edmNew::DetSet> stubs = (*TTStubHandle)[stackDetid]; const GeomDetUnit* det0 = theTrackerGeom->idToDetUnit(detid); const auto* theGeomDet = dynamic_cast(det0); const PixelTopology* topol = dynamic_cast(&(theGeomDet->specificTopology())); // loop over stubs for (auto stubIter = stubs.begin(); stubIter != stubs.end(); ++stubIter) { - edm::Ref >, TTStub > tempStubPtr = + edm::Ref>, TTStub> tempStubPtr = edmNew::makeRefTo(TTStubHandle, stubIter); int isBarrel = 0; @@ -985,7 +1010,7 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup // gen jets if (DebugMode) edm::LogVerbatim("Tracklet") << "get genjets"; - edm::Handle > GenJetHandle; + edm::Handle> GenJetHandle; iEvent.getByToken(GenJetToken_, GenJetHandle); if (GenJetHandle.isValid()) { @@ -1042,9 +1067,9 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup } int this_l1track = 0; - std::vector >::const_iterator iterL1Track; + std::vector>::const_iterator iterL1Track; for (iterL1Track = TTTrackHandle->begin(); iterL1Track != TTTrackHandle->end(); iterL1Track++) { - edm::Ptr > l1track_ptr(TTTrackHandle, this_l1track); + edm::Ptr> l1track_ptr(TTTrackHandle, this_l1track); this_l1track++; float tmp_trk_pt = iterL1Track->momentum().perp(); @@ -1052,6 +1077,7 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup float tmp_trk_phi = iterL1Track->momentum().phi(); float tmp_trk_z0 = iterL1Track->z0(); //cm float tmp_trk_tanL = iterL1Track->tanL(); + int tmp_trk_charge = (int)TMath::Sign(1, iterL1Track->rInv()); bool usingNewKF = hphSetup->useNewKF(); if (usingNewKF) { // Skip crazy tracks to avoid crash (as NewKF applies no cuts to kill them). @@ -1095,7 +1121,7 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup float tmp_trk_bendchi2 = iterL1Track->stubPtConsistency(); float tmp_trk_MVA1 = iterL1Track->trkMVA1(); - std::vector >, TTStub > > + std::vector>, TTStub>> stubRefs = iterL1Track->getStubRefs(); int tmp_trk_nstub = (int)stubRefs.size(); int ndof = 2 * tmp_trk_nstub - L1Tk_nPar; @@ -1207,6 +1233,7 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup m_trk_nLost2Sstub_hitpattern->push_back(tmp_trk_nLost2Sstub_hitpattern); m_trk_nLoststub_V1_hitpattern->push_back(tmp_trk_nLoststub_V1_hitpattern); m_trk_nLoststub_V2_hitpattern->push_back(tmp_trk_nLoststub_V2_hitpattern); + m_trk_charge->push_back(tmp_trk_charge); m_trk_phiSector->push_back(tmp_trk_phiSector); m_trk_etaSector->push_back(tmp_trk_etaSector); m_trk_genuine->push_back(tmp_trk_genuine); @@ -1227,7 +1254,7 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup float tmp_matchtp_eta = -999; float tmp_matchtp_phi = -999; float tmp_matchtp_z0 = -999; - float tmp_matchtp_dxy = -999; + float tmp_matchtp_lxy = -999; float tmp_matchtp_d0 = -999; if (my_tp.isNull()) @@ -1248,7 +1275,7 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup float tmp_matchtp_vz = my_tp->vz(); float tmp_matchtp_vx = my_tp->vx(); float tmp_matchtp_vy = my_tp->vy(); - tmp_matchtp_dxy = sqrt(tmp_matchtp_vx * tmp_matchtp_vx + tmp_matchtp_vy * tmp_matchtp_vy); + tmp_matchtp_lxy = sqrt(tmp_matchtp_vx * tmp_matchtp_vx + tmp_matchtp_vy * tmp_matchtp_vy); // ---------------------------------------------------------------------------------------------- // get d0/z0 propagated back to the IP @@ -1280,7 +1307,7 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup edm::LogVerbatim("Tracklet") << "TP matched to track has pt = " << my_tp->p4().pt() << " eta = " << my_tp->momentum().eta() << " phi = " << my_tp->momentum().phi() << " z0 = " << my_tp->vertex().z() << " pdgid = " << my_tp->pdgId() - << " dxy = " << tmp_matchtp_dxy; + << " lxy = " << tmp_matchtp_lxy; } } @@ -1291,7 +1318,7 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup m_trk_matchtp_eta->push_back(tmp_matchtp_eta); m_trk_matchtp_phi->push_back(tmp_matchtp_phi); m_trk_matchtp_z0->push_back(tmp_matchtp_z0); - m_trk_matchtp_dxy->push_back(tmp_matchtp_dxy); + m_trk_matchtp_lxy->push_back(tmp_matchtp_lxy); m_trk_matchtp_d0->push_back(tmp_matchtp_d0); // ---------------------------------------------------------------------------------------------- @@ -1330,6 +1357,16 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup } //end tracking in jets + // layer encoding + const TTBV hitPattern((int)iterL1Track->hitPattern(), setup->numLayers()); + const double zT = iterL1Track->z0() + setup->chosenRofZ() * iterL1Track->tanL(); + const vector& le = layerEncoding->layerEncoding(zT); + vector layers; + layers.reserve(hitPattern.size()); + for (int layer : hitPattern.ids()) + layers.push_back(le[layer]); + m_trk_layers->push_back(layers); + } //end track loop } //end if SaveAllTracks @@ -1407,9 +1444,9 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup continue; // for pions in ttbar, only consider TPs coming from near the IP! - float dxy = sqrt(tmp_tp_vx * tmp_tp_vx + tmp_tp_vy * tmp_tp_vy); - float tmp_tp_dxy = dxy; - if (MyProcess == 6 && (dxy > 1.0)) + float lxy = sqrt(tmp_tp_vx * tmp_tp_vx + tmp_tp_vy * tmp_tp_vy); + float tmp_tp_lxy = lxy; + if (MyProcess == 6 && (lxy > 1.0)) continue; if (DebugMode) @@ -1430,7 +1467,7 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup continue; } - std::vector >, TTStub > > + std::vector>, TTStub>> theStubRefs = MCTruthTTStubHandle->findTTStubRefs(tp_ptr); int nStubTP = (int)theStubRefs.size(); @@ -1491,7 +1528,7 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup // ---------------------------------------------------------------------------------------------- // look for L1 tracks matched to the tracking particle - std::vector > > matchedTracks = + std::vector>> matchedTracks = MCTruthTTTrackHandle->findTTTrackPtrs(tp_ptr); int nMatch = 0; @@ -1544,7 +1581,7 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup // + have >= L1Tk_minNStub stubs for it to be a valid match (only relevant is your track collection // e.g. stores 3-stub tracks but at plot level you require >= 4 stubs (--> tracklet case) - std::vector >, TTStub > > + std::vector>, TTStub>> stubRefs = matchedTracks.at(it)->getStubRefs(); int tmp_trk_nstub = stubRefs.size(); @@ -1602,6 +1639,7 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup float tmp_matchtrk_chi2rz_dof = -999; float tmp_matchtrk_bendchi2 = -999; float tmp_matchtrk_MVA1 = -999; + int tmp_matchtrk_charge = -999; int tmp_matchtrk_nstub = -999; int tmp_matchtrk_dhits = -999; int tmp_matchtrk_lhits = -999; @@ -1613,6 +1651,7 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup if (nMatch > 0) { tmp_matchtrk_pt = matchedTracks.at(i_track)->momentum().perp(); + tmp_matchtrk_charge = (int)TMath::Sign(1, matchedTracks.at(i_track)->rInv()); tmp_matchtrk_eta = matchedTracks.at(i_track)->momentum().eta(); tmp_matchtrk_phi = matchedTracks.at(i_track)->momentum().phi(); tmp_matchtrk_z0 = matchedTracks.at(i_track)->z0(); @@ -1646,7 +1685,7 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup tmp_matchtrk_dhits = 0; tmp_matchtrk_lhits = 0; - std::vector >, TTStub > > + std::vector>, TTStub>> stubRefs = matchedTracks.at(i_track)->getStubRefs(); int tmp_nstub = stubRefs.size(); @@ -1674,7 +1713,7 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup m_tp_pt->push_back(tmp_tp_pt); m_tp_eta->push_back(tmp_tp_eta); m_tp_phi->push_back(tmp_tp_phi); - m_tp_dxy->push_back(tmp_tp_dxy); + m_tp_lxy->push_back(tmp_tp_lxy); m_tp_z0->push_back(tmp_tp_z0); m_tp_d0->push_back(tmp_tp_d0); m_tp_z0_prod->push_back(tmp_tp_z0_prod); @@ -1700,6 +1739,7 @@ void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup m_matchtrk_lhits->push_back(tmp_matchtrk_lhits); m_matchtrk_seed->push_back(tmp_matchtrk_seed); m_matchtrk_hitpattern->push_back(tmp_matchtrk_hitpattern); + m_matchtrk_charge->push_back(tmp_matchtrk_charge); m_matchtrk_chi2_dof->push_back(tmp_matchtrk_chi2_dof); m_matchtrk_chi2rphi_dof->push_back(tmp_matchtrk_chi2rphi_dof); m_matchtrk_chi2rz_dof->push_back(tmp_matchtrk_chi2rz_dof); diff --git a/L1Trigger/TrackFindingTracklet/test/L1TrackNtupleMaker_cfg.py b/L1Trigger/TrackFindingTracklet/test/L1TrackNtupleMaker_cfg.py index 232ae8009f88f..b9eacb9283ecb 100644 --- a/L1Trigger/TrackFindingTracklet/test/L1TrackNtupleMaker_cfg.py +++ b/L1Trigger/TrackFindingTracklet/test/L1TrackNtupleMaker_cfg.py @@ -42,8 +42,8 @@ if GEOMETRY == "D88" or GEOMETRY == 'D98': print("using geometry " + GEOMETRY + " (tilted)") - process.load('Configuration.Geometry.GeometryExtended2026' + GEOMETRY + 'Reco_cff') - process.load('Configuration.Geometry.GeometryExtended2026' + GEOMETRY +'_cff') + process.load('Configuration.Geometry.GeometryExtendedRun4' + GEOMETRY + 'Reco_cff') + process.load('Configuration.Geometry.GeometryExtendedRun4' + GEOMETRY +'_cff') else: print("this is not a valid geometry!!!") @@ -60,7 +60,7 @@ # input and output ############################################################ -process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(100)) +process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(1000)) #--- To use MCsamples scripts, defining functions get*data*() for easy MC access, #--- follow instructions in https://github.com/cms-L1TK/MCsamples @@ -82,7 +82,18 @@ #dataName="/RelValTTbar_14TeV/CMSSW_14_0_0_pre2-PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/GEN-SIM-DIGI-RAW" #inputMC=getCMSdata(dataName) - inputMC = ["/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/0b2b0b0b-f312-48a8-9d46-ccbadc69bbfd.root"] + inputMC = [#"/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/0b2b0b0b-f312-48a8-9d46-ccbadc69bbfd.root" + '/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/0b2b0b0b-f312-48a8-9d46-ccbadc69bbfd.root', + '/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/0c3cb20d-8556-450d-b4f0-e5c754818f74.root', + '/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/0eafa2b4-711a-43ec-be1c-7e564c294a9a.root', + '/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1450b1bb-171e-495e-a767-68e2796d95c2.root', + '/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/15498564-9cf0-4219-aab7-f97b3484b122.root', + '/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1838a806-316b-4f53-9d22-5b3856019623.root', + '/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1a34eb87-b9a3-47fb-b945-57e6f775fcac.root', + '/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1add5b2e-19cb-4581-956d-271907d03b72.root', + '/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1bed1837-ef65-4e07-a2ac-13c705b20fc1.root', + '/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1d057884-72bd-4353-8375-ec4616c00a33.root' + ] elif GEOMETRY == "D88": @@ -117,8 +128,6 @@ ############################################################ process.load('L1Trigger.TrackTrigger.TrackTrigger_cff') -process.load('L1Trigger.TrackerTFP.ProducerES_cff') -process.load('L1Trigger.TrackerTFP.ProducerLayerEncoding_cff') # remake stubs? #from L1Trigger.TrackTrigger.TTStubAlgorithmRegister_cfi import * @@ -131,19 +140,19 @@ #process.TTClusterStubTruth = cms.Path(process.TrackTriggerAssociatorClustersStubs) +# load code that associates stubs with mctruth +process.load( 'SimTracker.TrackTriggerAssociation.StubAssociator_cff' ) # DTC emulation -process.load('L1Trigger.TrackerDTC.ProducerED_cff') +process.load('L1Trigger.TrackerDTC.DTC_cff') # load code that analyzes DTCStubs -#process.load('L1Trigger.TrackerDTC.Analyzer_cff') +process.load('L1Trigger.TrackerDTC.Analyzer_cff') # modify default cuts #process.TrackTriggerSetup.FrontEnd.BendCut = 5.0 #process.TrackTriggerSetup.Hybrid.MinPt = 1.0 -process.dtc = cms.Path(process.TrackerDTCProducer)#*process.TrackerDTCAnalyzer) -# Throw error if reading MC produced with different stub window sizes. -process.TrackerDTCProducer.CheckHistory = True +process.dtc = cms.Path(process.StubAssociator + process.ProducerDTC + process.AnalyzerDTC) ############################################################ # L1 tracking @@ -153,8 +162,9 @@ # HYBRID: prompt tracking if (L1TRKALGO == 'HYBRID'): + process.load( 'L1Trigger.TrackFindingTracklet.Analyzer_cff' ) process.TTTracksEmulation = cms.Path(process.L1THybridTracks) - process.TTTracksEmulationWithTruth = cms.Path(process.L1THybridTracksWithAssociators) + process.TTTracksEmulationWithTruth = cms.Path(process.L1THybridTracksWithAssociators + process.AnalyzerTracklet) NHELIXPAR = 4 L1TRK_NAME = "l1tTTTracksFromTrackletEmulation" L1TRK_LABEL = "Level1TTTracks" @@ -172,18 +182,18 @@ # HYBRID_NEWKF: prompt tracking or reduced elif (L1TRKALGO == 'HYBRID_NEWKF' or L1TRKALGO == 'HYBRID_REDUCED'): process.load( 'L1Trigger.TrackFindingTracklet.Producer_cff' ) + process.load( 'L1Trigger.TrackFindingTracklet.Analyzer_cff' ) NHELIXPAR = 4 - L1TRK_NAME = process.TrackFindingTrackletProducer_params.LabelKFout.value() - L1TRK_LABEL = process.TrackFindingTrackletProducer_params.BranchAcceptedTTTracks.value() + L1TRK_NAME = process.TrackFindingTrackletAnalyzer_params.OutputLabelTFP.value() + L1TRK_LABEL = process.TrackFindingTrackletProducer_params.BranchTTTracks.value() L1TRUTH_NAME = "TTTrackAssociatorFromPixelDigis" process.TTTrackAssociatorFromPixelDigis.TTTracks = cms.VInputTag( cms.InputTag(L1TRK_NAME, L1TRK_LABEL) ) - process.HybridNewKF = cms.Sequence(process.L1THybridTracks + process.TrackFindingTrackletProducerTBout + process.TrackFindingTrackletProducerDRin + process.TrackFindingTrackletProducerDR + process.TrackFindingTrackletProducerKFin + process.TrackFindingTrackletProducerKF + process.TrackFindingTrackletProducerKFout) + process.HybridNewKF = cms.Sequence(process.L1THybridTracks + process.ProducerTM + process.ProducerDR + process.ProducerKF + process.ProducerTQ + process.ProducerTFP) process.TTTracksEmulation = cms.Path(process.HybridNewKF) #process.TTTracksEmulationWithTruth = cms.Path(process.HybridNewKF + process.TrackTriggerAssociatorTracks) # Optionally include code producing performance plots & end-of-job summary. process.load( 'SimTracker.TrackTriggerAssociation.StubAssociator_cff' ) - process.load( 'L1Trigger.TrackFindingTracklet.Analyzer_cff' ) - process.TTTracksEmulationWithTruth = cms.Path(process.HybridNewKF + process.TrackTriggerAssociatorTracks + process.StubAssociator + process.TrackFindingTrackletAnalyzerTracklet + process.TrackFindingTrackletAnalyzerTBout + process.TrackFindingTrackletAnalyzerDRin + process.TrackFindingTrackletAnalyzerDR + process.TrackFindingTrackletAnalyzerKFin + process.TrackFindingTrackletAnalyzerKF + process.TrackFindingTrackletAnalyzerKFout) + process.TTTracksEmulationWithTruth = cms.Path(process.HybridNewKF + process.TrackTriggerAssociatorTracks + process.StubAssociator + process.AnalyzerTracklet + process.AnalyzerTM + process.AnalyzerDR + process.AnalyzerKF + process.AnalyzerTQ + process.AnalyzerTFP ) from L1Trigger.TrackFindingTracklet.Customize_cff import * if (L1TRKALGO == 'HYBRID_NEWKF'): fwConfig( process ) diff --git a/L1Trigger/TrackFindingTracklet/test/L1TrackNtuplePlot.C b/L1Trigger/TrackFindingTracklet/test/L1TrackNtuplePlot.C index 383c896baa7db..b6c89ee07dcbf 100644 --- a/L1Trigger/TrackFindingTracklet/test/L1TrackNtuplePlot.C +++ b/L1Trigger/TrackFindingTracklet/test/L1TrackNtuplePlot.C @@ -54,7 +54,7 @@ void L1TrackNtuplePlot(TString type, float TP_minPt = 2.0, float TP_maxPt = 100.0, float TP_maxEta = 2.4, - float TP_maxDxy = 1.0, + float TP_maxLxy = 1.0, float TP_maxD0 = 1.0, bool doDetailedPlots = false) { // type: this is the name of the input file you want to process (minus ".root" extension) @@ -68,7 +68,7 @@ void L1TrackNtuplePlot(TString type, // TP_select_injet: only look at TPs that are within a jet with pt > 30 GeV (==1) or within a jet with pt > 100 GeV (==2), >200 GeV (==3) or all TPs (==0) - //-- N.B. For standard displaced tracking plots, set TP_minPt=3.0, TP_maxEta=2.0, TP_maxDxy=10.0, + //-- N.B. For standard displaced tracking plots, set TP_minPt=3.0, TP_maxEta=2.0, TP_maxLxy=10.0, //-- TO_maxD0=10.0, doDetailedPlots=true. (Efficiency plots vs eta also usually made for d0 < 5). gROOT->SetBatch(); @@ -148,7 +148,7 @@ void L1TrackNtuplePlot(TString type, vector* tp_pt; vector* tp_eta; vector* tp_phi; - vector* tp_dxy; + vector* tp_lxy; vector* tp_z0; vector* tp_d0; vector* tp_pdgid; @@ -206,7 +206,7 @@ void L1TrackNtuplePlot(TString type, TBranch* b_tp_pt; TBranch* b_tp_eta; TBranch* b_tp_phi; - TBranch* b_tp_dxy; + TBranch* b_tp_lxy; TBranch* b_tp_z0; TBranch* b_tp_d0; TBranch* b_tp_pdgid; @@ -262,7 +262,7 @@ void L1TrackNtuplePlot(TString type, tp_pt = 0; tp_eta = 0; tp_phi = 0; - tp_dxy = 0; + tp_lxy = 0; tp_z0 = 0; tp_d0 = 0; tp_pdgid = 0; @@ -318,7 +318,7 @@ void L1TrackNtuplePlot(TString type, tree->SetBranchAddress("tp_pt", &tp_pt, &b_tp_pt); tree->SetBranchAddress("tp_eta", &tp_eta, &b_tp_eta); tree->SetBranchAddress("tp_phi", &tp_phi, &b_tp_phi); - tree->SetBranchAddress("tp_dxy", &tp_dxy, &b_tp_dxy); + tree->SetBranchAddress("tp_lxy", &tp_lxy, &b_tp_lxy); tree->SetBranchAddress("tp_z0", &tp_z0, &b_tp_z0); tree->SetBranchAddress("tp_d0", &tp_d0, &b_tp_d0); tree->SetBranchAddress("tp_pdgid", &tp_pdgid, &b_tp_pdgid); @@ -1240,7 +1240,7 @@ void L1TrackNtuplePlot(TString type, } // kinematic cuts - if (std::abs(tp_dxy->at(it)) > TP_maxDxy) + if (std::abs(tp_lxy->at(it)) > TP_maxLxy) continue; if (std::abs(tp_d0->at(it)) > TP_maxD0) continue; diff --git a/L1Trigger/TrackFindingTracklet/test/ProducerIRin.cc b/L1Trigger/TrackFindingTracklet/test/ProducerIRin.cc index 7ca0960306522..1b9255b4c5bbd 100644 --- a/L1Trigger/TrackFindingTracklet/test/ProducerIRin.cc +++ b/L1Trigger/TrackFindingTracklet/test/ProducerIRin.cc @@ -20,10 +20,6 @@ #include #include -using namespace std; -using namespace edm; -using namespace tt; - namespace trklet { /*! \class trklet::ProducerIRin @@ -31,72 +27,65 @@ namespace trklet { * \author Thomas Schuh * \date 2021, Oct */ - class ProducerIRin : public stream::EDProducer<> { + class ProducerIRin : public edm::stream::EDProducer<> { public: - explicit ProducerIRin(const ParameterSet&); + explicit ProducerIRin(const edm::ParameterSet&); ~ProducerIRin() override {} private: - void beginRun(const Run&, const EventSetup&) override; - void produce(Event&, const EventSetup&) override; + void beginRun(const edm::Run&, const edm::EventSetup&) override; + void produce(edm::Event&, const edm::EventSetup&) override; virtual void endJob() {} // ED input token of DTC Stubs - EDGetTokenT edGetTokenTTDTC_; + edm::EDGetTokenT edGetTokenTTDTC_; // ED output token for stubs - EDPutTokenT edPutTokenStubs_; + edm::EDPutTokenT edPutTokenStubs_; // Setup token - ESGetToken esGetTokenSetup_; + edm::ESGetToken esGetTokenSetup_; // ChannelAssignment token - ESGetToken esGetTokenChannelAssignment_; + edm::ESGetToken esGetTokenChannelAssignment_; // configuration - ParameterSet iConfig_; + edm::ParameterSet iConfig_; // helper class to store configurations - const Setup* setup_; + const tt::Setup* setup_; // helper class to assign stubs to channel const ChannelAssignment* channelAssignment_; // map of used tfp channels - vector channelEncoding_; + std::vector channelEncoding_; }; - ProducerIRin::ProducerIRin(const ParameterSet& iConfig) : iConfig_(iConfig) { - const InputTag& inputTag = iConfig.getParameter("InputTagDTC"); - const string& branchStubs = iConfig.getParameter("BranchAcceptedStubs"); + ProducerIRin::ProducerIRin(const edm::ParameterSet& iConfig) : iConfig_(iConfig) { + const edm::InputTag& inputTag = iConfig.getParameter("InputTagDTC"); + const std::string& branchStubs = iConfig.getParameter("BranchStubsAccepted"); // book in- and output ED products edGetTokenTTDTC_ = consumes(inputTag); - edPutTokenStubs_ = produces(branchStubs); + edPutTokenStubs_ = produces(branchStubs); // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenChannelAssignment_ = esConsumes(); + esGetTokenSetup_ = esConsumes(); + esGetTokenChannelAssignment_ = esConsumes(); // initial ES products setup_ = nullptr; } - void ProducerIRin::beginRun(const Run& iRun, const EventSetup& iSetup) { + void ProducerIRin::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) { // helper class to store configurations setup_ = &iSetup.getData(esGetTokenSetup_); - if (!setup_->configurationSupported()) - return; - // check process history if desired - if (iConfig_.getParameter("CheckHistory")) - setup_->checkHistory(iRun.processHistory()); channelAssignment_ = const_cast(&iSetup.getData(esGetTokenChannelAssignment_)); // map of used tfp channels channelEncoding_ = channelAssignment_->channelEncoding(); } - void ProducerIRin::produce(Event& iEvent, const EventSetup& iSetup) { + void ProducerIRin::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { // empty IRin product - StreamsStub streamStubs; + tt::StreamsStub streamStubs; // read in hybrid track finding product and produce KFin product - if (setup_->configurationSupported()) { - Handle handleTTDTC; - iEvent.getByToken(edGetTokenTTDTC_, handleTTDTC); - const int numChannel = channelEncoding_.size(); - streamStubs.reserve(numChannel); - for (int tfpRegion : handleTTDTC->tfpRegions()) - for (int tfpChannel : channelEncoding_) - streamStubs.emplace_back(handleTTDTC->stream(tfpRegion, tfpChannel)); - } + edm::Handle handleTTDTC; + iEvent.getByToken(edGetTokenTTDTC_, handleTTDTC); + const int numChannel = channelEncoding_.size(); + streamStubs.reserve(numChannel); + for (int tfpRegion : handleTTDTC->tfpRegions()) + for (int tfpChannel : channelEncoding_) + streamStubs.emplace_back(handleTTDTC->stream(tfpRegion, tfpChannel)); // store products iEvent.emplace(edPutTokenStubs_, std::move(streamStubs)); } diff --git a/L1Trigger/TrackFindingTracklet/test/demonstrator_cfg.py b/L1Trigger/TrackFindingTracklet/test/demonstrator_cfg.py index 77406528debd0..86dea01ab5bba 100644 --- a/L1Trigger/TrackFindingTracklet/test/demonstrator_cfg.py +++ b/L1Trigger/TrackFindingTracklet/test/demonstrator_cfg.py @@ -4,8 +4,8 @@ process = cms.Process( "Demo" ) process.load( 'FWCore.MessageService.MessageLogger_cfi' ) process.load( 'Configuration.EventContent.EventContent_cff' ) -process.load( 'Configuration.Geometry.GeometryExtendedRun4D88Reco_cff' ) -process.load( 'Configuration.Geometry.GeometryExtendedRun4D88_cff' ) +process.load( 'Configuration.Geometry.GeometryExtended2026D98Reco_cff' ) +process.load( 'Configuration.Geometry.GeometryExtended2026D98_cff' ) process.load( 'Configuration.StandardSequences.MagneticField_cff' ) process.load( 'Configuration.StandardSequences.FrontierConditions_GlobalTag_cff' ) process.load( 'L1Trigger.TrackTrigger.TrackTrigger_cff' ) @@ -14,7 +14,7 @@ process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic', '') # load code that produces DTCStubs -process.load( 'L1Trigger.TrackerDTC.ProducerED_cff' ) +process.load( 'L1Trigger.TrackerDTC.DTC_cff' ) # L1 tracking => hybrid emulation process.load("L1Trigger.TrackFindingTracklet.L1HybridEmulationTracks_cff") # load code that fits hybrid tracks @@ -26,12 +26,12 @@ fwConfig( process ) # build schedule -process.tt = cms.Sequence ( process.TrackerDTCProducer +process.tt = cms.Sequence ( process.ProducerDTC + #+ process.ProducerIRin + process.L1THybridTracks - + process.TrackFindingTrackletProducerIRin - + process.TrackFindingTrackletProducerTBout - + process.TrackFindingTrackletProducerDRin - + process.TrackFindingTrackletProducerDR + + process.ProducerTM + + process.ProducerDR + #+ process.ProducerKF ) process.demo = cms.Path( process.tt + process.TrackerTFPDemonstrator ) process.schedule = cms.Schedule( process.demo ) @@ -40,9 +40,20 @@ import FWCore.ParameterSet.VarParsing as VarParsing options = VarParsing.VarParsing( 'analysis' ) # specify input MC -inputMC = ["/store/relval/CMSSW_12_6_0_pre4/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_125X_mcRun4_realistic_v2_2026D88PU200-v1/2590000/00b3d04b-4c7b-4506-8d82-9538fb21ee19.root"] +Samples = [ +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/0b2b0b0b-f312-48a8-9d46-ccbadc69bbfd.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/0c3cb20d-8556-450d-b4f0-e5c754818f74.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/0eafa2b4-711a-43ec-be1c-7e564c294a9a.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1450b1bb-171e-495e-a767-68e2796d95c2.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/15498564-9cf0-4219-aab7-f97b3484b122.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1838a806-316b-4f53-9d22-5b3856019623.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1a34eb87-b9a3-47fb-b945-57e6f775fcac.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1add5b2e-19cb-4581-956d-271907d03b72.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1bed1837-ef65-4e07-a2ac-13c705b20fc1.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1d057884-72bd-4353-8375-ec4616c00a33.root' +] -options.register( 'inputMC', inputMC, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.string, "Files to be processed" ) +options.register( 'inputMC', Samples, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.string, "Files to be processed" ) # specify number of events to process. options.register( 'Events',100,VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.int, "Number of Events to analyze" ) options.parseArguments() @@ -52,7 +63,7 @@ process.source = cms.Source( "PoolSource", fileNames = cms.untracked.vstring( options.inputMC ), - #skipEvents = cms.untracked.uint32( 1 ), + #skipEvents = cms.untracked.uint32( 301 ), secondaryFileNames = cms.untracked.vstring(), duplicateCheckMode = cms.untracked.string( 'noDuplicateCheck' ) ) diff --git a/L1Trigger/TrackTrigger/interface/L1TrackQuality.h b/L1Trigger/TrackTrigger/interface/L1TrackQuality.h deleted file mode 100644 index 1107ed3e74fbb..0000000000000 --- a/L1Trigger/TrackTrigger/interface/L1TrackQuality.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -Track Quality Header file -C.Brown 28/07/20 -*/ - -#ifndef L1Trigger_TrackTrigger_interface_L1TrackQuality_h -#define L1Trigger_TrackTrigger_interface_L1TrackQuality_h - -#include -#include -#include -#include -#include - -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "DataFormats/L1TrackTrigger/interface/TTTrack.h" -#include "DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h" -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" -#include - -#include "conifer.h" -#include "ap_fixed.h" - -class L1TrackQuality { -public: - //Default Constructor - L1TrackQuality(); - - L1TrackQuality(const edm::ParameterSet& qualityParams); - - //Default Destructor - ~L1TrackQuality() = default; - - // Controls the conversion between TTTrack features and ML model training features - std::vector featureTransform(TTTrack& aTrack, - std::vector const& featureNames); - - // Passed by reference a track without MVA filled, method fills the track's MVA field - void setL1TrackQuality(TTTrack& aTrack); - // Function to run the BDT in isolation allowing a feature vector in the ap_fixed datatype to be passed - // and a single output to be returned which is then used to fill the bits in the Track Word for situations - // where a TTTrack datatype is unavailable to be passed to the track quality - float runEmulatedTQ(std::vector> inputFeatures); - - void setModel(edm::FileInPath const& model, std::vector const& featureNames); - - void setBonusFeatures(std::vector bonusFeatures); - - // TQ MVA bin conversions - static constexpr double invSigmoid(double value) { return -log(1. / value - 1.); } - static constexpr std::array getTqMVAPreSigBins() { - return {{-16., - invSigmoid(TTTrack_TrackWord::tqMVABins[1]), - invSigmoid(TTTrack_TrackWord::tqMVABins[2]), - invSigmoid(TTTrack_TrackWord::tqMVABins[3]), - invSigmoid(TTTrack_TrackWord::tqMVABins[4]), - invSigmoid(TTTrack_TrackWord::tqMVABins[5]), - invSigmoid(TTTrack_TrackWord::tqMVABins[6]), - invSigmoid(TTTrack_TrackWord::tqMVABins[7])}}; - } - -private: - // Private Member Data - edm::FileInPath model_; - std::vector featureNames_; - bool useHPH_; - std::vector bonusFeatures_; -}; -#endif diff --git a/L1Trigger/TrackTrigger/interface/SensorModule.h b/L1Trigger/TrackTrigger/interface/SensorModule.h index a10c701f24344..4533c39965940 100644 --- a/L1Trigger/TrackTrigger/interface/SensorModule.h +++ b/L1Trigger/TrackTrigger/interface/SensorModule.h @@ -25,6 +25,8 @@ namespace tt { bool side() const { return side_; } // barrel or endcap bool barrel() const { return barrel_; } + // tilted barrel or flat barrel + bool tilted() const { return tilted_; } // Pixel-Strip or 2Strip module bool psModule() const { return psModule_; } // main sensor inside or outside @@ -69,6 +71,10 @@ namespace tt { int windowSize() const { return windowSize_; } // double tiltCorrection(double cot) const { return std::abs(tiltCorrectionSlope_ * cot) + tiltCorrectionIntercept_; } + // + double dPhi(double inv2R) const { return dPhi_ + (dR_ + scattering_) * std::abs(inv2R); } + // + double dZ() const { return dZ_; } unsigned int ringId(const Setup* setup) const; @@ -84,6 +90,8 @@ namespace tt { bool side_; // barrel or endcap bool barrel_; + // tilted barrel or flat barrel + bool tilted_; // Pixel-Strip or 2Strip module bool psModule_; // main sensor inside or outside @@ -132,6 +140,14 @@ namespace tt { double tiltCorrectionSlope_; // tilt correction parameter used to project r to z uncertainty double tiltCorrectionIntercept_; + // + double scattering_; + // + double dR_; + // + double dPhi_; + // + double dZ_; }; } // namespace tt diff --git a/L1Trigger/TrackTrigger/interface/Setup.h b/L1Trigger/TrackTrigger/interface/Setup.h index 07fe6cd88eb5a..c54242e605560 100644 --- a/L1Trigger/TrackTrigger/interface/Setup.h +++ b/L1Trigger/TrackTrigger/interface/Setup.h @@ -4,8 +4,6 @@ #include "FWCore/Framework/interface/data_default_record_trait.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/ParameterSet/interface/Registry.h" -#include "DataFormats/Provenance/interface/ProcessHistory.h" -#include "DataFormats/Provenance/interface/ParameterSetID.h" #include "DataFormats/DetId/interface/DetId.h" #include "DataFormats/GeometryVector/interface/GlobalPoint.h" #include "DataFormats/Math/interface/deltaPhi.h" @@ -13,10 +11,7 @@ #include "DataFormats/SiStripDetId/interface/StripSubdetector.h" #include "Geometry/CommonTopologies/interface/PixelGeomDetUnit.h" #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" -#include "DetectorDescription/Core/interface/DDCompactView.h" -#include "DetectorDescription/DDCMS/interface/DDCompactView.h" #include "L1Trigger/TrackTrigger/interface/TTStubAlgorithm_official.h" -#include "MagneticField/Engine/interface/MagneticField.h" #include "CondFormats/SiPhase2TrackerObjects/interface/TrackerDetToDTCELinkCablingMap.h" #include "SimTracker/Common/interface/TrackingParticleSelector.h" @@ -43,23 +38,164 @@ namespace tt { */ class Setup { public: + // Configuration + struct Config { + double beamWindowZ_; + double minPt_; + double minPtCand_; + double maxEta_; + double maxD0_; + double chosenRofPhi_; + int numLayers_; + int minLayers_; + int tmttWidthR_; + int tmttWidthPhi_; + int tmttWidthZ_; + int hybridNumLayers_; + std::vector hybridNumRingsPS_; + std::vector hybridWidthsR_; + std::vector hybridWidthsZ_; + std::vector hybridWidthsPhi_; + std::vector hybridWidthsAlpha_; + std::vector hybridWidthsBend_; + std::vector hybridRangesR_; + std::vector hybridRangesZ_; + std::vector hybridRangesAlpha_; + std::vector hybridLayerRs_; + std::vector hybridDiskZs_; + std::vector hybridDisk2SRsSet_; + double hybridRangePhi_; + double tbBarrelHalfLength_; + double tbInnerRadius_; + std::vector tbWidthsR_; + int enableTruncation_; + bool useHybrid_; + int widthDSPa_; + int widthDSPab_; + int widthDSPau_; + int widthDSPb_; + int widthDSPbb_; + int widthDSPbu_; + int widthDSPc_; + int widthDSPcb_; + int widthDSPcu_; + int widthAddrBRAM36_; + int widthAddrBRAM18_; + int numFramesInfra_; + double freqLHC_; + double freqBEHigh_; + double freqBELow_; + int tmpFE_; + int tmpTFP_; + double speedOfLight_; + double bField_; + double bFieldError_; + double outerRadius_; + double innerRadius_; + double halfLength_; + double maxPitchRow_; + double maxPitchCol_; + double tiltApproxSlope_; + double tiltApproxIntercept_; + double tiltUncertaintyR_; + double scattering_; + double pitchRow2S_; + double pitchRowPS_; + double pitchCol2S_; + double pitchColPS_; + double limitPSBarrel_; + std::vector limitsTiltedR_; + std::vector limitsTiltedZ_; + std::vector limitsPSDiksZ_; + std::vector limitsPSDiksR_; + std::vector tiltedLayerLimitsZ_; + std::vector psDiskLimitsR_; + int widthBend_; + int widthCol_; + int widthRow_; + double baseBend_; + double baseCol_; + double baseRow_; + double baseWindowSize_; + double bendCut_; + int numRegions_; + int numOverlappingRegions_; + int numATCASlots_; + int numDTCsPerRegion_; + int numModulesPerDTC_; + int dtcNumRoutingBlocks_; + int dtcDepthMemory_; + int dtcWidthRowLUT_; + int dtcWidthInv2R_; + int offsetDetIdDSV_; + int offsetDetIdTP_; + int offsetLayerDisks_; + int offsetLayerId_; + int numBarrelLayer_; + int numBarrelLayerPS_; + int dtcNumStreams_; + int slotLimitPS_; + int slotLimit10gbps_; + int tfpWidthPhi0_; + int tfpWidthInvR_; + int tfpWidthCot_; + int tfpWidthZ0_; + int tfpNumChannel_; + int gpNumBinsPhiT_; + int gpNumBinsZT_; + double chosenRofZ_; + int gpDepthMemory_; + int gpWidthModule_; + int gpPosPS_; + int gpPosBarrel_; + int gpPosTilted_; + int htNumBinsInv2R_; + int htNumBinsPhiT_; + int htMinLayers_; + int htDepthMemory_; + int ctbNumBinsInv2R_; + int ctbNumBinsPhiT_; + int ctbNumBinsCot_; + int ctbNumBinsZT_; + int ctbMinLayers_; + int ctbMaxTracks_; + int ctbMaxStubs_; + int ctbDepthMemory_; + bool kfUse5ParameterFit_; + bool kfUseSimmulation_; + bool kfUseTTStubResiduals_; + bool kfUseTTStubParameters_; + bool kfApplyNonLinearCorrection_; + int kfNumWorker_; + int kfMaxTracks_; + int kfMinLayers_; + int kfMinLayersPS_; + int kfMaxLayers_; + int kfMaxGaps_; + int kfMaxSeedingLayer_; + int kfNumSeedStubs_; + double kfMinSeedDeltaR_; + double kfRangeFactor_; + int kfShiftInitialC00_; + int kfShiftInitialC11_; + int kfShiftInitialC22_; + int kfShiftInitialC33_; + int kfShiftChi20_; + int kfShiftChi21_; + double kfCutChi2_; + int kfWidthChi2_; + int drDepthMemory_; + int tqNumChannel_; + }; Setup() {} - Setup(const edm::ParameterSet& iConfig, - const MagneticField& magneticField, + Setup(const Config& iConfig, const TrackerGeometry& trackerGeometry, const TrackerTopology& trackerTopology, const TrackerDetToDTCELinkCablingMap& cablingMap, const StubAlgorithmOfficial& stubAlgorithm, - const edm::ParameterSet& pSetStubAlgorithm, - const edm::ParameterSet& pSetGeometryConfiguration, - const edm::ParameterSetID& pSetIdTTStubAlgorithm, - const edm::ParameterSetID& pSetIdGeometryConfiguration); + const edm::ParameterSet& pSetStubAlgorithm); ~Setup() {} - // true if tracker geometry and magnetic field supported - bool configurationSupported() const { return configurationSupported_; } - // checks current configuration vs input sample configuration - void checkHistory(const edm::ProcessHistory& processHistory) const; // converts tk layout id into dtc id int dtcId(int tklId) const; // converts dtci id into tk layout id @@ -76,6 +212,8 @@ namespace tt { int slot(int dtcId) const; // sensor module for det id SensorModule* sensorModule(const DetId& detId) const; + // sensor module for ttStubRef + SensorModule* sensorModule(const TTStubRef& ttStubRef) const; // TrackerGeometry const TrackerGeometry* trackerGeometry() const { return trackerGeometry_; } // TrackerTopology @@ -85,15 +223,9 @@ namespace tt { // returns bit accurate hybrid stub radius for given TTStubRef and h/w bit word double stubR(const TTBV& hw, const TTStubRef& ttStubRef) const; // returns bit accurate position of a stub from a given tfp region [0-8] - GlobalPoint stubPos(bool hybrid, const tt::FrameStub& frame, int region) const; + GlobalPoint stubPos(const tt::FrameStub& frame, int region) const; // empty trackerDTC EDProduct TTDTC ttDTC() const { return TTDTC(numRegions_, numOverlappingRegions_, numDTCsPerRegion_); } - // checks if stub collection is considered forming a reconstructable track - bool reconstructable(const std::vector& ttStubRefs) const; - // checks if tracking particle is selected for efficiency measurements - bool useForAlgEff(const TrackingParticle& tp) const; - // checks if tracking particle is selected for fake and duplicate rate measurements - bool useForReconstructable(const TrackingParticle& tp) const { return tpSelectorLoose_(tp); } // stub layer id (barrel: 1 - 6, endcap: 11 - 15) int layerId(const TTStubRef& ttStubRef) const; // return tracklet layerId (barrel: [0-5], endcap: [6-10]) for given TTStubRef @@ -106,6 +238,8 @@ namespace tt { bool psModule(const TTStubRef& ttStubRef) const; // return sensor moduel type SensorModule::Type type(const TTStubRef& ttStubRef) const; + // checks if stub collection is considered forming a reconstructable track + bool reconstructable(const std::vector& ttStubRefs) const; // TTBV layerMap(const std::vector& ints) const; // @@ -117,16 +251,30 @@ namespace tt { // stub projected phi uncertainty double dPhi(const TTStubRef& ttStubRef, double inv2R) const; // stub projected z uncertainty - double dZ(const TTStubRef& ttStubRef, double cot) const; + double dZ(const TTStubRef& ttStubRef) const; // stub projected chi2phi wheight double v0(const TTStubRef& ttStubRef, double inv2R) const; // stub projected chi2z wheight double v1(const TTStubRef& ttStubRef, double cot) const; // const std::vector& sensorModules() const { return sensorModules_; } + // + TTBV module(double r, double z) const; + // + bool ps(const TTBV& module) const { return module[gpPosPS_]; } + // + bool barrel(const TTBV& module) const { return module[gpPosBarrel_]; } + // + bool tilted(const TTBV& module) const { return module[gpPosTilted_]; } + // stub projected phi uncertainty for given module type, stub radius and track curvature + double dPhi(const TTBV& module, double r, double inv2R) const; // Firmware specific Parameter + // enable emulation of truncation for TM, DR, KF, TQ and TFP + int enableTruncation() const { return enableTruncation_; } + // use Hybrid or TMTT as TT algorithm + bool useHybrid() const { return useHybrid_; } // width of the 'A' port of an DSP slice int widthDSPa() const { return widthDSPa_; } // width of the 'A' port of an DSP slice using biased twos complement @@ -150,29 +298,50 @@ namespace tt { // smallest address width of an BRAM18 configured as broadest simple dual port memory int widthAddrBRAM18() const { return widthAddrBRAM18_; } // number of frames betwen 2 resets of 18 BX packets - int numFrames() const { return numFrames_; } + int numFramesHigh() const { return numFramesHigh_; } + // number of frames betwen 2 resets of 18 BX packets + int numFramesLow() const { return numFramesLow_; } // number of frames needed per reset int numFramesInfra() const { return numFramesInfra_; } // number of valid frames per 18 BX packet - int numFramesIO() const { return numFramesIO_; } + int numFramesIOHigh() const { return numFramesIOHigh_; } + // number of valid frames per 18 BX packet + int numFramesIOLow() const { return numFramesIOLow_; } // number of valid frames per 8 BX packet int numFramesFE() const { return numFramesFE_; } - // maximum representable stub phi uncertainty - double maxdPhi() const { return maxdPhi_; } - // maximum representable stub z uncertainty - double maxdZ() const { return maxdZ_; } - // barrel layer limit z value to partition into tilted and untilted region - double tiltedLayerLimitZ(int layer) const { return tiltedLayerLimitsZ_.at(layer); } - // endcap disk limit r value to partition into PS and 2S region - double psDiskLimitR(int layer) const { return psDiskLimitsR_.at(layer); } + + // Tracker specific Parameter + // strip pitch of outer tracker sensors in cm - double pitch2S() const { return pitch2S_; } + double pitchRow2S() const { return pitchRow2S_; } // pixel pitch of outer tracker sensors in cm - double pitchPS() const { return pitchPS_; } + double pitchRowPS() const { return pitchRowPS_; } // strip length of outer tracker sensors in cm - double length2S() const { return length2S_; } + double pitchCol2S() const { return pitchCol2S_; } // pixel length of outer tracker sensors in cm - double lengthPS() const { return lengthPS_; } + double pitchColPS() const { return pitchColPS_; } + // BField used in fw in T + double bField() const { return bField_; } + // outer radius of outer tracker in cm + double outerRadius() const { return outerRadius_; } + // inner radius of outer tracker in cm + double innerRadius() const { return innerRadius_; } + // half length of outer tracker in cm + double halfLength() const { return halfLength_; } + // max strip/pixel length of outer tracker sensors in cm + double maxPitchCol() const { return maxPitchCol_; } + // In tilted barrel, grad*|z|/r + int approximates |cosTilt| + |sinTilt * cotTheta| + double tiltApproxSlope() const { return tiltApproxSlope_; } + // In tilted barrel, grad*|z|/r + int approximates |cosTilt| + |sinTilt * cotTheta| + double tiltApproxIntercept() const { return tiltApproxIntercept_; } + // In tilted barrel, constant assumed stub radial uncertainty * sqrt(12) in cm + double tiltUncertaintyR() const { return tiltUncertaintyR_; } + // scattering term used to add stub phi uncertainty depending on assumed track inv2R + double scattering() const { return scattering_; } + // barrel layer limit z value to partition into tilted and untilted region + double tiltedLayerLimitZ(int layer) const { return tiltedLayerLimitsZ_.at(layer); } + // endcap disk limit r value to partition into PS and 2S region + double psDiskLimitR(int layer) const { return psDiskLimitsR_.at(layer); } // Common track finding parameter @@ -182,37 +351,23 @@ namespace tt { double invPtToDphi() const { return invPtToDphi_; } // region size in rad double baseRegion() const { return baseRegion_; } - // pt cut - double tpMinPt() const { return tpMinPt_; } - // TP eta cut - double tpMaxEta() const { return tpMaxEta_; } - // TP cut on vertex pos r in cm - double tpMaxVertR() const { return tpMaxVertR_; } - // TP cut on vertex pos z in cm - double tpMaxVertZ() const { return tpMaxVertZ_; } - // TP cut on impact parameter in cm - double tpMaxD0() const { return tpMaxD0_; } - // required number of associated layers to a TP to consider it reconstruct-able - int tpMinLayers() const { return tpMinLayers_; } - // required number of associated ps layers to a TP to consider it reconstruct-able - int tpMinLayersPS() const { return tpMinLayersPS_; } - // max number of unassociated 2S stubs allowed to still associate TTTrack with TP - int tpMaxBadStubs2S() const { return tpMaxBadStubs2S_; } - // max number of unassociated PS stubs allowed to still associate TTTrack with TP - int tpMaxBadStubsPS() const { return tpMaxBadStubsPS_; } - // BField used in fw in T - double bField() const { return bField_; } - - // TMTT specific parameter - + // max cot(theta) of found tracks + double maxCot() const { return maxCot_; } // cut on stub and TP pt, also defines region overlap shape in GeV double minPt() const { return minPt_; } + // cut on candidate pt + double minPtCand() const { return minPtCand_; } // cut on stub eta double maxEta() const { return maxEta_; } + // constraints track reconstruction phase space + double maxD0() const { return maxD0_; } // critical radius defining region overlap shape in cm double chosenRofPhi() const { return chosenRofPhi_; } - // number of detector layers a reconstructbale particle may cross + // TMTT: number of detector layers a reconstructbale particle may cross; Hybrid: max number of layers connected to one DTC int numLayers() const { return numLayers_; } + + // TMTT specific parameter + // number of bits used for stub r - ChosenRofPhi int tmttWidthR() const { return tmttWidthR_; } // number of bits used for stub phi w.r.t. phi sector centre @@ -237,35 +392,11 @@ namespace tt { double tmttBasePhiT() const { return tmttBasePhiT_; } // number of padded 0s in output data format int tmttNumUnusedBits() const { return tmttNumUnusedBits_; } - // outer radius of outer tracker in cm - double outerRadius() const { return outerRadius_; } - // inner radius of outer tracker in cm - double innerRadius() const { return innerRadius_; } - // half length of outer tracker in cm - double halfLength() const { return halfLength_; } - // max strip/pixel length of outer tracker sensors in cm - double maxLength() const { return maxLength_; } - // In tilted barrel, grad*|z|/r + int approximates |cosTilt| + |sinTilt * cotTheta| - double tiltApproxSlope() const { return tiltApproxSlope_; } - // In tilted barrel, grad*|z|/r + int approximates |cosTilt| + |sinTilt * cotTheta| - double tiltApproxIntercept() const { return tiltApproxIntercept_; } - // In tilted barrel, constant assumed stub radial uncertainty * sqrt(12) in cm - double tiltUncertaintyR() const { return tiltUncertaintyR_; } - // scattering term used to add stub phi uncertainty depending on assumed track inv2R - double scattering() const { return scattering_; } // Hybrid specific parameter - // cut on stub pt in GeV, also defines region overlap shape - double hybridMinPtStub() const { return hybridMinPtStub_; } - // cut on andidate pt in GeV - double hybridMinPtCand() const { return hybridMinPtCand_; } - // cut on stub eta - double hybridMaxEta() const { return hybridMaxEta_; } - // critical radius defining region overlap shape in cm - double hybridChosenRofPhi() const { return hybridChosenRofPhi_; } - // max number of detector layer connected to one DTC - int hybridNumLayers() const { return hybridNumLayers_; } + // max number of layer connected to one DTC + double hybridNumLayers() const { return hybridNumLayers_; } // number of bits used for stub r w.r.t layer/disk centre for module types (barrelPS, barrel2S, diskPS, disk2S) int hybridWidthR(SensorModule::Type type) const { return hybridWidthsR_.at(type); } // number of bits used for stub z w.r.t layer/disk centre for module types (barrelPS, barrel2S, diskPS, disk2S) @@ -280,10 +411,13 @@ namespace tt { int hybridWidthLayerId() const { return hybridWidthLayerId_; } // precision or r in cm for (barrelPS, barrel2S, diskPS, disk2S) double hybridBaseR(SensorModule::Type type) const { return hybridBasesR_.at(type); } + double hybridBaseR() const { return hybridBaseR_; } // precision or phi in rad for (barrelPS, barrel2S, diskPS, disk2S) double hybridBasePhi(SensorModule::Type type) const { return hybridBasesPhi_.at(type); } + double hybridBasePhi() const { return hybridBasePhi_; } // precision or z in cm for (barrelPS, barrel2S, diskPS, disk2S) double hybridBaseZ(SensorModule::Type type) const { return hybridBasesZ_.at(type); } + double hybridBaseZ() const { return hybridBaseZ_; } // precision or alpha in pitch units for (barrelPS, barrel2S, diskPS, disk2S) double hybridBaseAlpha(SensorModule::Type type) const { return hybridBasesAlpha_.at(type); } // number of padded 0s in output data format for (barrelPS, barrel2S, diskPS, disk2S) @@ -300,6 +434,8 @@ namespace tt { double hybridRangePhi() const { return hybridRangePhi_; } // range of stub r in cm double hybridRangeR() const { return hybridRangesR_[SensorModule::DiskPS]; } + // biggest barrel stub z position after TrackBuilder in cm + double tbBarrelHalfLength() const { return tbBarrelHalfLength_; } // smallest stub radius after TrackBuilder in cm double tbInnerRadius() const { return tbInnerRadius_; } // center radius of outer tracker endcap 2S diks strips @@ -325,6 +461,8 @@ namespace tt { double baseWindowSize() const { return baseWindowSize_; } // index = encoded bend, value = decoded bend for given window size and module type const std::vector& encodingBend(int windowSize, bool psModule) const; + //getBendCut + const StubAlgorithmOfficial* stubAlgorithm() const { return stubAlgorithm_; } // Parameter specifying front-end @@ -371,8 +509,10 @@ namespace tt { int offsetLayerDisks() const { return offsetLayerDisks_; } // offset between 0 and smallest layer id (barrel layer 1) int offsetLayerId() const { return offsetLayerId_; } - // + // number of barrel layer int numBarrelLayer() const { return numBarrelLayer_; } + // number of barrel PS layer + int numBarrelLayerPS() const { return numBarrelLayerPS_; } // total number of outer tracker DTCs int numDTCs() const { return numDTCs_; } // number of DTCs connected to one TFP (48) @@ -398,8 +538,8 @@ namespace tt { // number of bist used for phi0 int tfpWidthPhi0() const { return tfpWidthPhi0_; } - // umber of bist used for inv2R - int tfpWidthInv2R() const { return tfpWidthInv2R_; } + // umber of bist used for invR + int tfpWidthInvR() const { return tfpWidthInvR_; } // number of bist used for cot(theta) int tfpWidthCot() const { return tfpWidthCot_; } // number of bist used for z0 @@ -410,28 +550,23 @@ namespace tt { // Parameter specifying GeometricProcessor // number of phi sectors in a processing nonant used in hough transform - int numSectorsPhi() const { return numSectorsPhi_; } + int gpNumBinsPhiT() const { return gpNumBinsPhiT_; } // number of eta sectors used in hough transform - int numSectorsEta() const { return numSectorsEta_; } + int gpNumBinsZT() const { return gpNumBinsZT_; } // # critical radius defining r-z sector shape in cm double chosenRofZ() const { return chosenRofZ_; } // fifo depth in stub router firmware int gpDepthMemory() const { return gpDepthMemory_; } - // defining r-z sector shape - double boundarieEta(int eta) const { return boundariesEta_.at(eta); } - std::vector boundarieEta() const { return boundariesEta_; } + // + int gpWidthModule() const { return gpWidthModule_; } // phi sector size in rad double baseSector() const { return baseSector_; } - // cut on zT - double maxZT() const { return maxZT_; } - // cut on stub cot theta - double maxCot() const { return maxCot_; } // total number of sectors int numSectors() const { return numSectors_; } - // cot(theta) of given eta sector - double sectorCot(int eta) const { return sectorCots_.at(eta); } // - double neededRangeChiZ() const { return neededRangeChiZ_; } + double maxRphi() const { return maxRphi_; } + // + double maxRz() const { return maxRz_; } // Parameter specifying HoughTransform @@ -444,85 +579,83 @@ namespace tt { // internal fifo depth int htDepthMemory() const { return htDepthMemory_; } - // Parameter specifying MiniHoughTransform + // Parameter specifying Track Builder // number of finer inv2R bins inside HT bin - int mhtNumBinsInv2R() const { return mhtNumBinsInv2R_; } + int ctbNumBinsInv2R() const { return ctbNumBinsInv2R_; } // number of finer phiT bins inside HT bin - int mhtNumBinsPhiT() const { return mhtNumBinsPhiT_; } - // number of dynamic load balancing steps - int mhtNumDLBs() const { return mhtNumDLBs_; } - // number of units per dynamic load balancing step - int mhtNumDLBNodes() const { return mhtNumDLBNodes_; } - // number of inputs per dynamic load balancing unit - int mhtNumDLBChannel() const { return mhtNumDLBChannel_; } + int ctbNumBinsPhiT() const { return ctbNumBinsPhiT_; } + // number of used z0 bins inside GP ZT bin + int ctbNumBinsCot() const { return ctbNumBinsCot_; } + //number of used zT bins inside GP ZT bin + int ctbNumBinsZT() const { return ctbNumBinsZT_; } // required number of stub layers to form a candidate - int mhtMinLayers() const { return mhtMinLayers_; } - // number of mht cells - int mhtNumCells() const { return mhtNumCells_; } - - // Parameter specifying ZHoughTransform - - //number of used zT bins - int zhtNumBinsZT() const { return zhtNumBinsZT_; } - // number of used cot bins - int zhtNumBinsCot() const { return zhtNumBinsCot_; } - // number of stages - int zhtNumStages() const { return zhtNumStages_; } - // required number of stub layers to form a candidate - int zhtMinLayers() const { return zhtMinLayers_; } + int ctbMinLayers() const { return ctbMinLayers_; } // max number of output tracks per node - int zhtMaxTracks() const { return zhtMaxTracks_; } + int ctbMaxTracks() const { return ctbMaxTracks_; } // cut on number of stub per layer for input candidates - int zhtMaxStubsPerLayer() const { return zhtMaxStubsPerLayer_; } - // number of zht cells - int zhtNumCells() const { return zhtNumCells_; } - - // Parameter specifying KalmanFilter Input Formatter - - // power of 2 multiplier of stub phi residual range - int kfinShiftRangePhi() const { return kfinShiftRangePhi_; } - // power of 2 multiplier of stub z residual range - int kfinShiftRangeZ() const { return kfinShiftRangeZ_; } + int ctbMaxStubs() const { return ctbMaxStubs_; } + // internal memory depth + int ctbDepthMemory() const { return ctbDepthMemory_; } // Parameter specifying KalmanFilter + // double precision simulation of 5 parameter fit instead of bit accurate emulation of 4 parameter fit + bool kfUse5ParameterFit() const { return kfUse5ParameterFit_; } + // simulate KF instead of emulate + bool kfUseSimmulation() const { return kfUseSimmulation_; } + // stub residuals and radius are recalculated from seed parameter and TTStub position + bool kfUseTTStubResiduals() const { return kfUseTTStubResiduals_; } + // track parameter are recalculated from seed TTStub positions + bool kfUseTTStubParameters() const { return kfUseTTStubParameters_; } + // + bool kfApplyNonLinearCorrection() const { return kfApplyNonLinearCorrection_; } // number of kf worker int kfNumWorker() const { return kfNumWorker_; } + // max number of tracks a kf worker can process + int kfMaxTracks() const { return kfMaxTracks_; } // required number of stub layers to form a track int kfMinLayers() const { return kfMinLayers_; } + // required number of ps stub layers to form a track + int kfMinLayersPS() const { return kfMinLayersPS_; } // maximum number of layers added to a track int kfMaxLayers() const { return kfMaxLayers_; } + // + int kfMaxGaps() const { return kfMaxGaps_; } + // + int kfMaxSeedingLayer() const { return kfMaxSeedingLayer_; } + // + int kfNumSeedStubs() const { return kfNumSeedStubs_; } + // + double kfMinSeedDeltaR() const { return kfMinSeedDeltaR_; } // search window of each track parameter in initial uncertainties double kfRangeFactor() const { return kfRangeFactor_; } - // + // initial C00 is given by inv2R uncertainty squared times this power of 2 int kfShiftInitialC00() const { return kfShiftInitialC00_; } - // + // initial C11 is given by phiT uncertainty squared times this power of 2 int kfShiftInitialC11() const { return kfShiftInitialC11_; } - // + // initial C22 is given by cot uncertainty squared times this power of 2 int kfShiftInitialC22() const { return kfShiftInitialC22_; } - // + // initial C33 is given by zT uncertainty squared times this power of 2 int kfShiftInitialC33() const { return kfShiftInitialC33_; } - - // Parameter specifying KalmanFilter Output Formatter - // Conversion factor between dphi^2/weight and chi2rphi - int kfoutchi2rphiConv() const { return kfoutchi2rphiConv_; } - // Conversion factor between dz^2/weight and chi2rz - int kfoutchi2rzConv() const { return kfoutchi2rzConv_; } - // Fraction of total dphi and dz ranges to calculate v0 and v1 LUT for - int weightBinFraction() const { return weightBinFraction_; } - // Constant used in FW to prevent 32-bit int overflow - int dzTruncation() const { return dzTruncation_; } - // Constant used in FW to prevent 32-bit int overflow - int dphiTruncation() const { return dphiTruncation_; } + // + int kfShiftChi20() const { return kfShiftChi20_; } + // + int kfShiftChi21() const { return kfShiftChi21_; } + // + double kfCutChi2() const { return kfCutChi2_; } + // + int kfWidthChi2() const { return kfWidthChi2_; } // Parameter specifying DuplicateRemoval // internal memory depth int drDepthMemory() const { return drDepthMemory_; } - //getBendCut - const StubAlgorithmOfficial* stubAlgorithm() const { return stubAlgorithm_; } + // Parameter specifying TrackQuaility + + // number of output channel + int tqNumChannel() const { return tqNumChannel_; } private: // checks consitency between history and current configuration for a specific module @@ -532,10 +665,6 @@ namespace tt { const edm::ParameterSetID&) const; // dumps pSetHistory where incosistent lines with pSetProcess are highlighted std::string dumpDiff(const edm::ParameterSet& pSetHistory, const edm::ParameterSet& pSetProcess) const; - // check if bField is supported - void checkMagneticField(); - // check if geometry is supported - void checkGeometry(); // derive constants void calculateConstants(); // convert configuration of TTStubAlgorithm @@ -553,8 +682,6 @@ namespace tt { // configure TPSelector void configureTPSelector(); - // MagneticField - const MagneticField* magneticField_; // TrackerGeometry const TrackerGeometry* trackerGeometry_; // TrackerTopology @@ -565,59 +692,24 @@ namespace tt { const StubAlgorithmOfficial* stubAlgorithm_; // pSet of ttStub algorithm, used to identify bend window sizes of sensor modules const edm::ParameterSet* pSetSA_; - // pSet of geometry configuration, used to identify if geometry is supported - const edm::ParameterSet* pSetGC_; - // pset id of current TTStubAlgorithm - edm::ParameterSetID pSetIdTTStubAlgorithm_; - // pset id of current geometry configuration - edm::ParameterSetID pSetIdGeometryConfiguration_; - - // DD4hep - bool fromDD4hep_; - - // Parameter to check if configured Tracker Geometry is supported - edm::ParameterSet pSetSG_; - // label of ESProducer/ESSource - std::string sgXMLLabel_; - // compared path - std::string sgXMLPath_; - // compared filen ame - std::string sgXMLFile_; - // list of supported versions - std::vector sgXMLVersions_; - - // Parameter to check if Process History is consistent with process configuration - edm::ParameterSet pSetPH_; - // label of compared GeometryConfiguration - std::string phGeometryConfiguration_; - // label of compared TTStubAlgorithm - std::string phTTStubAlgorithm_; - // Common track finding parameter - edm::ParameterSet pSetTF_; // half lumi region size in cm double beamWindowZ_; - // required number of layers a found track has to have in common with a TP to consider it matched to it - int matchedLayers_; - // required number of ps layers a found track has to have in common with a TP to consider it matched to it - int matchedLayersPS_; - // allowed number of stubs a found track may have not in common with its matched TP - int unMatchedStubs_; - // allowed number of PS stubs a found track may have not in common with its matched TP - int unMatchedStubsPS_; - // scattering term used to add stub phi uncertainty depending on assumed track inv2R - double scattering_; - - // TMTT specific parameter - edm::ParameterSet pSetTMTT_; // cut on stub and TP pt, also defines region overlap shape in GeV double minPt_; + // cut on candidate pt + double minPtCand_; // cut on stub eta double maxEta_; + // in cm, constraints track reconstruction phase space + double maxD0_; // critical radius defining region overlap shape in cm double chosenRofPhi_; // number of detector layers a reconstructbale particle may cross int numLayers_; + // required number of stub layers to form a track + int minLayers_; + // number of bits used for stub r - ChosenRofPhi int tmttWidthR_; // number of bits used for stub phi w.r.t. phi sector centre @@ -625,17 +717,7 @@ namespace tt { // number of bits used for stub z int tmttWidthZ_; - // Hybrid specific parameter - edm::ParameterSet pSetHybrid_; - // cut on stub pt in GeV, also defines region overlap shape - double hybridMinPtStub_; - // cut on andidate pt in GeV - double hybridMinPtCand_; - // cut on stub eta - double hybridMaxEta_; - // critical radius defining region overlap shape in cm - double hybridChosenRofPhi_; - // max number of detector layer connected to one DTC + // max number of layers connected to one DTC int hybridNumLayers_; // number of outer PS rings for disk 1, 2, 3, 4, 5 std::vector hybridNumRingsPS_; @@ -663,34 +745,17 @@ namespace tt { std::vector hybridDisk2SRsSet_; // range of stub phi in rad double hybridRangePhi_; + // biggest barrel stub z position after TrackBuilder in cm + double tbBarrelHalfLength_; // smallest stub radius after TrackBuilder in cm double tbInnerRadius_; // number of bits used for stub r w.r.t layer/disk centre for module types (barrelPS, barrel2S, diskPS, disk2S) after TrackBuilder std::vector tbWidthsR_; - // Parameter specifying TrackingParticle used for Efficiency measurements - edm::ParameterSet pSetTP_; - // pt cut - double tpMinPt_; - // eta cut - double tpMaxEta_; - // cut on vertex pos r in cm - double tpMaxVertR_; - // cut on vertex pos z in cm - double tpMaxVertZ_; - // cut on impact parameter in cm - double tpMaxD0_; - // required number of associated layers to a TP to consider it reconstruct-able - int tpMinLayers_; - // required number of associated ps layers to a TP to consider it reconstruct-able - int tpMinLayersPS_; - // max number of unassociated 2S stubs allowed to still associate TTTrack with TP - int tpMaxBadStubs2S_; - // max number of unassociated PS stubs allowed to still associate TTTrack with TP - int tpMaxBadStubsPS_; - - // Firmware specific Parameter - edm::ParameterSet pSetFW_; + // enable emulation of truncation for TM, DR, KF, TQ and TFP + int enableTruncation_; + // use Hybrid or TMTT as TT algorithm + bool useHybrid_; // width of the 'A' port of an DSP slice int widthDSPa_; // width of the 'A' port of an DSP slice using biased twos complement @@ -718,13 +783,16 @@ namespace tt { // LHC bunch crossing rate in MHz double freqLHC_; // processing Frequency of DTC & TFP in MHz, has to be integer multiple of FreqLHC - double freqBE_; + double freqBEHigh_; + // processing Frequency of DTC & TFP in MHz, has to be integer multiple of FreqLHC + double freqBELow_; // number of events collected in front-end int tmpFE_; // time multiplexed period of track finding processor int tmpTFP_; // speed of light used in FW in e8 m/s double speedOfLight_; + // BField used in fw in T double bField_; // accepted BField difference between FW to EventSetup in T @@ -736,38 +804,40 @@ namespace tt { // half length of outer tracker in cm double halfLength_; // max strip/pixel pitch of outer tracker sensors in cm - double maxPitch_; + double maxPitchRow_; // max strip/pixel length of outer tracker sensors in cm - double maxLength_; + double maxPitchCol_; // approximated tilt correction parameter used to project r to z uncertainty double tiltApproxSlope_; // approximated tilt correction parameter used to project r to z uncertainty double tiltApproxIntercept_; // In tilted barrel, constant assumed stub radial uncertainty * sqrt(12) in cm double tiltUncertaintyR_; - // minimum representable stub phi uncertainty - double mindPhi_; - // maximum representable stub phi uncertainty - double maxdPhi_; - // minimum representable stub z uncertainty - double mindZ_; - // maximum representable stub z uncertainty - double maxdZ_; + // scattering term used to add stub phi uncertainty depending on assumed track inv2R + double scattering_; // strip pitch of outer tracker sensors in cm - double pitch2S_; + double pitchRow2S_; // pixel pitch of outer tracker sensors in cm - double pitchPS_; + double pitchRowPS_; // strip length of outer tracker sensors in cm - double length2S_; + double pitchCol2S_; // pixel length of outer tracker sensors in cm - double lengthPS_; + double pitchColPS_; + // barrel layer limit r value to partition into PS and 2S region + double limitPSBarrel_; + // barrel layer limit r value to partition into tilted and untilted region + std::vector limitsTiltedR_; + // barrel layer limit |z| value to partition into tilted and untilted region + std::vector limitsTiltedZ_; + // endcap disk limit |z| value to partition into PS and 2S region + std::vector limitsPSDiksZ_; + // endcap disk limit r value to partition into PS and 2S region + std::vector limitsPSDiksR_; // barrel layer limit |z| value to partition into tilted and untilted region std::vector tiltedLayerLimitsZ_; // endcap disk limit r value to partition into PS and 2S region std::vector psDiskLimitsR_; - // Parameter specifying front-end - edm::ParameterSet pSetFE_; // number of bits used for internal stub bend int widthBend_; // number of bits used for internal stub column @@ -785,8 +855,6 @@ namespace tt { // used stub bend uncertainty in pitch units double bendCut_; - // Parameter specifying DTC - edm::ParameterSet pSetDTC_; // number of phi slices the outer tracker readout is organized in int numRegions_; // number of regions a reconstructable particles may cross @@ -813,8 +881,10 @@ namespace tt { int offsetLayerDisks_; // offset between 0 and smallest layer id (barrel layer 1) int offsetLayerId_; - // + // number of barrel layer int numBarrelLayer_; + // number of barrel ps layer + int numBarrelLayerPS_; // total number of output channel int dtcNumStreams_; // slot number changing from PS to 2S (default: 6) @@ -822,36 +892,34 @@ namespace tt { // slot number changing from 10 gbps to 5gbps (default: 3) int slotLimit10gbps_; - // Parameter specifying TFP - edm::ParameterSet pSetTFP_; - // number of bist used for phi0 + // number of bits used for phi0 int tfpWidthPhi0_; - // umber of bist used for qOverPt - int tfpWidthInv2R_; - // number of bist used for cot(theta) + // umber of bits used for qOverPt + int tfpWidthInvR_; + // number of bits used for cot(theta) int tfpWidthCot_; - // number of bist used for z0 + // number of bits used for z0 int tfpWidthZ0_; // number of output links int tfpNumChannel_; - // Parameter specifying GeometricProcessor - edm::ParameterSet pSetGP_; // number of phi sectors used in hough transform - int numSectorsPhi_; + int gpNumBinsPhiT_; // number of eta sectors used in hough transform - int numSectorsEta_; + int gpNumBinsZT_; // # critical radius defining r-z sector shape in cm double chosenRofZ_; - // range of stub z residual w.r.t. sector center which needs to be covered - double neededRangeChiZ_; // fifo depth in stub router firmware int gpDepthMemory_; - // defining r-z sector shape - std::vector boundariesEta_; + // + int gpWidthModule_; + // + int gpPosPS_; + // + int gpPosBarrel_; + // + int gpPosTilted_; - // Parameter specifying HoughTransform - edm::ParameterSet pSetHT_; // number of inv2R bins used in hough transform int htNumBinsInv2R_; // number of phiT bins used in hough transform @@ -861,91 +929,80 @@ namespace tt { // internal fifo depth int htDepthMemory_; - // Parameter specifying MiniHoughTransform - edm::ParameterSet pSetMHT_; // number of finer inv2R bins inside HT bin - int mhtNumBinsInv2R_; + int ctbNumBinsInv2R_; // number of finer phiT bins inside HT bin - int mhtNumBinsPhiT_; - // number of dynamic load balancing steps - int mhtNumDLBs_; - // number of units per dynamic load balancing step - int mhtNumDLBNodes_; - // number of inputs per dynamic load balancing unit - int mhtNumDLBChannel_; + int ctbNumBinsPhiT_; + // number of used cot bins inside GP ZT bin + int ctbNumBinsCot_; + //number of used zT bins inside GP ZT bin + int ctbNumBinsZT_; // required number of stub layers to form a candidate - int mhtMinLayers_; - - // Parameter specifying ZHoughTransform - edm::ParameterSet pSetZHT_; - //number of used zT bins - int zhtNumBinsZT_; - // number of used cot bins - int zhtNumBinsCot_; - // number of stages - int zhtNumStages_; - // required number of stub layers to form a candidate - int zhtMinLayers_; + int ctbMinLayers_; // max number of output tracks per node - int zhtMaxTracks_; + int ctbMaxTracks_; // cut on number of stub per layer for input candidates - int zhtMaxStubsPerLayer_; - - // Parameter specifying KalmanFilter Input Formatter - edm::ParameterSet pSetKFin_; - // power of 2 multiplier of stub phi residual range - int kfinShiftRangePhi_; - // power of 2 multiplier of stub z residual range - int kfinShiftRangeZ_; - - // Parameter specifying KalmanFilter - edm::ParameterSet pSetKF_; + int ctbMaxStubs_; + // internal memory depth + int ctbDepthMemory_; + + // double precision simulation of 5 parameter fit instead of bit accurate emulation of 4 parameter fit + bool kfUse5ParameterFit_; + // simulate KF instead of emulate + bool kfUseSimmulation_; + // stub residuals and radius are recalculated from seed parameter and TTStub position + bool kfUseTTStubResiduals_; + // track parameter are recalculated from seed TTStub positions + bool kfUseTTStubParameters_; + // + bool kfApplyNonLinearCorrection_; // number of kf worker int kfNumWorker_; + // max number of tracks a kf worker can process + int kfMaxTracks_; // required number of stub layers to form a track int kfMinLayers_; + // required number of ps stub layers to form a track + int kfMinLayersPS_; // maximum number of layers added to a track int kfMaxLayers_; + // + int kfMaxGaps_; + // + int kfMaxSeedingLayer_; + // + int kfNumSeedStubs_; + // + double kfMinSeedDeltaR_; // search window of each track parameter in initial uncertainties double kfRangeFactor_; - // + // initial C00 is given by inv2R uncertainty squared times this power of 2 int kfShiftInitialC00_; - // + // initial C11 is given by phiT uncertainty squared times this power of 2 int kfShiftInitialC11_; - // + // initial C22 is given by cot uncertainty squared times this power of 2 int kfShiftInitialC22_; - // + // initial C33 is given by zT uncertainty squared times this power of 2 int kfShiftInitialC33_; + // + int kfShiftChi20_; + // + int kfShiftChi21_; + // + double kfCutChi2_; + // + int kfWidthChi2_; - // Parameter specifying KalmanFilter Output Formatter - edm::ParameterSet pSetKFOut_; - // Conversion factor between dphi^2/weight and chi2rphi - int kfoutchi2rphiConv_; - // Conversion factor between dz^2/weight and chi2rz - int kfoutchi2rzConv_; - // Fraction of total dphi and dz ranges to calculate v0 and v1 LUT for - int weightBinFraction_; - // Constant used in FW to prevent 32-bit int overflow - int dzTruncation_; - // Constant used in FW to prevent 32-bit int overflow - int dphiTruncation_; - - // Parameter specifying DuplicateRemoval - edm::ParameterSet pSetDR_; // internal memory depth int drDepthMemory_; + // number of output channel + int tqNumChannel_; + // // Derived constants // - // true if tracker geometry and magnetic field supported - bool configurationSupported_; - // selector to partly select TPs for efficiency measurements - TrackingParticleSelector tpSelector_; - // selector to partly select TPs for fake and duplicate rate measurements - TrackingParticleSelector tpSelectorLoose_; - // TTStubAlgorithm // number of tilted layer rings per barrel layer @@ -962,15 +1019,21 @@ namespace tt { // common Track finding // number of frames betwen 2 resets of 18 BX packets - int numFrames_; + int numFramesHigh_; + // number of frames betwen 2 resets of 18 BX packets + int numFramesLow_; + // number of valid frames per 18 BX packet + int numFramesIOHigh_; // number of valid frames per 18 BX packet - int numFramesIO_; + int numFramesIOLow_; // number of valid frames per 8 BX packet int numFramesFE_; // converts GeV in 1/cm double invPtToDphi_; // region size in rad double baseRegion_; + // max cot(theta) of found tracks + double maxCot_; // TMTT @@ -1055,30 +1118,28 @@ namespace tt { // phi sector size in rad double baseSector_; - // cut on zT - double maxZT_; - // cut on stub cot theta - double maxCot_; + // + double maxRphi_; + // + double maxRz_; // total number of sectors int numSectors_; - // number of unused bits in GP output format - int gpNumUnusedBits_; - // cot(theta) of eta sectors - std::vector sectorCots_; - - // MHT - - // number of mht cells - int mhtNumCells_; - // ZHT + // CTB - // number of zht cells - int zhtNumCells_; + // number of bits used to count stubs per layer + int ctbWidthLayerCount_; - // KF + // KFout - int kfWidthLayerCount_; + // Bins used to digitize dPhi for chi2 calculation + std::vector kfoutdPhiBins_; + // Bins used to digitize dZ for chi2 calculation + std::vector kfoutdZBins_; + // v0 weight Bins corresponding to dPhi Bins for chi2 calculation + std::vector kfoutv0Bins_; + // v1 weight Bins corresponding to dZ Bins for chi2 calculation + std::vector kfoutv1Bins_; }; } // namespace tt diff --git a/L1Trigger/TrackTrigger/interface/SetupRcd.h b/L1Trigger/TrackTrigger/interface/SetupRcd.h index a354a41e122c2..58ea67f941a38 100644 --- a/L1Trigger/TrackTrigger/interface/SetupRcd.h +++ b/L1Trigger/TrackTrigger/interface/SetupRcd.h @@ -1,11 +1,9 @@ -#ifndef L1Trigger_TrackerDTC_SetupRcd_h -#define L1Trigger_TrackerDTC_SetupRcd_h +#ifndef L1Trigger_TrackTrigger_SetupRcd_h +#define L1Trigger_TrackTrigger_SetupRcd_h #include "FWCore/Framework/interface/DependentRecordImplementation.h" -#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h" -#include "Geometry/Records/interface/IdealGeometryRecord.h" #include "DataFormats/TrackerCommon/interface/TrackerTopology.h" #include "CondFormats/DataRecord/interface/TrackerDetToDTCELinkCablingMapRcd.h" #include "L1Trigger/TrackTrigger/interface/TTStubAlgorithmRecord.h" @@ -14,16 +12,12 @@ namespace tt { - typedef edm::mpl::Vector - Rcds; + typedef edm::mpl:: + Vector + SetupDepRcds; // record of tt::Setup - class SetupRcd : public edm::eventsetup::DependentRecordImplementation {}; + class SetupRcd : public edm::eventsetup::DependentRecordImplementation {}; } // namespace tt diff --git a/L1Trigger/TrackTrigger/plugins/ProducerSetup.cc b/L1Trigger/TrackTrigger/plugins/ProducerSetup.cc index 51c053df55416..b465201d5715b 100644 --- a/L1Trigger/TrackTrigger/plugins/ProducerSetup.cc +++ b/L1Trigger/TrackTrigger/plugins/ProducerSetup.cc @@ -1,16 +1,12 @@ #include "FWCore/Framework/interface/ESProducer.h" +#include "FWCore/Framework/interface/ModuleFactory.h" #include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/Utilities/interface/ESGetToken.h" -#include "FWCore/Utilities/interface/ESInputTag.h" -#include "DataFormats/Provenance/interface/ParameterSetID.h" #include "L1Trigger/TrackTrigger/interface/Setup.h" #include -using namespace std; -using namespace edm; - namespace tt { /*! \class tt::ProducerSetup @@ -18,78 +14,187 @@ namespace tt { * \author Thomas Schuh * \date 2020, Apr */ - class ProducerSetup : public ESProducer { + class ProducerSetup : public edm::ESProducer { public: - ProducerSetup(const ParameterSet& iConfig); + ProducerSetup(const edm::ParameterSet& iConfig); ~ProducerSetup() override {} - unique_ptr produce(const SetupRcd& setupRcd); + std::unique_ptr produce(const SetupRcd& setupRcd); private: - const ParameterSet iConfig_; - ESGetToken getTokenTTStubAlgorithm_; - ESGetToken getTokenMagneticField_; - ESGetToken getTokenTrackerGeometry_; - ESGetToken getTokenTrackerTopology_; - ESGetToken getTokenCablingMap_; - ESGetToken getTokenGeometryConfiguration_; - ESGetToken getTokenGeometryConfigurationDD4hep_; - bool fromDD4hep_; + Setup::Config iConfig_; + edm::ESGetToken getTokenTrackerGeometry_; + edm::ESGetToken getTokenTrackerTopology_; + edm::ESGetToken getTokenCablingMap_; + edm::ESGetToken getTokenTTStubAlgorithm_; }; - ProducerSetup::ProducerSetup(const ParameterSet& iConfig) : iConfig_(iConfig) { - fromDD4hep_ = iConfig.getParameter("fromDD4hep"); + ProducerSetup::ProducerSetup(const edm::ParameterSet& iConfig) { auto cc = setWhatProduced(this); - getTokenTTStubAlgorithm_ = cc.consumes(); - getTokenMagneticField_ = cc.consumes(); getTokenTrackerGeometry_ = cc.consumes(); getTokenTrackerTopology_ = cc.consumes(); getTokenCablingMap_ = cc.consumes(); - if (fromDD4hep_) - getTokenGeometryConfigurationDD4hep_ = cc.consumes(); - else - getTokenGeometryConfiguration_ = cc.consumes(); + getTokenTTStubAlgorithm_ = cc.consumes(); + const edm::ParameterSet& pSetTF = iConfig.getParameter("TrackFinding"); + iConfig_.beamWindowZ_ = pSetTF.getParameter("BeamWindowZ"); + iConfig_.minPt_ = pSetTF.getParameter("MinPt"); + iConfig_.minPtCand_ = pSetTF.getParameter("MinPtCand"); + iConfig_.maxEta_ = pSetTF.getParameter("MaxEta"); + iConfig_.maxD0_ = pSetTF.getParameter("MaxD0"); + iConfig_.chosenRofPhi_ = pSetTF.getParameter("ChosenRofPhi"); + iConfig_.numLayers_ = pSetTF.getParameter("NumLayers"); + iConfig_.minLayers_ = pSetTF.getParameter("MinLayers"); + const edm::ParameterSet& pSetTMTT = iConfig.getParameter("TMTT"); + iConfig_.tmttWidthR_ = pSetTMTT.getParameter("WidthR"); + iConfig_.tmttWidthPhi_ = pSetTMTT.getParameter("WidthPhi"); + iConfig_.tmttWidthZ_ = pSetTMTT.getParameter("WidthZ"); + const edm::ParameterSet& pSetHybrid = iConfig.getParameter("Hybrid"); + iConfig_.hybridNumLayers_ = pSetHybrid.getParameter("NumLayers"); + iConfig_.hybridNumRingsPS_ = pSetHybrid.getParameter>("NumRingsPS"); + iConfig_.hybridWidthsR_ = pSetHybrid.getParameter>("WidthsR"); + iConfig_.hybridWidthsZ_ = pSetHybrid.getParameter>("WidthsZ"); + iConfig_.hybridWidthsPhi_ = pSetHybrid.getParameter>("WidthsPhi"); + iConfig_.hybridWidthsAlpha_ = pSetHybrid.getParameter>("WidthsAlpha"); + iConfig_.hybridWidthsBend_ = pSetHybrid.getParameter>("WidthsBend"); + iConfig_.hybridRangesR_ = pSetHybrid.getParameter>("RangesR"); + iConfig_.hybridRangesZ_ = pSetHybrid.getParameter>("RangesZ"); + iConfig_.hybridRangesAlpha_ = pSetHybrid.getParameter>("RangesAlpha"); + iConfig_.hybridLayerRs_ = pSetHybrid.getParameter>("LayerRs"); + iConfig_.hybridDiskZs_ = pSetHybrid.getParameter>("DiskZs"); + iConfig_.hybridDisk2SRsSet_ = pSetHybrid.getParameter>("Disk2SRsSet"); + iConfig_.tbBarrelHalfLength_ = pSetHybrid.getParameter("BarrelHalfLength"); + iConfig_.tbInnerRadius_ = pSetHybrid.getParameter("InnerRadius"); + iConfig_.tbWidthsR_ = pSetHybrid.getParameter>("WidthsRTB"); + const edm::ParameterSet& pSetFW = iConfig.getParameter("Firmware"); + iConfig_.enableTruncation_ = pSetFW.getParameter("EnableTruncation"); + iConfig_.widthDSPa_ = pSetFW.getParameter("WidthDSPa"); + iConfig_.widthDSPb_ = pSetFW.getParameter("WidthDSPb"); + iConfig_.widthDSPc_ = pSetFW.getParameter("WidthDSPc"); + iConfig_.widthAddrBRAM36_ = pSetFW.getParameter("WidthAddrBRAM36"); + iConfig_.widthAddrBRAM18_ = pSetFW.getParameter("WidthAddrBRAM18"); + iConfig_.numFramesInfra_ = pSetFW.getParameter("NumFramesInfra"); + iConfig_.freqLHC_ = pSetFW.getParameter("FreqLHC"); + iConfig_.freqBEHigh_ = pSetFW.getParameter("FreqBEHigh"); + iConfig_.freqBELow_ = pSetFW.getParameter("FreqBELow"); + iConfig_.tmpFE_ = pSetFW.getParameter("TMP_FE"); + iConfig_.tmpTFP_ = pSetFW.getParameter("TMP_TFP"); + iConfig_.speedOfLight_ = pSetFW.getParameter("SpeedOfLight"); + const edm::ParameterSet& pSetOT = iConfig.getParameter("Tracker"); + iConfig_.bField_ = pSetOT.getParameter("BField"); + iConfig_.bFieldError_ = pSetOT.getParameter("BFieldError"); + iConfig_.outerRadius_ = pSetOT.getParameter("OuterRadius"); + iConfig_.innerRadius_ = pSetOT.getParameter("InnerRadius"); + iConfig_.halfLength_ = pSetOT.getParameter("HalfLength"); + iConfig_.tiltApproxSlope_ = pSetOT.getParameter("TiltApproxSlope"); + iConfig_.tiltApproxIntercept_ = pSetOT.getParameter("TiltApproxIntercept"); + iConfig_.tiltUncertaintyR_ = pSetOT.getParameter("TiltUncertaintyR"); + iConfig_.scattering_ = pSetOT.getParameter("Scattering"); + iConfig_.pitchRow2S_ = pSetOT.getParameter("PitchRow2S"); + iConfig_.pitchRowPS_ = pSetOT.getParameter("PitchRowPS"); + iConfig_.pitchCol2S_ = pSetOT.getParameter("PitchCol2S"); + iConfig_.pitchColPS_ = pSetOT.getParameter("PitchColPS"); + iConfig_.limitPSBarrel_ = pSetOT.getParameter("LimitPSBarrel"); + iConfig_.limitsTiltedR_ = pSetOT.getParameter>("LimitsTiltedR"); + iConfig_.limitsTiltedZ_ = pSetOT.getParameter>("LimitsTiltedZ"); + iConfig_.limitsPSDiksZ_ = pSetOT.getParameter>("LimitsPSDiksZ"); + iConfig_.limitsPSDiksR_ = pSetOT.getParameter>("LimitsPSDiksR"); + iConfig_.tiltedLayerLimitsZ_ = pSetOT.getParameter>("TiltedLayerLimitsZ"); + iConfig_.psDiskLimitsR_ = pSetOT.getParameter>("PSDiskLimitsR"); + const edm::ParameterSet& pSetFE = iConfig.getParameter("FrontEnd"); + iConfig_.widthBend_ = pSetFE.getParameter("WidthBend"); + iConfig_.widthCol_ = pSetFE.getParameter("WidthCol"); + iConfig_.widthRow_ = pSetFE.getParameter("WidthRow"); + iConfig_.baseBend_ = pSetFE.getParameter("BaseBend"); + iConfig_.baseCol_ = pSetFE.getParameter("BaseCol"); + iConfig_.baseRow_ = pSetFE.getParameter("BaseRow"); + iConfig_.baseWindowSize_ = pSetFE.getParameter("BaseWindowSize"); + iConfig_.bendCut_ = pSetFE.getParameter("BendCut"); + const edm::ParameterSet& pSetDTC = iConfig.getParameter("DTC"); + iConfig_.numRegions_ = pSetDTC.getParameter("NumRegions"); + iConfig_.numOverlappingRegions_ = pSetDTC.getParameter("NumOverlappingRegions"); + iConfig_.numATCASlots_ = pSetDTC.getParameter("NumATCASlots"); + iConfig_.numDTCsPerRegion_ = pSetDTC.getParameter("NumDTCsPerRegion"); + iConfig_.numModulesPerDTC_ = pSetDTC.getParameter("NumModulesPerDTC"); + iConfig_.dtcNumRoutingBlocks_ = pSetDTC.getParameter("NumRoutingBlocks"); + iConfig_.dtcDepthMemory_ = pSetDTC.getParameter("DepthMemory"); + iConfig_.dtcWidthRowLUT_ = pSetDTC.getParameter("WidthRowLUT"); + iConfig_.dtcWidthInv2R_ = pSetDTC.getParameter("WidthInv2R"); + iConfig_.offsetDetIdDSV_ = pSetDTC.getParameter("OffsetDetIdDSV"); + iConfig_.offsetDetIdTP_ = pSetDTC.getParameter("OffsetDetIdTP"); + iConfig_.offsetLayerDisks_ = pSetDTC.getParameter("OffsetLayerDisks"); + iConfig_.offsetLayerId_ = pSetDTC.getParameter("OffsetLayerId"); + iConfig_.numBarrelLayer_ = pSetDTC.getParameter("NumBarrelLayer"); + iConfig_.numBarrelLayerPS_ = pSetDTC.getParameter("NumBarrelLayerPS"); + iConfig_.slotLimitPS_ = pSetDTC.getParameter("SlotLimitPS"); + iConfig_.slotLimit10gbps_ = pSetDTC.getParameter("SlotLimit10gbps"); + const edm::ParameterSet& pSetTFP = iConfig.getParameter("TFP"); + iConfig_.tfpWidthPhi0_ = pSetTFP.getParameter("WidthPhi0"); + iConfig_.tfpWidthInvR_ = pSetTFP.getParameter("WidthInvR"); + iConfig_.tfpWidthCot_ = pSetTFP.getParameter("WidthCot"); + iConfig_.tfpWidthZ0_ = pSetTFP.getParameter("WidthZ0"); + iConfig_.tfpNumChannel_ = pSetTFP.getParameter("NumChannel"); + const edm::ParameterSet& pSetGP = iConfig.getParameter("GeometricProcessor"); + iConfig_.gpNumBinsPhiT_ = pSetGP.getParameter("NumBinsPhiT"); + iConfig_.gpNumBinsZT_ = pSetGP.getParameter("NumBinsZT"); + iConfig_.chosenRofZ_ = pSetGP.getParameter("ChosenRofZ"); + iConfig_.gpDepthMemory_ = pSetGP.getParameter("DepthMemory"); + iConfig_.gpWidthModule_ = pSetGP.getParameter("WidthModule"); + iConfig_.gpPosPS_ = pSetGP.getParameter("PosPS"); + iConfig_.gpPosBarrel_ = pSetGP.getParameter("PosBarrel"); + iConfig_.gpPosTilted_ = pSetGP.getParameter("PosTilted"); + const edm::ParameterSet& pSetHT = iConfig.getParameter("HoughTransform"); + iConfig_.htNumBinsInv2R_ = pSetHT.getParameter("NumBinsInv2R"); + iConfig_.htNumBinsPhiT_ = pSetHT.getParameter("NumBinsPhiT"); + iConfig_.htMinLayers_ = pSetHT.getParameter("MinLayers"); + iConfig_.htDepthMemory_ = pSetHT.getParameter("DepthMemory"); + const edm::ParameterSet& pSetCTB = iConfig.getParameter("CleanTrackBuilder"); + iConfig_.ctbNumBinsInv2R_ = pSetCTB.getParameter("NumBinsInv2R"); + iConfig_.ctbNumBinsPhiT_ = pSetCTB.getParameter("NumBinsPhiT"); + iConfig_.ctbNumBinsCot_ = pSetCTB.getParameter("NumBinsCot"); + iConfig_.ctbNumBinsZT_ = pSetCTB.getParameter("NumBinsZT"); + iConfig_.ctbMinLayers_ = pSetCTB.getParameter("MinLayers"); + iConfig_.ctbMaxTracks_ = pSetCTB.getParameter("MaxTracks"); + iConfig_.ctbMaxStubs_ = pSetCTB.getParameter("MaxStubs"); + iConfig_.ctbDepthMemory_ = pSetCTB.getParameter("DepthMemory"); + const edm::ParameterSet& pSetKF = iConfig.getParameter("KalmanFilter"); + iConfig_.kfUse5ParameterFit_ = pSetKF.getParameter("Use5ParameterFit"); + iConfig_.kfUseSimmulation_ = pSetKF.getParameter("UseSimmulation"); + iConfig_.kfUseTTStubResiduals_ = pSetKF.getParameter("UseTTStubResiduals"); + iConfig_.kfUseTTStubParameters_ = pSetKF.getParameter("UseTTStubParameters"); + iConfig_.kfApplyNonLinearCorrection_ = pSetKF.getParameter("ApplyNonLinearCorrection"); + iConfig_.kfNumWorker_ = pSetKF.getParameter("NumWorker"); + iConfig_.kfMaxTracks_ = pSetKF.getParameter("MaxTracks"); + iConfig_.kfMinLayers_ = pSetKF.getParameter("MinLayers"); + iConfig_.kfMinLayersPS_ = pSetKF.getParameter("MinLayersPS"); + iConfig_.kfMaxLayers_ = pSetKF.getParameter("MaxLayers"); + iConfig_.kfMaxGaps_ = pSetKF.getParameter("MaxGaps"); + iConfig_.kfMaxSeedingLayer_ = pSetKF.getParameter("MaxSeedingLayer"); + iConfig_.kfNumSeedStubs_ = pSetKF.getParameter("NumSeedStubs"); + iConfig_.kfMinSeedDeltaR_ = pSetKF.getParameter("MinSeedDeltaR"); + iConfig_.kfRangeFactor_ = pSetKF.getParameter("RangeFactor"); + iConfig_.kfShiftInitialC00_ = pSetKF.getParameter("ShiftInitialC00"); + iConfig_.kfShiftInitialC11_ = pSetKF.getParameter("ShiftInitialC11"); + iConfig_.kfShiftInitialC22_ = pSetKF.getParameter("ShiftInitialC22"); + iConfig_.kfShiftInitialC33_ = pSetKF.getParameter("ShiftInitialC33"); + iConfig_.kfShiftChi20_ = pSetKF.getParameter("ShiftChi20"); + iConfig_.kfShiftChi21_ = pSetKF.getParameter("ShiftChi21"); + iConfig_.kfCutChi2_ = pSetKF.getParameter("CutChi2"); + iConfig_.kfWidthChi2_ = pSetKF.getParameter("WidthChi2"); + const edm::ParameterSet& pSetDR = iConfig.getParameter("DuplicateRemoval"); + iConfig_.drDepthMemory_ = pSetDR.getParameter("DepthMemory"); + const edm::ParameterSet& pSetTQ = iConfig.getParameter("TrackQuality"); + iConfig_.tqNumChannel_ = pSetTQ.getParameter("NumChannel"); } - unique_ptr ProducerSetup::produce(const SetupRcd& setupRcd) { - const MagneticField& magneticField = setupRcd.get(getTokenMagneticField_); + std::unique_ptr ProducerSetup::produce(const SetupRcd& setupRcd) { const TrackerGeometry& trackerGeometry = setupRcd.get(getTokenTrackerGeometry_); const TrackerTopology& trackerTopology = setupRcd.get(getTokenTrackerTopology_); const TrackerDetToDTCELinkCablingMap& cablingMap = setupRcd.get(getTokenCablingMap_); - const ESHandle handleStubAlgorithm = setupRcd.getHandle(getTokenTTStubAlgorithm_); - const ParameterSetID& pSetIdTTStubAlgorithm = handleStubAlgorithm.description()->pid_; + const edm::ESHandle handleStubAlgorithm = setupRcd.getHandle(getTokenTTStubAlgorithm_); const StubAlgorithmOfficial& stubAlgoritm = *dynamic_cast(&setupRcd.get(getTokenTTStubAlgorithm_)); - const ParameterSet& pSetStubAlgorithm = getParameterSet(handleStubAlgorithm.description()->pid_); - if (fromDD4hep_) { - const ESHandle handleGeometryConfiguration = - setupRcd.getHandle(getTokenGeometryConfigurationDD4hep_); - const ParameterSetID& pSetIdGeometryConfiguration = handleGeometryConfiguration.description()->pid_; - const ParameterSet& pSetGeometryConfiguration = getParameterSet(handleGeometryConfiguration.description()->pid_); - return make_unique(iConfig_, - magneticField, - trackerGeometry, - trackerTopology, - cablingMap, - stubAlgoritm, - pSetStubAlgorithm, - pSetGeometryConfiguration, - pSetIdTTStubAlgorithm, - pSetIdGeometryConfiguration); - } else { - const ESHandle handleGeometryConfiguration = setupRcd.getHandle(getTokenGeometryConfiguration_); - const ParameterSetID& pSetIdGeometryConfiguration = handleGeometryConfiguration.description()->pid_; - const ParameterSet& pSetGeometryConfiguration = getParameterSet(handleGeometryConfiguration.description()->pid_); - return make_unique(iConfig_, - magneticField, - trackerGeometry, - trackerTopology, - cablingMap, - stubAlgoritm, - pSetStubAlgorithm, - pSetGeometryConfiguration, - pSetIdTTStubAlgorithm, - pSetIdGeometryConfiguration); - } + const edm::ParameterSet& pSetStubAlgorithm = getParameterSet(handleStubAlgorithm.description()->pid_); + return std::make_unique( + iConfig_, trackerGeometry, trackerTopology, cablingMap, stubAlgoritm, pSetStubAlgorithm); } } // namespace tt diff --git a/L1Trigger/TrackTrigger/python/ProducerSetup_cff.py b/L1Trigger/TrackTrigger/python/ProducerSetup_cff.py deleted file mode 100644 index 1bb2fc46f0693..0000000000000 --- a/L1Trigger/TrackTrigger/python/ProducerSetup_cff.py +++ /dev/null @@ -1,14 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -from Configuration.ProcessModifiers.dd4hep_cff import dd4hep -from L1Trigger.TrackTrigger.ProducerSetup_cfi import TrackTrigger_params - -dd4hep.toModify(TrackTrigger_params, - fromDD4hep = cms.bool(True), - ProcessHistory = cms.PSet ( - GeometryConfiguration = cms.string("DDDetectorESProducer@"), - TTStubAlgorithm = cms.string("TTStubAlgorithm_official_Phase2TrackerDigi_@") - ) -) - -TrackTriggerSetup = cms.ESProducer("tt::ProducerSetup", TrackTrigger_params) diff --git a/L1Trigger/TrackTrigger/python/ProducerSetup_cfi.py b/L1Trigger/TrackTrigger/python/ProducerSetup_cfi.py deleted file mode 100644 index 333c47a2770d6..0000000000000 --- a/L1Trigger/TrackTrigger/python/ProducerSetup_cfi.py +++ /dev/null @@ -1,230 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -TrackTrigger_params = cms.PSet ( - - fromDD4hep = cms.bool(False), - - # Parameter to check if configured Tracker Geometry is supported - # this refers to files included by Configuration/Geometry/python/GeometryExtended*_cff.py - UnSupportedGeometry = cms.PSet ( - XMLLabel = cms.string ("geomXMLFiles" ), # label of ESProducer/ESSource - XMLPath = cms.string ("Geometry/TrackerCommonData/data/PhaseII/" ), # compared path - XMLFile = cms.string ("tracker.xml" ), # compared filen ame - XMLVersions = cms.vstring() # list of unsupported versions - ), - - # Parameter to check if Process History is consistent with process configuration - ProcessHistory = cms.PSet ( - GeometryConfiguration = cms.string( "XMLIdealGeometryESSource@" ), # label of compared GeometryConfiguration - TTStubAlgorithm = cms.string( "TTStubAlgorithm_official_Phase2TrackerDigi_@" ) # label of compared TTStubAlgorithm - ), - - # Common track finding parameter - TrackFinding = cms.PSet ( - BeamWindowZ = cms.double( 15. ), # half lumi region size in cm - MatchedLayers = cms.int32 ( 4 ), # required number of layers a found track has to have in common with a TP to consider it matched to it - MatchedLayersPS = cms.int32 ( 0 ), # required number of ps layers a found track has to have in common with a TP to consider it matched to it - UnMatchedStubs = cms.int32 ( 1 ), # allowed number of stubs a found track may have not in common with its matched TP - UnMatchedStubsPS = cms.int32 ( 0 ), # allowed number of PS stubs a found track may have not in common with its matched TP - Scattering = cms.double( 0.131283 ) # additional radial uncertainty in cm used to calculate stub phi residual uncertainty to take multiple scattering into account - ), - - # TMTT specific parameter - TMTT = cms.PSet ( - MinPt = cms.double( 3. ), # cut on stub in GeV, also defines region overlap shape - MaxEta = cms.double( 2.4 ), # cut on stub eta - ChosenRofPhi = cms.double( 67.24 ), # critical radius defining region overlap shape in cm - NumLayers = cms.int32 ( 7 ), # number of detector layers a reconstructbale particle may cross, reduced to 7, 8th layer almost never corssed - WidthR = cms.int32 ( 12 ), # number of bits used for stub r - ChosenRofPhi - WidthPhi = cms.int32 ( 15 ), # number of bits used for stub phi w.r.t. phi region centre - WidthZ = cms.int32 ( 14 ) # number of bits used for stub z - ), - - # Hybrid specific parameter - Hybrid = cms.PSet ( - MinPtStub = cms.double( 2.0 ), # cut on stub pt in GeV, also defines region overlap shape - MinPtCand = cms.double( 1.34 ), # cut on candidate pt in GeV - MaxEta = cms.double( 2.5 ), # cut on stub eta - ChosenRofPhi = cms.double( 55. ), # critical radius defining region overlap shape in cm - NumLayers = cms.int32 ( 4 ), # max number of detector layer connected to one DTC - NumRingsPS = cms.vint32 ( 11, 11, 8, 8, 8 ), # number of outer PS rings for disk 1, 2, 3, 4, 5 - WidthsR = cms.vint32 ( 7, 7, 12, 7 ), # number of bits used for stub r w.r.t layer/disk centre for module types (barrelPS, barrel2S, diskPS, disk2S) - WidthsZ = cms.vint32 ( 12, 8, 7, 7 ), # number of bits used for stub z w.r.t layer/disk centre for module types (barrelPS, barrel2S, diskPS, disk2S) - WidthsPhi = cms.vint32 ( 14, 17, 14, 14 ), # number of bits used for stub phi w.r.t. region centre for module types (barrelPS, barrel2S, diskPS, disk2S) - WidthsAlpha = cms.vint32 ( 0, 0, 0, 4 ), # number of bits used for stub row number for module types (barrelPS, barrel2S, diskPS, disk2S) - WidthsBend = cms.vint32 ( 3, 4, 3, 4 ), # number of bits used for stub bend number for module types (barrelPS, barrel2S, diskPS, disk2S) - RangesR = cms.vdouble( 7.5, 7.5, 120. , 0. ), # range in stub r which needs to be covered for module types (barrelPS, barrel2S, diskPS, disk2S) - RangesZ = cms.vdouble( 240., 240., 7.5, 7.5 ), # range in stub z which needs to be covered for module types (barrelPS, barrel2S, diskPS, disk2S) - RangesAlpha = cms.vdouble( 0., 0., 0., 2048. ), # range in stub row which needs to be covered for module types (barrelPS, barrel2S, diskPS, disk2S) - LayerRs = cms.vdouble( 24.9316, 37.1777, 52.2656, 68.7598, 86.0156, 108.3105 ), # mean radius of outer tracker barrel layer - DiskZs = cms.vdouble( 131.1914, 154.9805, 185.3320, 221.6016, 265.0195 ), # mean z of outer tracker endcap disks - Disk2SRsSet = cms.VPSet( # center radius of outer tracker endcap 2S diks strips - cms.PSet( Disk2SRs = cms.vdouble( 66.4391, 71.4391, 76.2750, 81.2750, 82.9550, 87.9550, 93.8150, 98.8150, 99.8160, 104.8160 ) ), # disk 1 - cms.PSet( Disk2SRs = cms.vdouble( 66.4391, 71.4391, 76.2750, 81.2750, 82.9550, 87.9550, 93.8150, 98.8150, 99.8160, 104.8160 ) ), # disk 2 - cms.PSet( Disk2SRs = cms.vdouble( 63.9903, 68.9903, 74.2750, 79.2750, 81.9562, 86.9562, 92.4920, 97.4920, 99.8160, 104.8160 ) ), # disk 3 - cms.PSet( Disk2SRs = cms.vdouble( 63.9903, 68.9903, 74.2750, 79.2750, 81.9562, 86.9562, 92.4920, 97.4920, 99.8160, 104.8160 ) ), # disk 4 - cms.PSet( Disk2SRs = cms.vdouble( 63.9903, 68.9903, 74.2750, 79.2750, 81.9562, 86.9562, 92.4920, 97.4920, 99.8160, 104.8160 ) ) # disk 5 - ), - InnerRadius = cms.double( 19.6 ), # smallest stub radius after TrackBuilder in cm - WidthsRTB = cms.vint32 ( 7, 7, 12, 12 ), # number of bits used for stub r w.r.t layer/disk centre for module types (barrelPS, barrel2S, diskPS, disk2S) at TB output - ), - - # Parameter specifying TrackingParticle used for Efficiency measurements - TrackingParticle = cms.PSet ( - MinPt = cms.double( 2. ), # pt cut in GeV - MaxEta = cms.double( 2.4 ), # eta cut - MaxVertR = cms.double( 1. ), # cut on vertex pos r in cm - MaxVertZ = cms.double( 30. ), # cut on vertex pos z in cm - MaxD0 = cms.double( 5. ), # cut on impact parameter in cm - MinLayers = cms.int32 ( 4 ), # required number of associated layers to a TP to consider it reconstruct-able and to match it with TTTrack - MinLayersPS = cms.int32 ( 0 ), # required number of associated ps layers to a TP to consider it reconstruct-able - MaxBadStubs2S = cms.int32 ( 1 ), # max number of unassociated 2S stubs allowed to still associate TTTrack with TP - MaxBadStubsPS = cms.int32 ( 0 ) # max number of unassociated PS stubs allowed to still associate TTTrack with TP - ), - - # Fimrware specific Parameter - Firmware = cms.PSet ( - WidthDSPa = cms.int32( 27 ), # width of the 'A' port of an DSP slice - WidthDSPb = cms.int32( 18 ), # width of the 'B' port of an DSP slice - WidthDSPc = cms.int32( 48 ), # width of the 'C' port of an DSP slice - WidthAddrBRAM36 = cms.int32( 9 ), # smallest address width of an BRAM36 configured as broadest simple dual port memory - WidthAddrBRAM18 = cms.int32( 10 ), # smallest address width of an BRAM18 configured as broadest simple dual port memory - NumFramesInfra = cms.int32 ( 6 ), # needed gap between events of emp-infrastructure firmware - FreqLHC = cms.double( 40. ), # LHC bunch crossing rate in MHz - FreqBE = cms.double( 360. ), # processing Frequency of DTC, KF & TFP in MHz, has to be integer multiple of FreqLHC - TMP_FE = cms.int32 ( 8 ), # number of events collected in front-end - TMP_TFP = cms.int32 ( 18 ), # time multiplexed period of track finding processor - SpeedOfLight = cms.double( 2.99792458 ), # in e8 m/s - BField = cms.double( 3.81120228767395 ), # in T - BFieldError = cms.double( 1.e-6 ), # accepted difference to EventSetup in T - OuterRadius = cms.double( 112.7 ), # outer radius of outer tracker in cm - InnerRadius = cms.double( 21.8 ), # inner radius of outer tracker in cm - HalfLength = cms.double( 270. ), # half length of outer tracker in cm - TiltApproxSlope = cms.double( 0.884 ), # In tilted barrel, grad*|z|/r + int approximates |cosTilt| + |sinTilt * cotTheta| - TiltApproxIntercept = cms.double( 0.507 ), # In tilted barrel, grad*|z|/r + int approximates |cosTilt| + |sinTilt * cotTheta| - TiltUncertaintyR = cms.double( 0.12 ), # In tilted barrel, constant assumed stub radial uncertainty * sqrt(12) in cm - MindPhi = cms.double( 0.0001 ), # minimum representable stub phi uncertainty * sqrt(12) + additional terms in rad - MaxdPhi = cms.double( 0.02 ), # maximum representable stub phi uncertainty * sqrt(12) + additional terms in rad - MindZ = cms.double( 0.1 ), # minimum representable stub z uncertainty * sqrt(12) + additional terms in cm - MaxdZ = cms.double( 30. ), # maximum representable stub z uncertainty * sqrt(12) + additional terms in cm - Pitch2S = cms.double( 0.009 ), # strip pitch of outer tracker sensors in cm - PitchPS = cms.double( 0.01 ), # pixel pitch of outer tracker sensors in cm - Length2S = cms.double( 5.025 ), # strip length of outer tracker sensors in cm - LengthPS = cms.double( 0.1467 ), # pixel length of outer tracker sensors in cm - TiltedLayerLimitsZ = cms.vdouble( 15.5, 24.9, 34.3, -1., -1., -1. ), # barrel layer limit |z| value to partition into tilted and untilted region - PSDiskLimitsR = cms.vdouble( 66.4, 66.4, 64.55, 64.55, 64.55 ), # endcap disk limit r value to partition into PS and 2S region - ), - - # Parmeter specifying front-end - FrontEnd = cms.PSet ( - WidthBend = cms.int32 ( 6 ), # number of bits used for internal stub bend - WidthCol = cms.int32 ( 5 ), # number of bits used for internal stub column - WidthRow = cms.int32 ( 11 ), # number of bits used for internal stub row - BaseBend = cms.double( .25 ), # precision of internal stub bend in pitch units - BaseCol = cms.double( 1. ), # precision of internal stub column in pitch units - BaseRow = cms.double( .5 ), # precision of internal stub row in pitch units - BaseWindowSize = cms.double( .5 ), # precision of window sizes in pitch units - BendCut = cms.double( 1.3125 ) # used stub bend uncertainty in pitch units - ), - - # Parmeter specifying DTC - DTC = cms.PSet ( - NumRegions = cms.int32( 9 ), # number of phi slices the outer tracker readout is organized in - NumOverlappingRegions = cms.int32( 2 ), # number of regions a reconstructable particles may cross - NumATCASlots = cms.int32( 12 ), # number of Slots in used ATCA crates - NumDTCsPerRegion = cms.int32( 24 ), # number of DTC boards used to readout a detector region, likely constructed to be an integerer multiple of NumSlots_ - NumModulesPerDTC = cms.int32( 72 ), # max number of sensor modules connected to one DTC board - NumRoutingBlocks = cms.int32( 2 ), # number of systiloic arrays in stub router firmware - DepthMemory = cms.int32( 64 ), # fifo depth in stub router firmware - WidthRowLUT = cms.int32( 4 ), # number of row bits used in look up table - WidthInv2R = cms.int32( 9 ), # number of bits used for stub inv2R. lut addr is col + bend = 11 => 1 BRAM -> 18 bits for min and max val -> 9 - OffsetDetIdDSV = cms.int32( 1 ), # tk layout det id minus DetSetVec->detId - OffsetDetIdTP = cms.int32( -1 ), # tk layout det id minus TrackerTopology lower det id - OffsetLayerDisks = cms.int32( 10 ), # offset in layer ids between barrel layer and endcap disks - OffsetLayerId = cms.int32( 1 ), # offset between 0 and smallest layer id (barrel layer 1) - NumBarrelLayer = cms.int32( 6 ), # - SlotLimitPS = cms.int32( 6 ), # slot number changing from PS to 2S - SlotLimit10gbps = cms.int32( 3 ) # slot number changing from 10 gbps to 5gbps - ), - - # Parmeter specifying TFP - TFP = cms.PSet ( - WidthPhi0 = cms.int32( 12 ), # number of bist used for phi0 - WidthInv2R = cms.int32( 15 ), # number of bist used for inv2R - WidthCot = cms.int32( 16 ), # number of bist used for cot(theta) - WidthZ0 = cms.int32( 12 ), # number of bist used for z0 - NumChannel = cms.int32( 2 ) # number of output links - ), - - # Parmeter specifying GeometricProcessor - GeometricProcessor = cms.PSet ( - NumSectorsPhi = cms.int32 ( 2 ), # number of phi sectors used in hough transform - ChosenRofZ = cms.double( 50. ), # critical radius defining r-z sector shape in cm - RangeChiZ = cms.double( 160. ), # range of stub z residual w.r.t. sector center which needs to be covered - DepthMemory = cms.int32 ( 64 ), # fifo depth in stub router firmware - #BoundariesEta = cms.vdouble( -2.40, -2.08, -1.68, -1.26, -0.90, -0.62, -0.41, -0.20, 0.0, 0.20, 0.41, 0.62, 0.90, 1.26, 1.68, 2.08, 2.40 ) # defining r-z sector shape - BoundariesEta = cms.vdouble( -2.50, -2.23, -1.88, -1.36, -0.90, -0.62, -0.41, -0.20, 0.0, 0.20, 0.41, 0.62, 0.90, 1.36, 1.88, 2.23, 2.50 ) # defining r-z sector shape - ), - - # Parmeter specifying HoughTransform - HoughTransform = cms.PSet ( - NumBinsInv2R = cms.int32( 16 ), # number of used inv2R bins - NumBinsPhiT = cms.int32( 32 ), # number of used phiT bins - MinLayers = cms.int32( 5 ), # required number of stub layers to form a candidate - DepthMemory = cms.int32( 32 ) # internal fifo depth - ), - - # Parmeter specifying MiniHoughTransform - MiniHoughTransform = cms.PSet ( - NumBinsInv2R = cms.int32( 2 ), # number of finer inv2R bins inside HT bin - NumBinsPhiT = cms.int32( 2 ), # number of finer phiT bins inside HT bin - NumDLBs = cms.int32( 2 ), # number of dynamic load balancing steps - NumDLBNodes = cms.int32( 8 ), # number of units per dynamic load balancing step - NumDLBChannel = cms.int32( 2 ), # number of inputs per dynamic load balancing unit - MinLayers = cms.int32( 5 ) # required number of stub layers to form a candidate - ), - - # Parmeter specifying ZHoughTransform - ZHoughTransform = cms.PSet ( - NumBinsZT = cms.int32( 2 ), # - NumBinsCot = cms.int32( 2 ), # - NumStages = cms.int32( 5 ), # - MinLayers = cms.int32( 4 ), # required number of stub layers to form a candidate - MaxTracks = cms.int32( 16 ), # max number of output tracks per node - MaxStubsPerLayer = cms.int32( 4 ) # cut on number of stub per layer for input candidates - ), - - # Parmeter specifying KalmanFilter Input Formatter - - KalmanFilterIn = cms.PSet ( - ShiftRangePhi = cms.int32( 2 ), # power of 2 multiplier of stub phi residual range - ShiftRangeZ = cms.int32( 1 ) # power of 2 multiplier of stub z residual range - ), - - # Parmeter specifying KalmanFilter - KalmanFilter = cms.PSet ( - NumWorker = cms.int32 ( 2 ), # number of kf worker - RangeFactor = cms.double( 2.0 ), # search window of each track parameter in initial uncertainties - MinLayers = cms.int32 ( 4 ), # required number of stub layers to form a track - MaxLayers = cms.int32 ( 7 ), # maximum number of layers added to a track - ShiftInitialC00 = cms.int32 ( 0 ), # - ShiftInitialC11 = cms.int32 ( -2 ), # - ShiftInitialC22 = cms.int32 ( 0 ), # - ShiftInitialC33 = cms.int32 ( 0 ) # - ), - - # Parmeter specifying KalmanFilter Output Formatter - KalmanFilterOut = cms.PSet ( - Chi2rphiConv = cms.int32( 3 ), # Conversion factor between dphi^2/weight and chi2rphi - Chi2rzConv = cms.int32( 13 ), # Conversion factor between dz^2/weight and chi2rz - WeightBinFraction = cms.int32( 0 ), # Number of bits dropped from dphi and dz for v0 and v1 LUTs - DzTruncation = cms.int32( 262144 ), # Constant used in FW to prevent 32-bit int overflow - DphiTruncation = cms.int32( 16 ) # Constant used in FW to prevent 32-bit int overflow - ), - - # Parmeter specifying DuplicateRemoval - DuplicateRemoval = cms.PSet ( - DepthMemory = cms.int32( 16 ) # internal memory depth - ) - -) diff --git a/L1Trigger/TrackTrigger/python/Setup_cff.py b/L1Trigger/TrackTrigger/python/Setup_cff.py new file mode 100644 index 0000000000000..4880aeadc1cb4 --- /dev/null +++ b/L1Trigger/TrackTrigger/python/Setup_cff.py @@ -0,0 +1,6 @@ +# ESProducer processing and providing run-time constants used by Track Trigger emulators + +import FWCore.ParameterSet.Config as cms +from L1Trigger.TrackTrigger.Setup_cfi import TrackTrigger_params + +TrackTriggerSetup = cms.ESProducer("tt::ProducerSetup", TrackTrigger_params) diff --git a/L1Trigger/TrackTrigger/python/Setup_cfi.py b/L1Trigger/TrackTrigger/python/Setup_cfi.py new file mode 100644 index 0000000000000..91d93c1ff01ca --- /dev/null +++ b/L1Trigger/TrackTrigger/python/Setup_cfi.py @@ -0,0 +1,212 @@ +# configuration for TrackTriggerSetup + +import FWCore.ParameterSet.Config as cms + +TrackTrigger_params = cms.PSet ( + + # Parameter to check if Process History is consistent with process configuration + ProcessHistory = cms.PSet ( + GeometryConfiguration = cms.string( "XMLIdealGeometryESSource@" ), # label of compared GeometryConfiguration + TTStubAlgorithm = cms.string( "TTStubAlgorithm_official_Phase2TrackerDigi_@" ) # label of compared TTStubAlgorithm + ), + + # Common track finding parameter + TrackFinding = cms.PSet ( + BeamWindowZ = cms.double( 15. ), # half lumi region size in cm + NumLayers = cms.int32 ( 8 ), # TMTT: number of detector layers a reconstructbale particle may cross, reduced to 7, 8th layer almost never corssed + MinLayers = cms.int32 ( 4 ), # required number of stub layers to form a track + MinPt = cms.double( 2.0 ), # min track pt in GeV, also defines region overlap shape + MinPtCand = cms.double( 1.34 ), # min candiate pt in GeV + MaxEta = cms.double( 2.5 ), # cut on stub eta + MaxD0 = cms.double( 5.0 ), # in cm, constraints track reconstruction phase space + ChosenRofPhi = cms.double( 55. ), # critical radius defining region overlap shape in cm + ), + + # TMTT specific parameter + TMTT = cms.PSet ( + WidthR = cms.int32 ( 12 ), # number of bits used for stub r - ChosenRofPhi + WidthPhi = cms.int32 ( 15 ), # number of bits used for stub phi w.r.t. phi region centre + WidthZ = cms.int32 ( 14 ) # number of bits used for stub z + ), + + # Hybrid specific parameter + Hybrid = cms.PSet ( + NumLayers = cms.int32 ( 4 ), # max number of layer connected to one DTC + NumRingsPS = cms.vint32 ( 11, 11, 8, 8, 8 ), # number of outer PS rings for disk 1, 2, 3, 4, 5 + WidthsR = cms.vint32 ( 7, 7, 12, 7 ), # number of bits used for stub r w.r.t layer/disk centre for module types (barrelPS, barrel2S, diskPS, disk2S) + WidthsZ = cms.vint32 ( 12, 8, 7, 7 ), # number of bits used for stub z w.r.t layer/disk centre for module types (barrelPS, barrel2S, diskPS, disk2S) + WidthsPhi = cms.vint32 ( 14, 17, 14, 14 ), # number of bits used for stub phi w.r.t. region centre for module types (barrelPS, barrel2S, diskPS, disk2S) + WidthsAlpha = cms.vint32 ( 0, 0, 0, 4 ), # number of bits used for stub row number for module types (barrelPS, barrel2S, diskPS, disk2S) + WidthsBend = cms.vint32 ( 3, 4, 3, 4 ), # number of bits used for stub bend number for module types (barrelPS, barrel2S, diskPS, disk2S) + WidthsRTB = cms.vint32 ( 7, 7, 12, 12 ), # number of bits used for stub r w.r.t layer/disk centre for module types (barrelPS, barrel2S, diskPS, disk2S) at TB output + RangesR = cms.vdouble( 7.5, 7.5, 120. , 0. ), # range in stub r which needs to be covered for module types (barrelPS, barrel2S, diskPS, disk2S) + RangesZ = cms.vdouble( 240., 240., 7.5, 7.5 ), # range in stub z which needs to be covered for module types (barrelPS, barrel2S, diskPS, disk2S) + RangesAlpha = cms.vdouble( 0., 0., 0., 2048. ), # range in stub row which needs to be covered for module types (barrelPS, barrel2S, diskPS, disk2S) + LayerRs = cms.vdouble( 24.9316, 37.1777, 52.2656, 68.7598, 86.0156, 108.3105 ), # mean radius of outer tracker barrel layer + DiskZs = cms.vdouble( 131.1914, 154.9805, 185.3320, 221.6016, 265.0195 ), # mean z of outer tracker endcap disks + Disk2SRsSet = cms.VPSet( # center radius of outer tracker endcap 2S diks strips + cms.PSet( Disk2SRs = cms.vdouble( 66.4391, 71.4391, 76.2750, 81.2750, 82.9550, 87.9550, 93.8150, 98.8150, 99.8160, 104.8160 ) ), # disk 1 + cms.PSet( Disk2SRs = cms.vdouble( 66.4391, 71.4391, 76.2750, 81.2750, 82.9550, 87.9550, 93.8150, 98.8150, 99.8160, 104.8160 ) ), # disk 2 + cms.PSet( Disk2SRs = cms.vdouble( 63.9903, 68.9903, 74.2750, 79.2750, 81.9562, 86.9562, 92.4920, 97.4920, 99.8160, 104.8160 ) ), # disk 3 + cms.PSet( Disk2SRs = cms.vdouble( 63.9903, 68.9903, 74.2750, 79.2750, 81.9562, 86.9562, 92.4920, 97.4920, 99.8160, 104.8160 ) ), # disk 4 + cms.PSet( Disk2SRs = cms.vdouble( 63.9903, 68.9903, 74.2750, 79.2750, 81.9562, 86.9562, 92.4920, 97.4920, 99.8160, 104.8160 ) ) # disk 5 + ), + BarrelHalfLength = cms.double( 120.0 ), # biggest barrel stub z position after TrackBuilder in cm + InnerRadius = cms.double( 19.6 ), # smallest stub radius after TrackBuilder in cm + ), + + # Fimrware specific Parameter + Firmware = cms.PSet ( + EnableTruncation = cms.bool ( True ), # enable emulation of truncation for TM, DR, KF, TQ and TFP + UseHybrid = cms.bool ( True ), # use Hybrid or TMTT as TT algorithm + WidthDSPa = cms.int32 ( 27 ), # width of the 'A' port of an DSP slice + WidthDSPb = cms.int32 ( 18 ), # width of the 'B' port of an DSP slice + WidthDSPc = cms.int32 ( 48 ), # width of the 'C' port of an DSP slice + WidthAddrBRAM36 = cms.int32 ( 9 ), # smallest address width of an BRAM36 configured as broadest simple dual port memory + WidthAddrBRAM18 = cms.int32 ( 10 ), # smallest address width of an BRAM18 configured as broadest simple dual port memory + NumFramesInfra = cms.int32 ( 6 ), # needed gap between events of emp-infrastructure firmware + FreqLHC = cms.double( 40. ), # LHC bunch crossing rate in MHz + FreqBEHigh = cms.double( 360. ), # processing Frequency of DTC, KF & TFP in MHz, has to be integer multiple of FreqLHC + FreqBELow = cms.double( 240. ), # processing Frequency of DTC, KF & TFP in MHz, has to be integer multiple of FreqLHC + TMP_FE = cms.int32 ( 8 ), # number of events collected in front-end + TMP_TFP = cms.int32 ( 18 ), # time multiplexed period of track finding processor + SpeedOfLight = cms.double( 2.99792458 ), # in e8 m/s + ), + + # Parameter specifying outer tracker + Tracker = cms.PSet ( + BField = cms.double ( 3.81120228767395 ), # in T + BFieldError = cms.double ( 1.e-6 ), # accepted difference to EventSetup in T + OuterRadius = cms.double ( 112.7 ), # outer radius of outer tracker in cm + InnerRadius = cms.double ( 21.8 ), # inner radius of outer tracker in cm + HalfLength = cms.double ( 270. ), # half length of outer tracker in cm + TiltApproxSlope = cms.double ( 0.884 ), # In tilted barrel, grad*|z|/r + int approximates |cosTilt| + |sinTilt * cotTheta| + TiltApproxIntercept = cms.double ( 0.507 ), # In tilted barrel, grad*|z|/r + int approximates |cosTilt| + |sinTilt * cotTheta| + TiltUncertaintyR = cms.double ( 0.12 ), # In tilted barrel, constant assumed stub radial uncertainty * sqrt(12) in cm + Scattering = cms.double ( 0.131283 ), # additional radial uncertainty in cm used to calculate stub phi residual uncertainty to take multiple scattering into account + PitchRow2S = cms.double ( 0.009 ), # strip pitch of outer tracker sensors in cm + PitchRowPS = cms.double ( 0.01 ), # pixel pitch of outer tracker sensors in cm + PitchCol2S = cms.double ( 5.025 ), # strip length of outer tracker sensors in cm + PitchColPS = cms.double ( 0.1467 ), # pixel length of outer tracker sensors in cm + LimitPSBarrel = cms.double ( 125.0 ), # barrel layer limit r value to partition into PS and 2S region + LimitsTiltedR = cms.vdouble( 30.0, 45.0, 60.0 ), # barrel layer limit r value to partition into tilted and untilted region + LimitsTiltedZ = cms.vdouble( 15.5, 25.0, 34.3 ), # barrel layer limit |z| value to partition into tilted and untilted region + LimitsPSDiksZ = cms.vdouble( 125.0, 150.0, 175.0, 200.0, 250.0 ), # endcap disk limit |z| value to partition into PS and 2S region + LimitsPSDiksR = cms.vdouble( 66.0, 66.0, 63.0, 63.0, 63.0 ), # endcap disk limit r value to partition into PS and 2S region + TiltedLayerLimitsZ = cms.vdouble( 15.5, 24.9, 34.3, -1., -1., -1. ), # barrel layer limit |z| value to partition into tilted and untilted region + PSDiskLimitsR = cms.vdouble( 66.4, 66.4, 64.55, 64.55, 64.55 ), # endcap disk limit r value to partition into PS and 2S region + ), + + # Parmeter specifying front-end + FrontEnd = cms.PSet ( + WidthBend = cms.int32 ( 6 ), # number of bits used for internal stub bend + WidthCol = cms.int32 ( 5 ), # number of bits used for internal stub column + WidthRow = cms.int32 ( 11 ), # number of bits used for internal stub row + BaseBend = cms.double( .25 ), # precision of internal stub bend in pitch units + BaseCol = cms.double( 1. ), # precision of internal stub column in pitch units + BaseRow = cms.double( .5 ), # precision of internal stub row in pitch units + BaseWindowSize = cms.double( .5 ), # precision of window sizes in pitch units + BendCut = cms.double( 1.3125 ) # used stub bend uncertainty in pitch units + ), + + # Parmeter specifying DTC + DTC = cms.PSet ( + NumRegions = cms.int32( 9 ), # number of phi slices the outer tracker readout is organized in + NumOverlappingRegions = cms.int32( 2 ), # number of regions a reconstructable particles may cross + NumATCASlots = cms.int32( 12 ), # number of Slots in used ATCA crates + NumDTCsPerRegion = cms.int32( 24 ), # number of DTC boards used to readout a detector region, likely constructed to be an integerer multiple of NumSlots_ + NumModulesPerDTC = cms.int32( 72 ), # max number of sensor modules connected to one DTC board + NumRoutingBlocks = cms.int32( 2 ), # number of systiloic arrays in stub router firmware + DepthMemory = cms.int32( 64 ), # fifo depth in stub router firmware + WidthRowLUT = cms.int32( 4 ), # number of row bits used in look up table + WidthInv2R = cms.int32( 9 ), # number of bits used for stub inv2R. lut addr is col + bend = 11 => 1 BRAM -> 18 bits for min and max val -> 9 + OffsetDetIdDSV = cms.int32( 1 ), # tk layout det id minus DetSetVec->detId + OffsetDetIdTP = cms.int32( -1 ), # tk layout det id minus TrackerTopology lower det id + OffsetLayerDisks = cms.int32( 10 ), # offset in layer ids between barrel layer and endcap disks + OffsetLayerId = cms.int32( 1 ), # offset between 0 and smallest layer id (barrel layer 1) + NumBarrelLayer = cms.int32( 6 ), # number of barrel layer + NumBarrelLayerPS = cms.int32( 3 ), # number of barrel ps layer + SlotLimitPS = cms.int32( 6 ), # slot number changing from PS to 2S + SlotLimit10gbps = cms.int32( 3 ) # slot number changing from 10 gbps to 5gbps + ), + + # Parmeter specifying TFP + TFP = cms.PSet ( + WidthPhi0 = cms.int32( 12 ), # number of bist used for phi0 + WidthInvR = cms.int32( 15 ), # number of bist used for invR + WidthCot = cms.int32( 16 ), # number of bist used for cot(theta) + WidthZ0 = cms.int32( 12 ), # number of bist used for z0 + NumChannel = cms.int32( 2 ) # number of output links + ), + + # Parmeter specifying GeometricProcessor + GeometricProcessor = cms.PSet ( + NumBinsPhiT = cms.int32 ( 2 ), # number of phi sectors used in hough transform + NumBinsZT = cms.int32 ( 32 ), # number of eta sectors used in hough transform + ChosenRofZ = cms.double( 57.76 ), # critical radius defining r-z sector shape in cm + DepthMemory = cms.int32 ( 32 ), # fifo depth in stub router firmware + WidthModule = cms.int32 ( 3 ), # + PosPS = cms.int32 ( 2 ), # + PosBarrel = cms.int32 ( 1 ), # + PosTilted = cms.int32 ( 0 ) # + ), + + # Parmeter specifying HoughTransform + HoughTransform = cms.PSet ( + NumBinsInv2R = cms.int32( 16 ), # number of used inv2R bins + NumBinsPhiT = cms.int32( 32 ), # number of used phiT bins + MinLayers = cms.int32( 5 ), # required number of stub layers to form a candidate + DepthMemory = cms.int32( 32 ) # internal fifo depth + ), + + # Parmeter specifying Clean Track Builder + + CleanTrackBuilder = cms.PSet ( + NumBinsInv2R = cms.int32( 4 ), # number of inv2R bins + NumBinsPhiT = cms.int32( 4 ), # number of phiT bins + NumBinsCot = cms.int32( 4 ), # number of cot bins + NumBinsZT = cms.int32( 4 ), # number of zT bins + MinLayers = cms.int32( 4 ), # required number of stub layers to form a candidate + MaxTracks = cms.int32( 16 ), # max number of output tracks per node + MaxStubs = cms.int32( 4 ), # cut on number of stub per layer for input candidates + DepthMemory = cms.int32( 16 ) # internal fifo depth + ), + + # Parmeter specifying KalmanFilter + KalmanFilter = cms.PSet ( + Use5ParameterFit = cms.bool ( False ), # double precision simulation of 5 parameter fit instead of bit accurate emulation of 4 parameter fit + UseSimmulation = cms.bool ( False ), # simulate KF instead of emulate + UseTTStubResiduals = cms.bool ( True ), # stub residuals and radius are recalculated from seed parameter and TTStub position + UseTTStubParameters = cms.bool ( True ), # track parameter are recalculated from seed TTStub positions + ApplyNonLinearCorrection = cms.bool ( True ), # aplly correction to stub position making trajectory appear linear + NumWorker = cms.int32 ( 1 ), # number of kf worker + MaxTracks = cms.int32 ( 63 ), # max number of tracks a kf worker can process + RangeFactor = cms.double( 3.0 ), # search window of each track parameter in initial uncertainties + MinLayers = cms.int32 ( 4 ), # required number of stub layers to form a track + MinLayersPS = cms.int32 ( 0 ), # required number of ps stub layers to form a track + MaxLayers = cms.int32 ( 8 ), # maximum number of layers added to a track + MaxGaps = cms.int32 ( 4 ), # maximum number of layer gaps allowed during cominatorical track building + MaxSeedingLayer = cms.int32 ( 4 ), # perform seeding in layers 0 to this + NumSeedStubs = cms.int32 ( 2 ), # number of stubs forming a seed + MinSeedDeltaR = cms.double( 1.6 ), # don't build seeds with smaller radial difference as this in cm + ShiftInitialC00 = cms.int32 ( 0 ), # initial C00 is given by inv2R uncertainty squared times this power of 2 + ShiftInitialC11 = cms.int32 ( 0 ), # initial C11 is given by phiT uncertainty squared times this power of 2 + ShiftInitialC22 = cms.int32 ( 0 ), # initial C22 is given by cot uncertainty squared times this power of 2 + ShiftInitialC33 = cms.int32 ( 0 ), # initial C33 is given by zT uncertainty squared times this power of 2 + ShiftChi20 = cms.int32 ( -1 ), # shiting chi2 in r-phi plane by power of two when caliclating chi2 + ShiftChi21 = cms.int32 ( -5 ), # shiting chi2 in r-z plane by power of two when caliclating chi2 + CutChi2 = cms.double( 2.0 ), # cut on chi2 over degree of freedom + WidthChi2 = cms.int32 ( 8 ) # number of bits used to represent chi2 over degree of freedom + ), + + # Parmeter specifying DuplicateRemoval + DuplicateRemoval = cms.PSet ( + DepthMemory = cms.int32( 16 ) # internal memory depth + ), + + # Parmeter specifying Track Quality + TrackQuality = cms.PSet ( + NumChannel = cms.int32( 2 ) # number of output channel + ) + +) diff --git a/L1Trigger/TrackTrigger/python/TTStubAlgorithmRegister_cfi.py b/L1Trigger/TrackTrigger/python/TTStubAlgorithmRegister_cfi.py index b7dea492ce517..4ff930293cbd9 100644 --- a/L1Trigger/TrackTrigger/python/TTStubAlgorithmRegister_cfi.py +++ b/L1Trigger/TrackTrigger/python/TTStubAlgorithmRegister_cfi.py @@ -43,4 +43,3 @@ # anything. Override with process.TTStubAlgorithm_PSimHit_ = ..., # etc. in your configuration. TTStubAlgorithm_Phase2TrackerDigi_ = cms.ESPrefer("TTStubAlgorithm_official_Phase2TrackerDigi_") - diff --git a/L1Trigger/TrackTrigger/python/TrackQualityParams_cfi.py b/L1Trigger/TrackTrigger/python/TrackQualityParams_cfi.py deleted file mode 100644 index e1e8f6cdb5ec2..0000000000000 --- a/L1Trigger/TrackTrigger/python/TrackQualityParams_cfi.py +++ /dev/null @@ -1,11 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -TrackQualityParams = cms.PSet(# This emulation GBDT is optimised for the HYBRID_NEWKF emulation and works with the emulation of the KF out module - # It is compatible with the HYBRID simulation and will give equivilant performance with this workflow - model = cms.FileInPath("L1Trigger/TrackTrigger/data/L1_TrackQuality_GBDT_emulation_digitized.json"), - #Vector of strings of training features, in the order that the model was trained with - featureNames = cms.vstring(["tanl", "z0_scaled", "bendchi2_bin", "nstub", - "nlaymiss_interior", "chi2rphi_bin", "chi2rz_bin"]), - tqemu_TanlScale = cms.double( 128.0), - tqemu_Z0Scale = cms.double( 64.0 ), - ) diff --git a/L1Trigger/TrackTrigger/src/L1TrackQuality.cc b/L1Trigger/TrackTrigger/src/L1TrackQuality.cc deleted file mode 100644 index 7296cb385e665..0000000000000 --- a/L1Trigger/TrackTrigger/src/L1TrackQuality.cc +++ /dev/null @@ -1,115 +0,0 @@ -/* -Track Quality Body file -C.Brown & C.Savard 07/2020 -*/ - -#include "L1Trigger/TrackTrigger/interface/L1TrackQuality.h" - -//Constructors - -L1TrackQuality::L1TrackQuality() {} - -L1TrackQuality::L1TrackQuality(const edm::ParameterSet& qualityParams) : useHPH_(false), bonusFeatures_() { - // Unpacks EDM parameter set itself to save unecessary processing within TrackProducers - setModel(qualityParams.getParameter("model"), - qualityParams.getParameter>("featureNames")); -} - -std::vector L1TrackQuality::featureTransform(TTTrack& aTrack, - std::vector const& featureNames) { - // List input features for MVA in proper order below, the current features options are - // {"phi", "eta", "z0", "bendchi2_bin", "nstub", "nlaymiss_interior", "chi2rphi_bin", - // "chi2rz_bin"} - // - // To use more features, they must be created here and added to feature_map below - - std::vector transformedFeatures; - - // Define feature map, filled as features are generated - std::map feature_map; - - // -------- calculate feature variables -------- - - // calculate number of missed interior layers from hitpattern - int tmp_trk_hitpattern = aTrack.hitPattern(); - int nbits = floor(log2(tmp_trk_hitpattern)) + 1; - int lay_i = 0; - int tmp_trk_nlaymiss_interior = 0; - bool seq = false; - for (int i = 0; i < nbits; i++) { - lay_i = ((1 << i) & tmp_trk_hitpattern) >> i; //0 or 1 in ith bit (right to left) - - if (lay_i && !seq) - seq = true; //sequence starts when first 1 found - if (!lay_i && seq) - tmp_trk_nlaymiss_interior++; - } - - // binned chi2 variables - int tmp_trk_bendchi2_bin = aTrack.getBendChi2Bits(); - int tmp_trk_chi2rphi_bin = aTrack.getChi2RPhiBits(); - int tmp_trk_chi2rz_bin = aTrack.getChi2RZBits(); - - // get the nstub - std::vector>, TTStub>> stubRefs = - aTrack.getStubRefs(); - int tmp_trk_nstub = stubRefs.size(); - - // get other variables directly from TTTrack - float tmp_trk_z0 = aTrack.z0(); - float tmp_trk_z0_scaled = tmp_trk_z0 / abs(aTrack.minZ0); - float tmp_trk_phi = aTrack.phi(); - float tmp_trk_eta = aTrack.eta(); - float tmp_trk_tanl = aTrack.tanL(); - - // -------- fill the feature map --------- - - feature_map["nstub"] = float(tmp_trk_nstub); - feature_map["z0"] = tmp_trk_z0; - feature_map["z0_scaled"] = tmp_trk_z0_scaled; - feature_map["phi"] = tmp_trk_phi; - feature_map["eta"] = tmp_trk_eta; - feature_map["nlaymiss_interior"] = float(tmp_trk_nlaymiss_interior); - feature_map["bendchi2_bin"] = tmp_trk_bendchi2_bin; - feature_map["chi2rphi_bin"] = tmp_trk_chi2rphi_bin; - feature_map["chi2rz_bin"] = tmp_trk_chi2rz_bin; - feature_map["tanl"] = tmp_trk_tanl; - - // fill tensor with track params - transformedFeatures.reserve(featureNames.size()); - for (const std::string& feature : featureNames) - transformedFeatures.push_back(feature_map[feature]); - - return transformedFeatures; -} - -void L1TrackQuality::setL1TrackQuality(TTTrack& aTrack) { - // load in bdt - conifer::BDT bdt(this->model_.fullPath()); - - // collect features and classify using bdt - std::vector inputs = featureTransform(aTrack, this->featureNames_); - std::vector output = bdt.decision_function(inputs); - aTrack.settrkMVA1(1. / (1. + exp(-output.at(0)))); -} - -float L1TrackQuality::runEmulatedTQ(std::vector> inputFeatures) { - // load in bdt - - conifer::BDT, ap_fixed<10, 5>> bdt(this->model_.fullPath()); - - // collect features and classify using bdt - std::vector> output = bdt.decision_function(inputFeatures); - return output.at(0).to_float(); // need logistic sigmoid fcn applied to xgb output -} - -void L1TrackQuality::setModel(edm::FileInPath const& model, std::vector const& featureNames) { - //Convert algorithm string to Enum class for track by track comparison - model_ = model; - featureNames_ = featureNames; -} - -void L1TrackQuality::setBonusFeatures(std::vector bonusFeatures) { - bonusFeatures_ = bonusFeatures; - useHPH_ = true; -} diff --git a/L1Trigger/TrackTrigger/src/SensorModule.cc b/L1Trigger/TrackTrigger/src/SensorModule.cc index e30e75819c744..0a8f585e2d123 100644 --- a/L1Trigger/TrackTrigger/src/SensorModule.cc +++ b/L1Trigger/TrackTrigger/src/SensorModule.cc @@ -7,9 +7,6 @@ #include #include -using namespace std; -using namespace edm; - namespace tt { SensorModule::SensorModule(const Setup* setup, const DetId& detId, int dtcId, int modId) @@ -50,8 +47,8 @@ namespace tt { // Pixel-Strip or 2Strip module psModule_ = trackerGeometry->getDetectorType(detId) == TrackerGeometry::ModuleType::Ph2PSP; // module tilt angle measured w.r.t. beam axis (0=barrel), tk layout measures w.r.t. radial axis - tilt_ = flipped_ ? atan2(pos1.z() - pos0.z(), pos0.perp() - pos1.perp()) - : atan2(pos0.z() - pos1.z(), pos1.perp() - pos0.perp()); + tilt_ = flipped_ ? std::atan2(pos1.z() - pos0.z(), pos0.perp() - pos1.perp()) + : std::atan2(pos0.z() - pos1.z(), pos1.perp() - pos0.perp()); // sinus of module tilt measured w.r.t. beam axis (0=barrel), tk layout measures w.r.t. radial axis sinTilt_ = std::sin(tilt_); // cosinus of module tilt measured w.r.t. beam axis (+-1=endcap), tk layout measures w.r.t. radial axis @@ -62,7 +59,7 @@ namespace tt { // layer id [1-6,11-15] layerId_ = layer + setup->offsetLayerId() + (barrel_ ? 0 : setup->offsetLayerDisks()); // TTStub row needs flip of sign - signRow_ = signbit(deltaPhi(plane.rotation().x().phi() - pos0.phi())); + signRow_ = std::signbit(deltaPhi(plane.rotation().x().phi() - pos0.phi())); // TTStub col needs flip of sign signCol_ = !barrel_ && !side_; // TTStub bend needs flip of sign @@ -113,10 +110,17 @@ namespace tt { // calculate tilt correction parameter used to project r to z uncertainty tiltCorrectionSlope_ = barrel_ ? 0. : 1.; tiltCorrectionIntercept_ = barrel_ ? 1. : 0.; + tilted_ = false; if (typeTilt == tiltedMinus || typeTilt == tiltedPlus) { + tilted_ = true; tiltCorrectionSlope_ = setup->tiltApproxSlope(); tiltCorrectionIntercept_ = setup->tiltApproxIntercept(); } + // stub uncertainty + scattering_ = setup->scattering(); + dR_ = std::abs(sinTilt_) * pitchCol_; + dPhi_ = pitchRow_ / r_; + dZ_ = std::abs(cosTilt_) * pitchCol_ + dR_ * std::abs(z_) / r_; } unsigned int SensorModule::ringId(const Setup* setup) const { diff --git a/L1Trigger/TrackTrigger/src/Setup.cc b/L1Trigger/TrackTrigger/src/Setup.cc index f26ed4ac2c238..da31845bae339 100644 --- a/L1Trigger/TrackTrigger/src/Setup.cc +++ b/L1Trigger/TrackTrigger/src/Setup.cc @@ -1,228 +1,176 @@ #include "L1Trigger/TrackTrigger/interface/Setup.h" #include "FWCore/Utilities/interface/Exception.h" -#include "DataFormats/Provenance/interface/ProcessConfiguration.h" #include "DataFormats/L1TrackTrigger/interface/TTBV.h" #include "DataFormats/L1TrackTrigger/interface/TTTypes.h" #include #include +#include #include #include -#include -#include -#include - -using namespace std; -using namespace edm; namespace tt { - Setup::Setup(const ParameterSet& iConfig, - const MagneticField& magneticField, + Setup::Setup(const Config& iConfig, const TrackerGeometry& trackerGeometry, const TrackerTopology& trackerTopology, const TrackerDetToDTCELinkCablingMap& cablingMap, const StubAlgorithmOfficial& stubAlgorithm, - const ParameterSet& pSetStubAlgorithm, - const ParameterSet& pSetGeometryConfiguration, - const ParameterSetID& pSetIdTTStubAlgorithm, - const ParameterSetID& pSetIdGeometryConfiguration) - : magneticField_(&magneticField), - trackerGeometry_(&trackerGeometry), + const edm::ParameterSet& pSetStubAlgorithm) + : trackerGeometry_(&trackerGeometry), trackerTopology_(&trackerTopology), cablingMap_(&cablingMap), stubAlgorithm_(&stubAlgorithm), pSetSA_(&pSetStubAlgorithm), - pSetGC_(&pSetGeometryConfiguration), - pSetIdTTStubAlgorithm_(pSetIdTTStubAlgorithm), - pSetIdGeometryConfiguration_(pSetIdGeometryConfiguration), - // DD4hep - fromDD4hep_(iConfig.getParameter("fromDD4hep")), - // Parameter to check if configured Tracker Geometry is supported - pSetSG_(iConfig.getParameter("UnSupportedGeometry")), - sgXMLLabel_(pSetSG_.getParameter("XMLLabel")), - sgXMLPath_(pSetSG_.getParameter("XMLPath")), - sgXMLFile_(pSetSG_.getParameter("XMLFile")), - sgXMLVersions_(pSetSG_.getParameter>("XMLVersions")), - // Parameter to check if Process History is consistent with process configuration - pSetPH_(iConfig.getParameter("ProcessHistory")), - phGeometryConfiguration_(pSetPH_.getParameter("GeometryConfiguration")), - phTTStubAlgorithm_(pSetPH_.getParameter("TTStubAlgorithm")), // Common track finding parameter - pSetTF_(iConfig.getParameter("TrackFinding")), - beamWindowZ_(pSetTF_.getParameter("BeamWindowZ")), - matchedLayers_(pSetTF_.getParameter("MatchedLayers")), - matchedLayersPS_(pSetTF_.getParameter("MatchedLayersPS")), - unMatchedStubs_(pSetTF_.getParameter("UnMatchedStubs")), - unMatchedStubsPS_(pSetTF_.getParameter("UnMatchedStubsPS")), - scattering_(pSetTF_.getParameter("Scattering")), + beamWindowZ_(iConfig.beamWindowZ_), + minPt_(iConfig.minPt_), + minPtCand_(iConfig.minPtCand_), + maxEta_(iConfig.maxEta_), + maxD0_(iConfig.maxD0_), + chosenRofPhi_(iConfig.chosenRofPhi_), + numLayers_(iConfig.numLayers_), + minLayers_(iConfig.minLayers_), // TMTT specific parameter - pSetTMTT_(iConfig.getParameter("TMTT")), - minPt_(pSetTMTT_.getParameter("MinPt")), - maxEta_(pSetTMTT_.getParameter("MaxEta")), - chosenRofPhi_(pSetTMTT_.getParameter("ChosenRofPhi")), - numLayers_(pSetTMTT_.getParameter("NumLayers")), - tmttWidthR_(pSetTMTT_.getParameter("WidthR")), - tmttWidthPhi_(pSetTMTT_.getParameter("WidthPhi")), - tmttWidthZ_(pSetTMTT_.getParameter("WidthZ")), + tmttWidthR_(iConfig.tmttWidthR_), + tmttWidthPhi_(iConfig.tmttWidthPhi_), + tmttWidthZ_(iConfig.tmttWidthZ_), // Hybrid specific parameter - pSetHybrid_(iConfig.getParameter("Hybrid")), - hybridMinPtStub_(pSetHybrid_.getParameter("MinPtStub")), - hybridMinPtCand_(pSetHybrid_.getParameter("MinPtCand")), - hybridMaxEta_(pSetHybrid_.getParameter("MaxEta")), - hybridChosenRofPhi_(pSetHybrid_.getParameter("ChosenRofPhi")), - hybridNumLayers_(pSetHybrid_.getParameter("NumLayers")), - hybridNumRingsPS_(pSetHybrid_.getParameter>("NumRingsPS")), - hybridWidthsR_(pSetHybrid_.getParameter>("WidthsR")), - hybridWidthsZ_(pSetHybrid_.getParameter>("WidthsZ")), - hybridWidthsPhi_(pSetHybrid_.getParameter>("WidthsPhi")), - hybridWidthsAlpha_(pSetHybrid_.getParameter>("WidthsAlpha")), - hybridWidthsBend_(pSetHybrid_.getParameter>("WidthsBend")), - hybridRangesR_(pSetHybrid_.getParameter>("RangesR")), - hybridRangesZ_(pSetHybrid_.getParameter>("RangesZ")), - hybridRangesAlpha_(pSetHybrid_.getParameter>("RangesAlpha")), - hybridLayerRs_(pSetHybrid_.getParameter>("LayerRs")), - hybridDiskZs_(pSetHybrid_.getParameter>("DiskZs")), - hybridDisk2SRsSet_(pSetHybrid_.getParameter>("Disk2SRsSet")), - tbInnerRadius_(pSetHybrid_.getParameter("InnerRadius")), - tbWidthsR_(pSetHybrid_.getParameter>("WidthsRTB")), - // Parameter specifying TrackingParticle used for Efficiency measurements - pSetTP_(iConfig.getParameter("TrackingParticle")), - tpMinPt_(pSetTP_.getParameter("MinPt")), - tpMaxEta_(pSetTP_.getParameter("MaxEta")), - tpMaxVertR_(pSetTP_.getParameter("MaxVertR")), - tpMaxVertZ_(pSetTP_.getParameter("MaxVertZ")), - tpMaxD0_(pSetTP_.getParameter("MaxD0")), - tpMinLayers_(pSetTP_.getParameter("MinLayers")), - tpMinLayersPS_(pSetTP_.getParameter("MinLayersPS")), - tpMaxBadStubs2S_(pSetTP_.getParameter("MaxBadStubs2S")), - tpMaxBadStubsPS_(pSetTP_.getParameter("MaxBadStubsPS")), + hybridNumLayers_(iConfig.hybridNumLayers_), + hybridNumRingsPS_(iConfig.hybridNumRingsPS_), + hybridWidthsR_(iConfig.hybridWidthsR_), + hybridWidthsZ_(iConfig.hybridWidthsZ_), + hybridWidthsPhi_(iConfig.hybridWidthsPhi_), + hybridWidthsAlpha_(iConfig.hybridWidthsAlpha_), + hybridWidthsBend_(iConfig.hybridWidthsBend_), + hybridRangesR_(iConfig.hybridRangesR_), + hybridRangesZ_(iConfig.hybridRangesZ_), + hybridRangesAlpha_(iConfig.hybridRangesAlpha_), + hybridLayerRs_(iConfig.hybridLayerRs_), + hybridDiskZs_(iConfig.hybridDiskZs_), + hybridDisk2SRsSet_(iConfig.hybridDisk2SRsSet_), + tbBarrelHalfLength_(iConfig.tbBarrelHalfLength_), + tbInnerRadius_(iConfig.tbInnerRadius_), + tbWidthsR_(iConfig.tbWidthsR_), // Fimrware specific Parameter - pSetFW_(iConfig.getParameter("Firmware")), - widthDSPa_(pSetFW_.getParameter("WidthDSPa")), - widthDSPb_(pSetFW_.getParameter("WidthDSPb")), - widthDSPc_(pSetFW_.getParameter("WidthDSPc")), - widthAddrBRAM36_(pSetFW_.getParameter("WidthAddrBRAM36")), - widthAddrBRAM18_(pSetFW_.getParameter("WidthAddrBRAM18")), - numFramesInfra_(pSetFW_.getParameter("NumFramesInfra")), - freqLHC_(pSetFW_.getParameter("FreqLHC")), - freqBE_(pSetFW_.getParameter("FreqBE")), - tmpFE_(pSetFW_.getParameter("TMP_FE")), - tmpTFP_(pSetFW_.getParameter("TMP_TFP")), - speedOfLight_(pSetFW_.getParameter("SpeedOfLight")), - bField_(pSetFW_.getParameter("BField")), - bFieldError_(pSetFW_.getParameter("BFieldError")), - outerRadius_(pSetFW_.getParameter("OuterRadius")), - innerRadius_(pSetFW_.getParameter("InnerRadius")), - halfLength_(pSetFW_.getParameter("HalfLength")), - tiltApproxSlope_(pSetFW_.getParameter("TiltApproxSlope")), - tiltApproxIntercept_(pSetFW_.getParameter("TiltApproxIntercept")), - tiltUncertaintyR_(pSetFW_.getParameter("TiltUncertaintyR")), - mindPhi_(pSetFW_.getParameter("MindPhi")), - maxdPhi_(pSetFW_.getParameter("MaxdPhi")), - mindZ_(pSetFW_.getParameter("MindZ")), - maxdZ_(pSetFW_.getParameter("MaxdZ")), - pitch2S_(pSetFW_.getParameter("Pitch2S")), - pitchPS_(pSetFW_.getParameter("PitchPS")), - length2S_(pSetFW_.getParameter("Length2S")), - lengthPS_(pSetFW_.getParameter("LengthPS")), - tiltedLayerLimitsZ_(pSetFW_.getParameter>("TiltedLayerLimitsZ")), - psDiskLimitsR_(pSetFW_.getParameter>("PSDiskLimitsR")), + enableTruncation_(iConfig.enableTruncation_), + widthDSPa_(iConfig.widthDSPa_), + widthDSPb_(iConfig.widthDSPb_), + widthDSPc_(iConfig.widthDSPc_), + widthAddrBRAM36_(iConfig.widthAddrBRAM36_), + widthAddrBRAM18_(iConfig.widthAddrBRAM18_), + numFramesInfra_(iConfig.numFramesInfra_), + freqLHC_(iConfig.freqLHC_), + freqBEHigh_(iConfig.freqBEHigh_), + freqBELow_(iConfig.freqBELow_), + tmpFE_(iConfig.tmpFE_), + tmpTFP_(iConfig.tmpTFP_), + speedOfLight_(iConfig.speedOfLight_), + // Tracker specific Paramter + bField_(iConfig.bField_), + bFieldError_(iConfig.bFieldError_), + outerRadius_(iConfig.outerRadius_), + innerRadius_(iConfig.innerRadius_), + halfLength_(iConfig.halfLength_), + tiltApproxSlope_(iConfig.tiltApproxSlope_), + tiltApproxIntercept_(iConfig.tiltApproxIntercept_), + tiltUncertaintyR_(iConfig.tiltUncertaintyR_), + scattering_(iConfig.scattering_), + pitchRow2S_(iConfig.pitchRow2S_), + pitchRowPS_(iConfig.pitchRowPS_), + pitchCol2S_(iConfig.pitchCol2S_), + pitchColPS_(iConfig.pitchColPS_), + limitPSBarrel_(iConfig.limitPSBarrel_), + limitsTiltedR_(iConfig.limitsTiltedR_), + limitsTiltedZ_(iConfig.limitsTiltedZ_), + limitsPSDiksZ_(iConfig.limitsPSDiksZ_), + limitsPSDiksR_(iConfig.limitsPSDiksR_), + tiltedLayerLimitsZ_(iConfig.tiltedLayerLimitsZ_), + psDiskLimitsR_(iConfig.psDiskLimitsR_), // Parmeter specifying front-end - pSetFE_(iConfig.getParameter("FrontEnd")), - widthBend_(pSetFE_.getParameter("WidthBend")), - widthCol_(pSetFE_.getParameter("WidthCol")), - widthRow_(pSetFE_.getParameter("WidthRow")), - baseBend_(pSetFE_.getParameter("BaseBend")), - baseCol_(pSetFE_.getParameter("BaseCol")), - baseRow_(pSetFE_.getParameter("BaseRow")), - baseWindowSize_(pSetFE_.getParameter("BaseWindowSize")), - bendCut_(pSetFE_.getParameter("BendCut")), + widthBend_(iConfig.widthBend_), + widthCol_(iConfig.widthCol_), + widthRow_(iConfig.widthRow_), + baseBend_(iConfig.baseBend_), + baseCol_(iConfig.baseCol_), + baseRow_(iConfig.baseRow_), + baseWindowSize_(iConfig.baseWindowSize_), + bendCut_(iConfig.bendCut_), // Parmeter specifying DTC - pSetDTC_(iConfig.getParameter("DTC")), - numRegions_(pSetDTC_.getParameter("NumRegions")), - numOverlappingRegions_(pSetDTC_.getParameter("NumOverlappingRegions")), - numATCASlots_(pSetDTC_.getParameter("NumATCASlots")), - numDTCsPerRegion_(pSetDTC_.getParameter("NumDTCsPerRegion")), - numModulesPerDTC_(pSetDTC_.getParameter("NumModulesPerDTC")), - dtcNumRoutingBlocks_(pSetDTC_.getParameter("NumRoutingBlocks")), - dtcDepthMemory_(pSetDTC_.getParameter("DepthMemory")), - dtcWidthRowLUT_(pSetDTC_.getParameter("WidthRowLUT")), - dtcWidthInv2R_(pSetDTC_.getParameter("WidthInv2R")), - offsetDetIdDSV_(pSetDTC_.getParameter("OffsetDetIdDSV")), - offsetDetIdTP_(pSetDTC_.getParameter("OffsetDetIdTP")), - offsetLayerDisks_(pSetDTC_.getParameter("OffsetLayerDisks")), - offsetLayerId_(pSetDTC_.getParameter("OffsetLayerId")), - numBarrelLayer_(pSetDTC_.getParameter("NumBarrelLayer")), - slotLimitPS_(pSetDTC_.getParameter("SlotLimitPS")), - slotLimit10gbps_(pSetDTC_.getParameter("SlotLimit10gbps")), + numRegions_(iConfig.numRegions_), + numOverlappingRegions_(iConfig.numOverlappingRegions_), + numATCASlots_(iConfig.numATCASlots_), + numDTCsPerRegion_(iConfig.numDTCsPerRegion_), + numModulesPerDTC_(iConfig.numModulesPerDTC_), + dtcNumRoutingBlocks_(iConfig.dtcNumRoutingBlocks_), + dtcDepthMemory_(iConfig.dtcDepthMemory_), + dtcWidthRowLUT_(iConfig.dtcWidthRowLUT_), + dtcWidthInv2R_(iConfig.dtcWidthInv2R_), + offsetDetIdDSV_(iConfig.offsetDetIdDSV_), + offsetDetIdTP_(iConfig.offsetDetIdTP_), + offsetLayerDisks_(iConfig.offsetLayerDisks_), + offsetLayerId_(iConfig.offsetLayerId_), + numBarrelLayer_(iConfig.numBarrelLayer_), + numBarrelLayerPS_(iConfig.numBarrelLayerPS_), + slotLimitPS_(iConfig.slotLimitPS_), + slotLimit10gbps_(iConfig.slotLimit10gbps_), // Parmeter specifying TFP - pSetTFP_(iConfig.getParameter("TFP")), - tfpWidthPhi0_(pSetTFP_.getParameter("WidthPhi0")), - tfpWidthInv2R_(pSetTFP_.getParameter("WidthInv2R")), - tfpWidthCot_(pSetTFP_.getParameter("WidthCot")), - tfpWidthZ0_(pSetTFP_.getParameter("WidthZ0")), - tfpNumChannel_(pSetTFP_.getParameter("NumChannel")), + tfpWidthPhi0_(iConfig.tfpWidthPhi0_), + tfpWidthInvR_(iConfig.tfpWidthInvR_), + tfpWidthCot_(iConfig.tfpWidthCot_), + tfpWidthZ0_(iConfig.tfpWidthZ0_), + tfpNumChannel_(iConfig.tfpNumChannel_), // Parmeter specifying GeometricProcessor - pSetGP_(iConfig.getParameter("GeometricProcessor")), - numSectorsPhi_(pSetGP_.getParameter("NumSectorsPhi")), - chosenRofZ_(pSetGP_.getParameter("ChosenRofZ")), - neededRangeChiZ_(pSetGP_.getParameter("RangeChiZ")), - gpDepthMemory_(pSetGP_.getParameter("DepthMemory")), - boundariesEta_(pSetGP_.getParameter>("BoundariesEta")), + gpNumBinsPhiT_(iConfig.gpNumBinsPhiT_), + gpNumBinsZT_(iConfig.gpNumBinsZT_), + chosenRofZ_(iConfig.chosenRofZ_), + gpDepthMemory_(iConfig.gpDepthMemory_), + gpWidthModule_(iConfig.gpWidthModule_), + gpPosPS_(iConfig.gpPosPS_), + gpPosBarrel_(iConfig.gpPosBarrel_), + gpPosTilted_(iConfig.gpPosTilted_), // Parmeter specifying HoughTransform - pSetHT_(iConfig.getParameter("HoughTransform")), - htNumBinsInv2R_(pSetHT_.getParameter("NumBinsInv2R")), - htNumBinsPhiT_(pSetHT_.getParameter("NumBinsPhiT")), - htMinLayers_(pSetHT_.getParameter("MinLayers")), - htDepthMemory_(pSetHT_.getParameter("DepthMemory")), - // Parmeter specifying MiniHoughTransform - pSetMHT_(iConfig.getParameter("MiniHoughTransform")), - mhtNumBinsInv2R_(pSetMHT_.getParameter("NumBinsInv2R")), - mhtNumBinsPhiT_(pSetMHT_.getParameter("NumBinsPhiT")), - mhtNumDLBs_(pSetMHT_.getParameter("NumDLBs")), - mhtNumDLBNodes_(pSetMHT_.getParameter("NumDLBNodes")), - mhtNumDLBChannel_(pSetMHT_.getParameter("NumDLBChannel")), - mhtMinLayers_(pSetMHT_.getParameter("MinLayers")), - // Parmeter specifying ZHoughTransform - pSetZHT_(iConfig.getParameter("ZHoughTransform")), - zhtNumBinsZT_(pSetZHT_.getParameter("NumBinsZT")), - zhtNumBinsCot_(pSetZHT_.getParameter("NumBinsCot")), - zhtNumStages_(pSetZHT_.getParameter("NumStages")), - zhtMinLayers_(pSetZHT_.getParameter("MinLayers")), - zhtMaxTracks_(pSetZHT_.getParameter("MaxTracks")), - zhtMaxStubsPerLayer_(pSetZHT_.getParameter("MaxStubsPerLayer")), - // Parameter specifying KalmanFilter Input Formatter - pSetKFin_(iConfig.getParameter("KalmanFilterIn")), - kfinShiftRangePhi_(pSetKFin_.getParameter("ShiftRangePhi")), - kfinShiftRangeZ_(pSetKFin_.getParameter("ShiftRangeZ")), + htNumBinsInv2R_(iConfig.htNumBinsInv2R_), + htNumBinsPhiT_(iConfig.htNumBinsPhiT_), + htMinLayers_(iConfig.htMinLayers_), + htDepthMemory_(iConfig.htDepthMemory_), + // Parameter specifying Track Builder + ctbNumBinsInv2R_(iConfig.ctbNumBinsInv2R_), + ctbNumBinsPhiT_(iConfig.ctbNumBinsPhiT_), + ctbNumBinsCot_(iConfig.ctbNumBinsCot_), + ctbNumBinsZT_(iConfig.ctbNumBinsZT_), + ctbMinLayers_(iConfig.ctbMinLayers_), + ctbMaxTracks_(iConfig.ctbMaxTracks_), + ctbMaxStubs_(iConfig.ctbMaxStubs_), + ctbDepthMemory_(iConfig.ctbDepthMemory_), // Parmeter specifying KalmanFilter - pSetKF_(iConfig.getParameter("KalmanFilter")), - kfNumWorker_(pSetKF_.getParameter("NumWorker")), - kfMinLayers_(pSetKF_.getParameter("MinLayers")), - kfMaxLayers_(pSetKF_.getParameter("MaxLayers")), - kfRangeFactor_(pSetKF_.getParameter("RangeFactor")), - kfShiftInitialC00_(pSetKF_.getParameter("ShiftInitialC00")), - kfShiftInitialC11_(pSetKF_.getParameter("ShiftInitialC11")), - kfShiftInitialC22_(pSetKF_.getParameter("ShiftInitialC22")), - kfShiftInitialC33_(pSetKF_.getParameter("ShiftInitialC33")), - // Parmeter specifying KalmanFilter Output Formatter - pSetKFOut_(iConfig.getParameter("KalmanFilterOut")), - kfoutchi2rphiConv_(pSetKFOut_.getParameter("Chi2rphiConv")), - kfoutchi2rzConv_(pSetKFOut_.getParameter("Chi2rzConv")), - weightBinFraction_(pSetKFOut_.getParameter("WeightBinFraction")), - dzTruncation_(pSetKFOut_.getParameter("DzTruncation")), - dphiTruncation_(pSetKFOut_.getParameter("DphiTruncation")), + kfUse5ParameterFit_(iConfig.kfUse5ParameterFit_), + kfUseSimmulation_(iConfig.kfUseSimmulation_), + kfUseTTStubResiduals_(iConfig.kfUseTTStubResiduals_), + kfUseTTStubParameters_(iConfig.kfUseTTStubParameters_), + kfApplyNonLinearCorrection_(iConfig.kfApplyNonLinearCorrection_), + kfNumWorker_(iConfig.kfNumWorker_), + kfMaxTracks_(iConfig.kfMaxTracks_), + kfMinLayers_(iConfig.kfMinLayers_), + kfMinLayersPS_(iConfig.kfMinLayersPS_), + kfMaxLayers_(iConfig.kfMaxLayers_), + kfMaxGaps_(iConfig.kfMaxGaps_), + kfMaxSeedingLayer_(iConfig.kfMaxSeedingLayer_), + kfNumSeedStubs_(iConfig.kfNumSeedStubs_), + kfMinSeedDeltaR_(iConfig.kfMinSeedDeltaR_), + kfRangeFactor_(iConfig.kfRangeFactor_), + kfShiftInitialC00_(iConfig.kfShiftInitialC00_), + kfShiftInitialC11_(iConfig.kfShiftInitialC11_), + kfShiftInitialC22_(iConfig.kfShiftInitialC22_), + kfShiftInitialC33_(iConfig.kfShiftInitialC33_), + kfShiftChi20_(iConfig.kfShiftChi20_), + kfShiftChi21_(iConfig.kfShiftChi21_), + kfCutChi2_(iConfig.kfCutChi2_), + kfWidthChi2_(iConfig.kfWidthChi2_), // Parmeter specifying DuplicateRemoval - pSetDR_(iConfig.getParameter("DuplicateRemoval")), - drDepthMemory_(pSetDR_.getParameter("DepthMemory")) { - configurationSupported_ = true; - // check if bField is supported - checkMagneticField(); - // check if geometry is supported - checkGeometry(); - if (!configurationSupported_) - return; + drDepthMemory_(iConfig.drDepthMemory_), + // Parmeter specifying Track Quality + tqNumChannel_(iConfig.tqNumChannel_) { // derive constants calculateConstants(); // convert configuration of TTStubAlgorithm @@ -234,60 +182,6 @@ namespace tt { encodeBend(encodingsBend2S_, false); // create sensor modules produceSensorModules(); - // configure TPSelector - configureTPSelector(); - } - - // checks current configuration vs input sample configuration - void Setup::checkHistory(const ProcessHistory& processHistory) const { - const pset::Registry* psetRegistry = pset::Registry::instance(); - // check used TTStubAlgorithm in input producer - checkHistory(processHistory, psetRegistry, phTTStubAlgorithm_, pSetIdTTStubAlgorithm_); - // check used GeometryConfiguration in input producer - checkHistory(processHistory, psetRegistry, phGeometryConfiguration_, pSetIdGeometryConfiguration_); - } - - // checks consitency between history and current configuration for a specific module - void Setup::checkHistory(const ProcessHistory& ph, - const pset::Registry* pr, - const string& label, - const ParameterSetID& pSetId) const { - vector> pSets; - pSets.reserve(ph.size()); - for (const ProcessConfiguration& pc : ph) { - const ParameterSet* pSet = pr->getMapped(pc.parameterSetID()); - if (pSet && pSet->exists(label)) - pSets.emplace_back(pc.processName(), pSet->getParameterSet(label)); - } - if (pSets.empty()) { - cms::Exception exception("BadConfiguration"); - exception << label << " not found in process history."; - exception.addContext("tt::Setup::checkHistory"); - throw exception; - } - auto consistent = [&pSetId](const pair& p) { return p.second.id() == pSetId; }; - if (!all_of(pSets.begin(), pSets.end(), consistent)) { - const ParameterSet& pSetProcess = getParameterSet(pSetId); - cms::Exception exception("BadConfiguration"); - exception.addContext("tt::Setup::checkHistory"); - exception << label << " inconsistent with History." << endl; - exception << "Current Configuration:" << endl << pSetProcess.dump() << endl; - for (const pair& p : pSets) - if (!consistent(p)) - exception << "Process " << p.first << " Configuration:" << endl << dumpDiff(p.second, pSetProcess) << endl; - throw exception; - } - } - - // dumps pSetHistory where incosistent lines with pSetProcess are highlighted - string Setup::dumpDiff(const ParameterSet& pSetHistory, const ParameterSet& pSetProcess) const { - stringstream ssHistory, ssProcess, ss; - ssHistory << pSetHistory.dump(); - ssProcess << pSetProcess.dump(); - string lineHistory, lineProcess; - for (; getline(ssHistory, lineHistory) && getline(ssProcess, lineProcess);) - ss << (lineHistory != lineProcess ? "\033[1;31m" : "") << lineHistory << "\033[0m" << endl; - return ss.str(); } // converts tk layout id into dtc id @@ -373,72 +267,41 @@ namespace tt { return it->second; } - // index = encoded bend, value = decoded bend for given window size and module type - const vector& Setup::encodingBend(int windowSize, bool psModule) const { - const vector>& encodingsBend = psModule ? encodingsBendPS_ : encodingsBend2S_; - return encodingsBend.at(windowSize); - } - - // check if bField is supported - void Setup::checkMagneticField() { - const double bFieldES = magneticField_->inTesla(GlobalPoint(0., 0., 0.)).z(); - if (abs(bField_ - bFieldES) > bFieldError_) { - configurationSupported_ = false; - LogWarning("ConfigurationNotSupported") - << "Magnetic Field from EventSetup (" << bFieldES << ") differs more then " << bFieldError_ - << " from supported value (" << bField_ << "). "; - } + // sensor module for ttStubRef + SensorModule* Setup::sensorModule(const TTStubRef& ttStubRef) const { + const DetId detId = ttStubRef->getDetId() + offsetDetIdDSV_; + return this->sensorModule(detId); } - // check if geometry is supported - void Setup::checkGeometry() { - //FIX ME: Can we assume that geometry used in dd4hep wf supports L1Track? - if (!fromDD4hep_) { - const vector& geomXMLFiles = pSetGC_->getParameter>(sgXMLLabel_); - string version; - for (const string& geomXMLFile : geomXMLFiles) { - const auto begin = geomXMLFile.find(sgXMLPath_) + sgXMLPath_.size(); - const auto end = geomXMLFile.find(sgXMLFile_); - if (begin != string::npos && end != string::npos) - version = geomXMLFile.substr(begin, end - begin - 1); - } - if (version.empty()) { - cms::Exception exception("LogicError"); - exception << "No " << sgXMLPath_ << "*/" << sgXMLFile_ << " found in GeometryConfiguration"; - exception.addContext("tt::Setup::checkGeometry"); - throw exception; - } - if (find(sgXMLVersions_.begin(), sgXMLVersions_.end(), version) != sgXMLVersions_.end()) { - configurationSupported_ = false; - LogWarning("ConfigurationNotSupported") - << "Geometry Configuration " << sgXMLPath_ << version << "/" << sgXMLFile_ << " is not supported. "; - } - } + // index = encoded bend, value = decoded bend for given window size and module type + const std::vector& Setup::encodingBend(int windowSize, bool psModule) const { + const std::vector>& encodingsBend = psModule ? encodingsBendPS_ : encodingsBend2S_; + return encodingsBend.at(windowSize); } // convert configuration of TTStubAlgorithm void Setup::consumeStubAlgorithm() { - numTiltedLayerRings_ = pSetSA_->getParameter>("NTiltedRings"); - windowSizeBarrelLayers_ = pSetSA_->getParameter>("BarrelCut"); - const auto& pSetsTiltedLayer = pSetSA_->getParameter>("TiltedBarrelCutSet"); - const auto& pSetsEncapDisks = pSetSA_->getParameter>("EndcapCutSet"); + numTiltedLayerRings_ = pSetSA_->getParameter>("NTiltedRings"); + windowSizeBarrelLayers_ = pSetSA_->getParameter>("BarrelCut"); + const auto& pSetsTiltedLayer = pSetSA_->getParameter>("TiltedBarrelCutSet"); + const auto& pSetsEncapDisks = pSetSA_->getParameter>("EndcapCutSet"); windowSizeTiltedLayerRings_.reserve(pSetsTiltedLayer.size()); for (const auto& pSet : pSetsTiltedLayer) - windowSizeTiltedLayerRings_.emplace_back(pSet.getParameter>("TiltedCut")); + windowSizeTiltedLayerRings_.emplace_back(pSet.getParameter>("TiltedCut")); windowSizeEndcapDisksRings_.reserve(pSetsEncapDisks.size()); for (const auto& pSet : pSetsEncapDisks) - windowSizeEndcapDisksRings_.emplace_back(pSet.getParameter>("EndcapCut")); + windowSizeEndcapDisksRings_.emplace_back(pSet.getParameter>("EndcapCut")); maxWindowSize_ = -1; for (const auto& windowss : {windowSizeTiltedLayerRings_, windowSizeEndcapDisksRings_, {windowSizeBarrelLayers_}}) for (const auto& windows : windowss) for (const auto& window : windows) - maxWindowSize_ = max(maxWindowSize_, (int)(window / baseWindowSize_)); + maxWindowSize_ = std::max(maxWindowSize_, static_cast(window / baseWindowSize_)); } // create bend encodings - void Setup::encodeBend(vector>& encodings, bool ps) const { + void Setup::encodeBend(std::vector>& encodings, bool ps) const { for (int window = 0; window < maxWindowSize_ + 1; window++) { - set encoding; + std::set encoding; for (int bend = 0; bend < window + 1; bend++) encoding.insert(stubAlgorithm_->degradeBend(ps, window, bend)); encodings.emplace_back(encoding.begin(), encoding.end()); @@ -448,8 +311,8 @@ namespace tt { // create sensor modules void Setup::produceSensorModules() { sensorModules_.reserve(numModules_); - dtcModules_ = vector>(numDTCs_); - for (vector& dtcModules : dtcModules_) + dtcModules_ = std::vector>(numDTCs_); + for (std::vector& dtcModules : dtcModules_) dtcModules.reserve(numModulesPerDTC_); enum SubDetId { pixelBarrel = 1, pixelDisks = 2 }; // loop over all tracker modules @@ -467,7 +330,7 @@ namespace tt { // track trigger dtc id [0-215] const int dtcId = Setup::dtcId(tklId); // collection of so far connected modules to this dtc - vector& dtcModules = dtcModules_[dtcId]; + std::vector& dtcModules = dtcModules_[dtcId]; // construct sendor module sensorModules_.emplace_back(this, detId, dtcId, dtcModules.size()); SensorModule* sensorModule = &sensorModules_.back(); @@ -476,7 +339,7 @@ namespace tt { // store connection between dtcId and sensor module dtcModules.push_back(sensorModule); } - for (vector& dtcModules : dtcModules_) { + for (std::vector& dtcModules : dtcModules_) { dtcModules.shrink_to_fit(); // check configuration if ((int)dtcModules.size() > numModulesPerDTC_) { @@ -488,25 +351,6 @@ namespace tt { } } - // configure TPSelector - void Setup::configureTPSelector() { - // configure TrackingParticleSelector - const double ptMin = tpMinPt_; - constexpr double ptMax = 9.e9; - const double etaMax = tpMaxEta_; - const double tip = tpMaxVertR_; - const double lip = tpMaxVertZ_; - constexpr int minHit = 0; - constexpr bool signalOnly = true; - constexpr bool intimeOnly = true; - constexpr bool chargedOnly = true; - constexpr bool stableOnly = false; - tpSelector_ = TrackingParticleSelector( - ptMin, ptMax, -etaMax, etaMax, tip, lip, minHit, signalOnly, intimeOnly, chargedOnly, stableOnly); - tpSelectorLoose_ = - TrackingParticleSelector(ptMin, ptMax, -etaMax, etaMax, tip, lip, minHit, false, false, false, stableOnly); - } - // stub layer id (barrel: 1 - 6, endcap: 11 - 15) int Setup::layerId(const TTStubRef& ttStubRef) const { const DetId& detId = ttStubRef->getDetId(); @@ -516,12 +360,16 @@ namespace tt { // return tracklet layerId (barrel: [0-5], endcap: [6-10]) for given TTStubRef int Setup::trackletLayerId(const TTStubRef& ttStubRef) const { - return this->layerId(ttStubRef) - (this->barrel(ttStubRef) ? offsetLayerId_ : numBarrelLayer_ - offsetLayerId_); + static constexpr int offsetBarrel = 1; + static constexpr int offsetDisks = 5; + return this->layerId(ttStubRef) - (this->barrel(ttStubRef) ? offsetBarrel : offsetDisks); } // return index layerId (barrel: [0-5], endcap: [0-6]) for given TTStubRef int Setup::indexLayerId(const TTStubRef& ttStubRef) const { - return this->layerId(ttStubRef) - (this->barrel(ttStubRef) ? offsetLayerId_ : offsetLayerId_ + offsetLayerDisks_); + static constexpr int offsetBarrel = 1; + static constexpr int offsetDisks = 11; + return this->layerId(ttStubRef) - (this->barrel(ttStubRef) ? offsetBarrel : offsetDisks); } // true if stub from barrel module @@ -533,46 +381,47 @@ namespace tt { // true if stub from barrel module bool Setup::psModule(const TTStubRef& ttStubRef) const { const DetId& detId = ttStubRef->getDetId(); - return trackerGeometry_->getDetectorType(detId) == TrackerGeometry::ModuleType::Ph2PSP; + SensorModule* sm = sensorModule(detId + 1); + return sm->psModule(); } // - TTBV Setup::layerMap(const vector& ints) const { + TTBV Setup::layerMap(const std::vector& ints) const { TTBV ttBV; for (int layer = numLayers_ - 1; layer >= 0; layer--) { const int i = ints[layer]; - ttBV += TTBV(i, kfWidthLayerCount_); + ttBV += TTBV(i, ctbWidthLayerCount_); } return ttBV; } // - TTBV Setup::layerMap(const TTBV& hitPattern, const vector& ints) const { + TTBV Setup::layerMap(const TTBV& hitPattern, const std::vector& ints) const { TTBV ttBV; for (int layer = numLayers_ - 1; layer >= 0; layer--) { const int i = ints[layer]; - ttBV += TTBV((hitPattern[layer] ? i - 1 : 0), kfWidthLayerCount_); + ttBV += TTBV((hitPattern[layer] ? i - 1 : 0), ctbWidthLayerCount_); } return ttBV; } // - vector Setup::layerMap(const TTBV& hitPattern, const TTBV& ttBV) const { + std::vector Setup::layerMap(const TTBV& hitPattern, const TTBV& ttBV) const { TTBV bv(ttBV); - vector ints(numLayers_, 0); + std::vector ints(numLayers_, 0); for (int layer = 0; layer < numLayers_; layer++) { - const int i = bv.extract(kfWidthLayerCount_); + const int i = bv.extract(ctbWidthLayerCount_); ints[layer] = i + (hitPattern[layer] ? 1 : 0); } return ints; } // - vector Setup::layerMap(const TTBV& ttBV) const { + std::vector Setup::layerMap(const TTBV& ttBV) const { TTBV bv(ttBV); - vector ints(numLayers_, 0); + std::vector ints(numLayers_, 0); for (int layer = 0; layer < numLayers_; layer++) - ints[layer] = bv.extract(kfWidthLayerCount_); + ints[layer] = bv.extract(ctbWidthLayerCount_); return ints; } @@ -580,36 +429,14 @@ namespace tt { double Setup::dPhi(const TTStubRef& ttStubRef, double inv2R) const { const DetId& detId = ttStubRef->getDetId(); SensorModule* sm = sensorModule(detId + 1); - const double r = stubPos(ttStubRef).perp(); - const double sigma = sm->pitchRow() / r; - const double scat = scattering_ * abs(inv2R); - const double extra = sm->barrel() ? 0. : sm->pitchCol() * abs(inv2R); - const double digi = tmttBasePhi_; - const double dPhi = sigma + scat + extra + digi; - if (dPhi >= maxdPhi_ || dPhi < mindPhi_) { - cms::Exception exception("out_of_range"); - exception.addContext("tt::Setup::dPhi"); - exception << "Stub phi uncertainty " << dPhi << " " - << "is out of range " << mindPhi_ << " to " << maxdPhi_ << "."; - throw exception; - } - return dPhi; + return sm->dPhi(inv2R); } // stub projected z uncertainty - double Setup::dZ(const TTStubRef& ttStubRef, double cot) const { + double Setup::dZ(const TTStubRef& ttStubRef) const { const DetId& detId = ttStubRef->getDetId(); SensorModule* sm = sensorModule(detId + 1); - const double sigma = sm->pitchCol() * sm->tiltCorrection(cot); - const double digi = tmttBaseZ_; - const double dZ = sigma + digi; - if (dZ >= maxdZ_ || dZ < mindZ_) { - cms::Exception exception("out_of_range"); - exception.addContext("tt::Setup::dZ"); - exception << "Stub z uncertainty " << dZ << " " - << "is out of range " << mindZ_ << " to " << maxdZ_ << "."; - throw exception; - } + const double dZ = sm->dZ(); return dZ; } @@ -618,10 +445,10 @@ namespace tt { const DetId& detId = ttStubRef->getDetId(); SensorModule* sm = sensorModule(detId + 1); const double r = stubPos(ttStubRef).perp(); - const double sigma = pow(sm->pitchRow() / r, 2) / 12.; - const double scat = pow(scattering_ * inv2R, 2); - const double extra = sm->barrel() ? 0. : pow(sm->pitchCol() * inv2R, 2); - const double digi = pow(tmttBasePhi_ / 12., 2); + const double sigma = std::pow(sm->pitchRow() / r, 2) / 12.; + const double scat = std::pow(scattering_ * inv2R, 2); + const double extra = sm->barrel() ? 0. : std::pow(sm->pitchCol() * inv2R, 2); + const double digi = std::pow(tmttBasePhi_ / 12., 2); return sigma + scat + extra + digi; } @@ -629,38 +456,81 @@ namespace tt { double Setup::v1(const TTStubRef& ttStubRef, double cot) const { const DetId& detId = ttStubRef->getDetId(); SensorModule* sm = sensorModule(detId + 1); - const double sigma = pow(sm->pitchCol() * sm->tiltCorrection(cot), 2) / 12.; - const double digi = pow(tmttBaseZ_ / 12., 2); + const double sigma = std::pow(sm->pitchCol() * sm->tiltCorrection(cot), 2) / 12.; + const double digi = std::pow(tmttBaseZ_ / 12., 2); return sigma + digi; } // checks if stub collection is considered forming a reconstructable track - bool Setup::reconstructable(const vector& ttStubRefs) const { - set hitPattern; + bool Setup::reconstructable(const std::vector& ttStubRefs) const { + std::set hitPattern; for (const TTStubRef& ttStubRef : ttStubRefs) hitPattern.insert(layerId(ttStubRef)); - return (int)hitPattern.size() >= tpMinLayers_; + return (int)hitPattern.size() >= minLayers_; } - // checks if tracking particle is selected for efficiency measurements - bool Setup::useForAlgEff(const TrackingParticle& tp) const { - const bool selected = tpSelector_(tp); - const double cot = sinh(tp.eta()); - const double s = sin(tp.phi()); - const double c = cos(tp.phi()); - const TrackingParticle::Point& v = tp.vertex(); - const double z0 = v.z() - (v.x() * c + v.y() * s) * cot; - const double d0 = v.x() * s - v.y() * c; - return selected && (abs(d0) < tpMaxD0_) && (abs(z0) < tpMaxVertZ_); + // + TTBV Setup::module(double r, double z) const { + static constexpr int layer1 = 0; + static constexpr int layer2 = 1; + static constexpr int layer3 = 2; + static constexpr int disk1 = 0; + static constexpr int disk2 = 1; + static constexpr int disk3 = 2; + static constexpr int disk4 = 3; + static constexpr int disk5 = 4; + bool ps(false); + bool barrel(false); + bool tilted(false); + if (std::abs(z) < limitPSBarrel_) { + barrel = true; + if (r < limitsTiltedR_[layer3]) + ps = true; + if (r < limitsTiltedR_[layer1]) + tilted = std::abs(z) > limitsTiltedZ_[layer1]; + else if (r < limitsTiltedR_[layer2]) + tilted = std::abs(z) > limitsTiltedZ_[layer2]; + else if (r < limitsTiltedR_[layer3]) + tilted = std::abs(z) > limitsTiltedZ_[layer3]; + } else if (std::abs(z) > limitsPSDiksZ_[disk5]) + ps = r < limitsPSDiksR_[disk5]; + else if (std::abs(z) > limitsPSDiksZ_[disk4]) + ps = r < limitsPSDiksR_[disk4]; + else if (std::abs(z) > limitsPSDiksZ_[disk3]) + ps = r < limitsPSDiksR_[disk3]; + else if (std::abs(z) > limitsPSDiksZ_[disk2]) + ps = r < limitsPSDiksR_[disk2]; + else if (std::abs(z) > limitsPSDiksZ_[disk1]) + ps = r < limitsPSDiksR_[disk1]; + TTBV module(0, gpWidthModule_); + if (ps) + module.set(gpPosPS_); + if (barrel) + module.set(gpPosBarrel_); + if (tilted) + module.set(gpPosTilted_); + return module; + } + + // stub projected phi uncertainty for given module type, stub radius and track curvature + double Setup::dPhi(const TTBV& module, double r, double inv2R) const { + const double sigma = (ps(module) ? pitchRowPS_ : pitchRow2S_) / r; + const double dR = scattering_ + (barrel(module) ? (tilted(module) ? tiltUncertaintyR_ : 0.0) + : (ps(module) ? pitchColPS_ : pitchCol2S_)); + const double dPhi = sigma + dR * abs(inv2R) + tmttBasePhi_; + return dPhi; } // derive constants void Setup::calculateConstants() { // emp - const int numFramesPerBX = freqBE_ / freqLHC_; - numFrames_ = numFramesPerBX * tmpTFP_ - 1; - numFramesIO_ = numFramesPerBX * tmpTFP_ - numFramesInfra_; - numFramesFE_ = numFramesPerBX * tmpFE_ - numFramesInfra_; + const int numFramesPerBXHigh = freqBEHigh_ / freqLHC_; + numFramesHigh_ = numFramesPerBXHigh * tmpTFP_ - 1; + numFramesIOHigh_ = numFramesPerBXHigh * tmpTFP_ - numFramesInfra_; + const int numFramesPerBXLow = freqBELow_ / freqLHC_; + numFramesLow_ = numFramesPerBXLow * tmpTFP_ - 1; + numFramesIOLow_ = numFramesPerBXLow * tmpTFP_ - numFramesInfra_; + numFramesFE_ = numFramesPerBXHigh * tmpFE_ - numFramesInfra_; // dsp widthDSPab_ = widthDSPa_ - 1; widthDSPau_ = widthDSPab_ - 1; @@ -669,89 +539,87 @@ namespace tt { widthDSPcb_ = widthDSPc_ - 1; widthDSPcu_ = widthDSPcb_ - 1; // firmware - maxPitch_ = max(pitchPS_, pitch2S_); - maxLength_ = max(lengthPS_, length2S_); + maxPitchRow_ = std::max(pitchRowPS_, pitchRow2S_); + maxPitchCol_ = std::max(pitchColPS_, pitchCol2S_); // common track finding invPtToDphi_ = speedOfLight_ * bField_ / 2000.; baseRegion_ = 2. * M_PI / numRegions_; + maxCot_ = beamWindowZ_ / chosenRofZ_ + std::sinh(maxEta_); // gp - baseSector_ = baseRegion_ / numSectorsPhi_; - maxCot_ = sinh(maxEta_); - maxZT_ = maxCot_ * chosenRofZ_; - numSectorsEta_ = boundariesEta_.size() - 1; - numSectors_ = numSectorsPhi_ * numSectorsEta_; - sectorCots_.reserve(numSectorsEta_); - for (int eta = 0; eta < numSectorsEta_; eta++) - sectorCots_.emplace_back((sinh(boundariesEta_.at(eta)) + sinh(boundariesEta_.at(eta + 1))) / 2.); + baseSector_ = baseRegion_ / gpNumBinsPhiT_; + maxRphi_ = std::max(std::abs(outerRadius_ - chosenRofPhi_), std::abs(innerRadius_ - chosenRofPhi_)); + maxRz_ = std::max(std::abs(outerRadius_ - chosenRofZ_), std::abs(innerRadius_ - chosenRofZ_)); + numSectors_ = gpNumBinsPhiT_ * gpNumBinsZT_; // tmtt const double rangeInv2R = 2. * invPtToDphi_ / minPt_; tmttBaseInv2R_ = rangeInv2R / htNumBinsInv2R_; tmttBasePhiT_ = baseSector_ / htNumBinsPhiT_; const double baseRgen = tmttBasePhiT_ / tmttBaseInv2R_; - const double rangeR = 2. * max(abs(outerRadius_ - chosenRofPhi_), abs(innerRadius_ - chosenRofPhi_)); - const int baseShiftR = ceil(log2(rangeR / baseRgen / pow(2., tmttWidthR_))); - tmttBaseR_ = baseRgen * pow(2., baseShiftR); + const double rangeR = 2. * maxRphi_; + const int baseShiftR = std::ceil(std::log2(rangeR / baseRgen / std::pow(2., tmttWidthR_))); + tmttBaseR_ = baseRgen * std::pow(2., baseShiftR); const double rangeZ = 2. * halfLength_; - const int baseShiftZ = ceil(log2(rangeZ / tmttBaseR_ / pow(2., tmttWidthZ_))); - tmttBaseZ_ = tmttBaseR_ * pow(2., baseShiftZ); + const int baseShiftZ = std::ceil(std::log2(rangeZ / tmttBaseR_ / std::pow(2., tmttWidthZ_))); + tmttBaseZ_ = tmttBaseR_ * std::pow(2., baseShiftZ); const double rangePhi = baseRegion_ + rangeInv2R * rangeR / 2.; - const int baseShiftPhi = ceil(log2(rangePhi / tmttBasePhiT_ / pow(2., tmttWidthPhi_))); - tmttBasePhi_ = tmttBasePhiT_ * pow(2., baseShiftPhi); - tmttWidthLayer_ = ceil(log2(numLayers_)); - tmttWidthSectorEta_ = ceil(log2(numSectorsEta_)); - tmttWidthInv2R_ = ceil(log2(htNumBinsInv2R_)); + const int baseShiftPhi = std::ceil(std::log2(rangePhi / tmttBasePhiT_ / std::pow(2., tmttWidthPhi_))); + tmttBasePhi_ = tmttBasePhiT_ * std::pow(2., baseShiftPhi); + tmttWidthLayer_ = std::ceil(std::log2(numLayers_)); + tmttWidthSectorEta_ = std::ceil(std::log2(gpNumBinsZT_)); + tmttWidthInv2R_ = std::ceil(std::log2(htNumBinsInv2R_)); tmttNumUnusedBits_ = TTBV::S_ - tmttWidthLayer_ - 2 * tmttWidthSectorEta_ - tmttWidthR_ - tmttWidthPhi_ - - tmttWidthZ_ - 2 * tmttWidthInv2R_ - numSectorsPhi_ - 1; + tmttWidthZ_ - 2 * tmttWidthInv2R_ - gpNumBinsPhiT_ - 1; // hybrid - const double hybridRangeInv2R = 2. * invPtToDphi_ / hybridMinPtStub_; + const double hybridRangeInv2R = 2. * invPtToDphi_ / minPt_; const double hybridRangeR = - 2. * max(abs(outerRadius_ - hybridChosenRofPhi_), abs(innerRadius_ - hybridChosenRofPhi_)); + 2. * std::max(std::abs(outerRadius_ - chosenRofPhi_), std::abs(innerRadius_ - chosenRofPhi_)); hybridRangePhi_ = baseRegion_ + (hybridRangeR * hybridRangeInv2R) / 2.; - hybridWidthLayerId_ = ceil(log2(hybridNumLayers_)); + hybridWidthLayerId_ = std::ceil(std::log2(hybridNumLayers_)); hybridBasesZ_.reserve(SensorModule::NumTypes); for (int type = 0; type < SensorModule::NumTypes; type++) - hybridBasesZ_.emplace_back(hybridRangesZ_.at(type) / pow(2., hybridWidthsZ_.at(type))); + hybridBasesZ_.emplace_back(hybridRangesZ_.at(type) / std::pow(2., hybridWidthsZ_.at(type))); hybridBasesR_.reserve(SensorModule::NumTypes); for (int type = 0; type < SensorModule::NumTypes; type++) - hybridBasesR_.emplace_back(hybridRangesR_.at(type) / pow(2., hybridWidthsR_.at(type))); + hybridBasesR_.emplace_back(hybridRangesR_.at(type) / std::pow(2., hybridWidthsR_.at(type))); hybridBasesR_[SensorModule::Disk2S] = 1.; hybridBasesPhi_.reserve(SensorModule::NumTypes); for (int type = 0; type < SensorModule::NumTypes; type++) - hybridBasesPhi_.emplace_back(hybridRangePhi_ / pow(2., hybridWidthsPhi_.at(type))); + hybridBasesPhi_.emplace_back(hybridRangePhi_ / std::pow(2., hybridWidthsPhi_.at(type))); hybridBasesAlpha_.reserve(SensorModule::NumTypes); for (int type = 0; type < SensorModule::NumTypes; type++) - hybridBasesAlpha_.emplace_back(hybridRangesAlpha_.at(type) / pow(2., hybridWidthsAlpha_.at(type))); + hybridBasesAlpha_.emplace_back(hybridRangesAlpha_.at(type) / std::pow(2., hybridWidthsAlpha_.at(type))); hybridNumsUnusedBits_.reserve(SensorModule::NumTypes); for (int type = 0; type < SensorModule::NumTypes; type++) hybridNumsUnusedBits_.emplace_back(TTBV::S_ - hybridWidthsR_.at(type) - hybridWidthsZ_.at(type) - hybridWidthsPhi_.at(type) - hybridWidthsAlpha_.at(type) - hybridWidthsBend_.at(type) - hybridWidthLayerId_ - 1); - hybridMaxCot_ = sinh(hybridMaxEta_); + hybridBaseR_ = *std::min_element(hybridBasesR_.begin(), hybridBasesR_.end()); + hybridBasePhi_ = *std::min_element(hybridBasesPhi_.begin(), hybridBasesPhi_.end()); + hybridBaseZ_ = *std::min_element(hybridBasesZ_.begin(), hybridBasesZ_.end()); + hybridMaxCot_ = std::sinh(maxEta_); disk2SRs_.reserve(hybridDisk2SRsSet_.size()); for (const auto& pSet : hybridDisk2SRsSet_) - disk2SRs_.emplace_back(pSet.getParameter>("Disk2SRs")); + disk2SRs_.emplace_back(pSet.getParameter>("Disk2SRs")); // dtc numDTCs_ = numRegions_ * numDTCsPerRegion_; numDTCsPerTFP_ = numDTCsPerRegion_ * numOverlappingRegions_; numModules_ = numDTCs_ * numModulesPerDTC_; dtcNumModulesPerRoutingBlock_ = numModulesPerDTC_ / dtcNumRoutingBlocks_; - dtcNumMergedRows_ = pow(2, widthRow_ - dtcWidthRowLUT_); - const double maxRangeInv2R = max(rangeInv2R, hybridRangeInv2R); - const int baseShiftInv2R = ceil(log2(htNumBinsInv2R_)) - dtcWidthInv2R_ + ceil(log2(maxRangeInv2R / rangeInv2R)); - dtcBaseInv2R_ = tmttBaseInv2R_ * pow(2., baseShiftInv2R); + dtcNumMergedRows_ = std::pow(2, widthRow_ - dtcWidthRowLUT_); + const double maxRangeInv2R = std::max(rangeInv2R, hybridRangeInv2R); + const int baseShiftInv2R = + std::ceil(std::log2(htNumBinsInv2R_)) - dtcWidthInv2R_ + std::ceil(std::log2(maxRangeInv2R / rangeInv2R)); + dtcBaseInv2R_ = tmttBaseInv2R_ * std::pow(2., baseShiftInv2R); const int baseDiffM = dtcWidthRowLUT_ - widthRow_; - dtcBaseM_ = tmttBasePhi_ * pow(2., baseDiffM); - const double x1 = pow(2, widthRow_) * baseRow_ * maxPitch_ / 2.; - const double x0 = x1 - pow(2, dtcWidthRowLUT_) * baseRow_ * maxPitch_; - const double maxM = atan2(x1, innerRadius_) - atan2(x0, innerRadius_); - dtcWidthM_ = ceil(log2(maxM / dtcBaseM_)); + dtcBaseM_ = tmttBasePhi_ * std::pow(2., baseDiffM); + const double x1 = std::pow(2, widthRow_) * baseRow_ * maxPitchRow_ / 2.; + const double x0 = x1 - std::pow(2, dtcWidthRowLUT_) * baseRow_ * maxPitchRow_; + const double maxM = std::atan2(x1, innerRadius_) - std::atan2(x0, innerRadius_); + dtcWidthM_ = std::ceil(std::log2(maxM / dtcBaseM_)); dtcNumStreams_ = numDTCs_ * numOverlappingRegions_; - // mht - mhtNumCells_ = mhtNumBinsInv2R_ * mhtNumBinsPhiT_; - // zht - zhtNumCells_ = zhtNumBinsCot_ * zhtNumBinsZT_; - // - kfWidthLayerCount_ = ceil(log2(zhtMaxStubsPerLayer_)); + // ctb + ctbWidthLayerCount_ = std::ceil(std::log2(ctbMaxStubs_)); + // kf } // returns bit accurate hybrid stub radius for given TTStubRef and h/w bit word @@ -769,12 +637,12 @@ namespace tt { } // returns bit accurate position of a stub from a given tfp region [0-8] - GlobalPoint Setup::stubPos(bool hybrid, const FrameStub& frame, int region) const { + GlobalPoint Setup::stubPos(const FrameStub& frame, int region) const { GlobalPoint p; if (frame.first.isNull()) return p; TTBV bv(frame.second); - if (hybrid) { + if (useHybrid_) { const bool barrel = this->barrel(frame.first); const int layerId = this->indexLayerId(frame.first); const GlobalPoint gp = this->stubPos(frame.first); @@ -806,7 +674,7 @@ namespace tt { } p = GlobalPoint(GlobalPoint::Cylindrical(r, phi, z)); } else { - bv >>= 2 * tmttWidthInv2R_ + 2 * tmttWidthSectorEta_ + numSectorsPhi_ + tmttWidthLayer_; + bv >>= 2 * tmttWidthInv2R_ + 2 * tmttWidthSectorEta_ + gpNumBinsPhiT_ + tmttWidthLayer_; double z = (bv.val(tmttWidthZ_, 0, true) + .5) * tmttBaseZ_; bv >>= tmttWidthZ_; double phi = (bv.val(tmttWidthPhi_, 0, true) + .5) * tmttBasePhi_; diff --git a/L1Trigger/TrackerDTC/BuildFile.xml b/L1Trigger/TrackerDTC/BuildFile.xml index 5b09818a993ea..d22023419c1d6 100644 --- a/L1Trigger/TrackerDTC/BuildFile.xml +++ b/L1Trigger/TrackerDTC/BuildFile.xml @@ -1,5 +1,6 @@ - + + diff --git a/L1Trigger/TrackerDTC/interface/DTC.h b/L1Trigger/TrackerDTC/interface/DTC.h index 6f5bc72f6f9b7..4b79011ccaf7c 100644 --- a/L1Trigger/TrackerDTC/interface/DTC.h +++ b/L1Trigger/TrackerDTC/interface/DTC.h @@ -5,6 +5,7 @@ #include "L1Trigger/TrackTrigger/interface/Setup.h" #include "L1Trigger/TrackerDTC/interface/LayerEncoding.h" #include "L1Trigger/TrackerDTC/interface/Stub.h" +#include "L1Trigger/TrackerTFP/interface/DataFormats.h" #include #include @@ -23,8 +24,8 @@ namespace trackerDTC { typedef std::vector Stubsss; public: - DTC(const edm::ParameterSet& iConfig, - const tt::Setup* setup, + DTC(const tt::Setup* setup, + const trackerTFP::DataFormats* dataFormats, const LayerEncoding* layerEncoding, int dtcId, const std::vector>& stubsDTC); @@ -43,8 +44,8 @@ namespace trackerDTC { Stub* pop_front(Stubs& stubs); // helper class to store configurations const tt::Setup* setup_; - // enables emulation of truncation - bool enableTruncation_; + // provides dataformats + const trackerTFP::DataFormats* dataFormats_; // outer tracker detector region [0-8] int region_; // outer tracker dtc id in region [0-23] diff --git a/L1Trigger/TrackerDTC/interface/LayerEncoding.h b/L1Trigger/TrackerDTC/interface/LayerEncoding.h index 7e18cff679ba8..57316b8e26bc1 100644 --- a/L1Trigger/TrackerDTC/interface/LayerEncoding.h +++ b/L1Trigger/TrackerDTC/interface/LayerEncoding.h @@ -2,10 +2,8 @@ #define L1Trigger_TrackerDTC_LayerEncoding_h #include "FWCore/Framework/interface/data_default_record_trait.h" -#include "L1Trigger/TrackerDTC/interface/LayerEncodingRcd.h" #include "L1Trigger/TrackTrigger/interface/Setup.h" #include "L1Trigger/TrackTrigger/interface/SensorModule.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" #include @@ -19,10 +17,10 @@ namespace trackerDTC { class LayerEncoding { public: LayerEncoding() {} - LayerEncoding(const edm::ParameterSet& iConfig, const tt::Setup* setup); + LayerEncoding(const tt::Setup* setup); ~LayerEncoding() {} // decode layer id for given sensor module - int decode(tt::SensorModule* sm) const; + int decode(const tt::SensorModule* sm) const; // get encoded layers read by given DTC const std::vector& layers(int dtcId) const { return encodingsLayerId_.at(dtcId % numDTCsPerRegion_); } @@ -37,6 +35,6 @@ namespace trackerDTC { } // namespace trackerDTC -EVENTSETUP_DATA_DEFAULT_RECORD(trackerDTC::LayerEncoding, trackerDTC::LayerEncodingRcd); +EVENTSETUP_DATA_DEFAULT_RECORD(trackerDTC::LayerEncoding, tt::SetupRcd); #endif diff --git a/L1Trigger/TrackerDTC/interface/LayerEncodingRcd.h b/L1Trigger/TrackerDTC/interface/LayerEncodingRcd.h deleted file mode 100644 index b1b374bebcdcc..0000000000000 --- a/L1Trigger/TrackerDTC/interface/LayerEncodingRcd.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef L1Trigger_TrackerDTC_LayerEncodingRcd_h -#define L1Trigger_TrackerDTC_LayerEncodingRcd_h - -#include "FWCore/Framework/interface/DependentRecordImplementation.h" -#include "L1Trigger/TrackTrigger/interface/SetupRcd.h" -#include "FWCore/Utilities/interface/mplVector.h" - -namespace trackerDTC { - - typedef edm::mpl::Vector RcdsLayerEncoding; - - // record of trackerDTC::LayerEncoding - class LayerEncodingRcd : public edm::eventsetup::DependentRecordImplementation { - }; - -} // namespace trackerDTC - -#endif diff --git a/L1Trigger/TrackerDTC/interface/Stub.h b/L1Trigger/TrackerDTC/interface/Stub.h index 1dde69828ff57..3f991393aeb38 100644 --- a/L1Trigger/TrackerDTC/interface/Stub.h +++ b/L1Trigger/TrackerDTC/interface/Stub.h @@ -3,7 +3,7 @@ #include "L1Trigger/TrackTrigger/interface/Setup.h" #include "L1Trigger/TrackerDTC/interface/LayerEncoding.h" -#include "SimDataFormats/Associations/interface/TTTypes.h" +#include "L1Trigger/TrackerTFP/interface/DataFormats.h" #include #include @@ -17,18 +17,27 @@ namespace trackerDTC { */ class Stub { public: - Stub(const edm::ParameterSet&, const tt::Setup*, const LayerEncoding*, tt::SensorModule*, const TTStubRef&); + Stub(const trackerTFP::DataFormats*, const tt::SensorModule*, const TTStubRef&); + Stub(const tt::Setup*, + const trackerTFP::DataFormats*, + const LayerEncoding*, + const tt::SensorModule*, + const TTStubRef&); ~Stub() {} // underlying TTStubRef - TTStubRef ttStubRef() const { return ttStubRef_; } + const TTStubRef& ttStubRef() const { return ttStubRef_; } // did pass pt and eta cut bool valid() const { return valid_; } // stub bend in quarter pitch units int bend() const { return bend_; } // bit accurate representation of Stub - tt::Frame frame(int region) const; + tt::FrameStub frame(int region) const; // checks stubs region assignment - bool inRegion(int region) const; + bool inRegion(int region) const { return regions_[region]; } + // range of stub extrapolated phi to radius chosenRofPhi in rad + std::pair phiT() const { return phiT_; } + // stub phi w.r.t. detector region centre in rad + double phi() const { return phi_; } private: // truncates double precision to f/w integer equivalent @@ -39,14 +48,14 @@ namespace trackerDTC { tt::Frame formatTMTT(int region) const; // stores, calculates and provides run-time constants const tt::Setup* setup_; + // helper class to extract structured data from tt::Frames + const trackerTFP::DataFormats* dataFormats_; // class to encode layer ids used between DTC and TFP in Hybrid const LayerEncoding* layerEncoding_; // representation of an outer tracker sensormodule - tt::SensorModule* sm_; + const tt::SensorModule* sm_; // underlying TTStubRef - TTStubRef ttStubRef_; - // chosen TT algorithm - bool hybrid_; + const TTStubRef ttStubRef_; // passes pt and eta cut bool valid_; // column number in pitch units @@ -73,12 +82,12 @@ namespace trackerDTC { double d_; // range of stub inv2R in 1/cm std::pair inv2R_; - // range of stub cot(theta) - std::pair cot_; - // range of stub extrapolated phi to radius chosenRofPhi in rad + // range of stub extrapolated phi to radius chosenRofPhi wrt detector nonant center in rad std::pair phiT_; + // range of stub extrapolated z to radius chosenRofZ in cm + std::pair zT_; // shared regions this stub belongs to [0-1] - std::vector regions_; + TTBV regions_; }; } // namespace trackerDTC diff --git a/L1Trigger/TrackerDTC/plugins/ProducerDTC.cc b/L1Trigger/TrackerDTC/plugins/ProducerDTC.cc new file mode 100644 index 0000000000000..a783dcde007c5 --- /dev/null +++ b/L1Trigger/TrackerDTC/plugins/ProducerDTC.cc @@ -0,0 +1,110 @@ +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Utilities/interface/EDPutToken.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/DetId/interface/DetId.h" + +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "DataFormats/L1TrackTrigger/interface/TTDTC.h" +#include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackTrigger/interface/SensorModule.h" +#include "L1Trigger/TrackerDTC/interface/LayerEncoding.h" +#include "L1Trigger/TrackerDTC/interface/DTC.h" +#include "L1Trigger/TrackerTFP/interface/DataFormats.h" + +#include +#include +#include +#include +#include + +namespace trackerDTC { + + /*! \class trackerDTC::ProducerDTC + * \brief Class to produce hardware like structured TTStub Collection used by Track Trigger emulators + * \author Thomas Schuh + * \date 2020, Jan + */ + class ProducerDTC : public edm::stream::EDProducer<> { + public: + explicit ProducerDTC(const edm::ParameterSet&); + ~ProducerDTC() override {} + + private: + void produce(edm::Event&, const edm::EventSetup&) override; + // ED input token of TTStubs + edm::EDGetTokenT edGetToken_; + // ED output token for accepted stubs + edm::EDPutTokenT edPutTokenAccepted_; + // ED output token for lost stubs + edm::EDPutTokenT edPutTokenLost_; + // Setup token + edm::ESGetToken esGetTokenSetup_; + // DataFormats token + edm::ESGetToken esGetTokenDataFormats_; + // LayerEncoding token + edm::ESGetToken esGetTokenLayerEncoding_; + }; + + ProducerDTC::ProducerDTC(const edm::ParameterSet& iConfig) { + // book in- and output ED products + const auto& inputTag = iConfig.getParameter("InputTag"); + const auto& branchAccepted = iConfig.getParameter("BranchAccepted"); + const auto& branchLost = iConfig.getParameter("BranchLost"); + edGetToken_ = consumes(inputTag); + edPutTokenAccepted_ = produces(branchAccepted); + edPutTokenLost_ = produces(branchLost); + // book ES products + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + esGetTokenLayerEncoding_ = esConsumes(); + } + + void ProducerDTC::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + // helper class to store configurations + const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_); + // helper class to extract structured data from tt::Frames + const trackerTFP::DataFormats* dataFormats = &iSetup.getData(esGetTokenDataFormats_); + // class to encode layer ids used between DTC and TFP in Hybrid + const LayerEncoding* layerEncoding = &iSetup.getData(esGetTokenLayerEncoding_); + // empty DTC products + TTDTC productAccepted = setup->ttDTC(); + TTDTC productLost = setup->ttDTC(); + // read in stub collection + edm::Handle handle; + iEvent.getByToken(edGetToken_, handle); + // apply cabling map, reorganise stub collections + std::vector>> stubsDTCs( + setup->numDTCs(), std::vector>(setup->numModulesPerDTC())); + for (auto module = handle->begin(); module != handle->end(); module++) { + // DetSetVec->detId + 1 = tk layout det id + const DetId detId = module->detId() + setup->offsetDetIdDSV(); + // corresponding sensor module + tt::SensorModule* sm = setup->sensorModule(detId); + // empty stub collection + std::vector& stubsModule = stubsDTCs[sm->dtcId()][sm->modId()]; + stubsModule.reserve(module->size()); + for (TTStubDetSet::const_iterator ttStub = module->begin(); ttStub != module->end(); ttStub++) + stubsModule.emplace_back(makeRefTo(handle, ttStub)); + } + // board level processing + for (int dtcId = 0; dtcId < setup->numDTCs(); dtcId++) { + // create single outer tracker DTC board + DTC dtc(setup, dataFormats, layerEncoding, dtcId, stubsDTCs.at(dtcId)); + // route stubs and fill products + dtc.produce(productAccepted, productLost); + } + // store ED products + iEvent.emplace(edPutTokenAccepted_, std::move(productAccepted)); + iEvent.emplace(edPutTokenLost_, std::move(productLost)); + } + +} // namespace trackerDTC + +DEFINE_FWK_MODULE(trackerDTC::ProducerDTC); diff --git a/L1Trigger/TrackerDTC/plugins/ProducerED.cc b/L1Trigger/TrackerDTC/plugins/ProducerED.cc deleted file mode 100644 index 8017496fc3358..0000000000000 --- a/L1Trigger/TrackerDTC/plugins/ProducerED.cc +++ /dev/null @@ -1,124 +0,0 @@ -#include "FWCore/Framework/interface/stream/EDProducer.h" -#include "FWCore/Framework/interface/Run.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/Utilities/interface/EDGetToken.h" -#include "FWCore/Utilities/interface/EDPutToken.h" -#include "FWCore/Utilities/interface/ESGetToken.h" -#include "DataFormats/Common/interface/Handle.h" -#include "DataFormats/DetId/interface/DetId.h" - -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" -#include "DataFormats/L1TrackTrigger/interface/TTDTC.h" -#include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackTrigger/interface/SensorModule.h" -#include "L1Trigger/TrackerDTC/interface/LayerEncoding.h" -#include "L1Trigger/TrackerDTC/interface/DTC.h" - -#include -#include -#include -#include -#include - -using namespace std; -using namespace edm; -using namespace tt; - -namespace trackerDTC { - - /*! \class trackerDTC::ProducerED - * \brief Class to produce hardware like structured TTStub Collection used by Track Trigger emulators - * \author Thomas Schuh - * \date 2020, Jan - */ - class ProducerED : public stream::EDProducer<> { - public: - explicit ProducerED(const ParameterSet&); - ~ProducerED() override {} - - private: - void beginRun(const Run&, const EventSetup&) override; - void produce(Event&, const EventSetup&) override; - void endJob() {} - // helper class to store configurations - const Setup* setup_ = nullptr; - // class to encode layer ids used between DTC and TFP in Hybrid - const LayerEncoding* layerEncoding_ = nullptr; - // ED input token of TTStubs - EDGetTokenT edGetToken_; - // ED output token for accepted stubs - EDPutTokenT edPutTokenAccepted_; - // ED output token for lost stubs - EDPutTokenT edPutTokenLost_; - // Setup token - ESGetToken esGetTokenSetup_; - // LayerEncoding token - ESGetToken esGetTokenLayerEncoding_; - // configuration - ParameterSet iConfig_; - }; - - ProducerED::ProducerED(const ParameterSet& iConfig) : iConfig_(iConfig) { - // book in- and output ED products - const auto& inputTag = iConfig.getParameter("InputTag"); - const auto& branchAccepted = iConfig.getParameter("BranchAccepted"); - const auto& branchLost = iConfig.getParameter("BranchLost"); - edGetToken_ = consumes(inputTag); - edPutTokenAccepted_ = produces(branchAccepted); - edPutTokenLost_ = produces(branchLost); - // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenLayerEncoding_ = esConsumes(); - } - - void ProducerED::beginRun(const Run& iRun, const EventSetup& iSetup) { - setup_ = &iSetup.getData(esGetTokenSetup_); - if (!setup_->configurationSupported()) - return; - // check process history if desired - if (iConfig_.getParameter("CheckHistory")) - setup_->checkHistory(iRun.processHistory()); - layerEncoding_ = &iSetup.getData(esGetTokenLayerEncoding_); - } - - void ProducerED::produce(Event& iEvent, const EventSetup& iSetup) { - // empty DTC products - TTDTC productAccepted = setup_->ttDTC(); - TTDTC productLost = setup_->ttDTC(); - if (setup_->configurationSupported()) { - // read in stub collection - Handle handle; - iEvent.getByToken(edGetToken_, handle); - // apply cabling map, reorganise stub collections - vector>> stubsDTCs(setup_->numDTCs(), - vector>(setup_->numModulesPerDTC())); - for (auto module = handle->begin(); module != handle->end(); module++) { - // DetSetVec->detId + 1 = tk layout det id - const DetId detId = module->detId() + setup_->offsetDetIdDSV(); - // corresponding sensor module - SensorModule* sm = setup_->sensorModule(detId); - // empty stub collection - vector& stubsModule = stubsDTCs[sm->dtcId()][sm->modId()]; - stubsModule.reserve(module->size()); - for (TTStubDetSet::const_iterator ttStub = module->begin(); ttStub != module->end(); ttStub++) - stubsModule.emplace_back(makeRefTo(handle, ttStub)); - } - // board level processing - for (int dtcId = 0; dtcId < setup_->numDTCs(); dtcId++) { - // create single outer tracker DTC board - DTC dtc(iConfig_, setup_, layerEncoding_, dtcId, stubsDTCs.at(dtcId)); - // route stubs and fill products - dtc.produce(productAccepted, productLost); - } - } - // store ED products - iEvent.emplace(edPutTokenAccepted_, std::move(productAccepted)); - iEvent.emplace(edPutTokenLost_, std::move(productLost)); - } - -} // namespace trackerDTC - -DEFINE_FWK_MODULE(trackerDTC::ProducerED); diff --git a/L1Trigger/TrackerDTC/plugins/ProducerLayerEncoding.cc b/L1Trigger/TrackerDTC/plugins/ProducerLayerEncoding.cc index 2adbd96ce57fd..c50f80e29db49 100644 --- a/L1Trigger/TrackerDTC/plugins/ProducerLayerEncoding.cc +++ b/L1Trigger/TrackerDTC/plugins/ProducerLayerEncoding.cc @@ -8,10 +8,6 @@ #include -using namespace std; -using namespace edm; -using namespace tt; - namespace trackerDTC { /*! \class trackerDTC::ProducerLayerEncoding @@ -19,25 +15,24 @@ namespace trackerDTC { * \author Thomas Schuh * \date 2021, April */ - class ProducerLayerEncoding : public ESProducer { + class ProducerLayerEncoding : public edm::ESProducer { public: - ProducerLayerEncoding(const ParameterSet& iConfig); + ProducerLayerEncoding(const edm::ParameterSet& iConfig); ~ProducerLayerEncoding() override {} - unique_ptr produce(const LayerEncodingRcd& rcd); + std::unique_ptr produce(const tt::SetupRcd& rcd); private: - const ParameterSet iConfig_; - ESGetToken esGetToken_; + edm::ESGetToken esGetToken_; }; - ProducerLayerEncoding::ProducerLayerEncoding(const ParameterSet& iConfig) : iConfig_(iConfig) { + ProducerLayerEncoding::ProducerLayerEncoding(const edm::ParameterSet& iConfig) { auto cc = setWhatProduced(this); esGetToken_ = cc.consumes(); } - unique_ptr ProducerLayerEncoding::produce(const LayerEncodingRcd& rcd) { - const Setup* setup = &rcd.get(esGetToken_); - return make_unique(iConfig_, setup); + std::unique_ptr ProducerLayerEncoding::produce(const tt::SetupRcd& rcd) { + const tt::Setup* setup = &rcd.get(esGetToken_); + return std::make_unique(setup); } } // namespace trackerDTC diff --git a/L1Trigger/TrackerDTC/python/AnalyzerDAQ_cff.py b/L1Trigger/TrackerDTC/python/AnalyzerDAQ_cff.py index 7c015b9333806..4b7b561e662ff 100644 --- a/L1Trigger/TrackerDTC/python/AnalyzerDAQ_cff.py +++ b/L1Trigger/TrackerDTC/python/AnalyzerDAQ_cff.py @@ -1,6 +1,8 @@ +# EDAnalyzer to analyze TTCluster Occupancies on DTCs, plots cluster occupancy + import FWCore.ParameterSet.Config as cms from L1Trigger.TrackerDTC.AnalyzerDAQ_cfi import TrackerDTCAnalyzerDAQ_params -from L1Trigger.TrackTrigger.ProducerSetup_cff import TrackTriggerSetup +from L1Trigger.TrackTrigger.Setup_cff import TrackTriggerSetup TrackerDTCAnalyzerDAQ = cms.EDAnalyzer('trackerDTC::AnalyzerDAQ', TrackerDTCAnalyzerDAQ_params) diff --git a/L1Trigger/TrackerDTC/python/AnalyzerDAQ_cfi.py b/L1Trigger/TrackerDTC/python/AnalyzerDAQ_cfi.py index 8c03b9126c3e8..9e8ed768f7ac5 100644 --- a/L1Trigger/TrackerDTC/python/AnalyzerDAQ_cfi.py +++ b/L1Trigger/TrackerDTC/python/AnalyzerDAQ_cfi.py @@ -1,3 +1,5 @@ +# configuration for TrackerDTCAnalyzerDAQ + import FWCore.ParameterSet.Config as cms TrackerDTCAnalyzerDAQ_params = cms.PSet ( diff --git a/L1Trigger/TrackerDTC/python/Analyzer_cff.py b/L1Trigger/TrackerDTC/python/Analyzer_cff.py index aaf563eac18ef..9a673c297a2bd 100644 --- a/L1Trigger/TrackerDTC/python/Analyzer_cff.py +++ b/L1Trigger/TrackerDTC/python/Analyzer_cff.py @@ -1,7 +1,9 @@ +# EDAnalyzer for hardware like structured TTStub Collection used by Track Trigger emulators, runs DTC stub emulation, plots performance & stub occupancy + import FWCore.ParameterSet.Config as cms from L1Trigger.TrackerDTC.Analyzer_cfi import TrackerDTCAnalyzer_params -from L1Trigger.TrackerDTC.ProducerED_cfi import TrackerDTCProducer_params -from L1Trigger.TrackTrigger.ProducerSetup_cff import TrackTriggerSetup +from L1Trigger.TrackerDTC.DTC_cfi import TrackerDTC_params +from L1Trigger.TrackTrigger.Setup_cff import TrackTriggerSetup -TrackerDTCAnalyzer = cms.EDAnalyzer('trackerDTC::Analyzer', TrackerDTCAnalyzer_params, TrackerDTCProducer_params) +AnalyzerDTC = cms.EDAnalyzer('trackerDTC::Analyzer', TrackerDTCAnalyzer_params, TrackerDTC_params) diff --git a/L1Trigger/TrackerDTC/python/Analyzer_cfi.py b/L1Trigger/TrackerDTC/python/Analyzer_cfi.py index 4b6a091d0884f..3f87cc24917d3 100644 --- a/L1Trigger/TrackerDTC/python/Analyzer_cfi.py +++ b/L1Trigger/TrackerDTC/python/Analyzer_cfi.py @@ -1,12 +1,13 @@ +# configuration for AnalyzerDTC + import FWCore.ParameterSet.Config as cms TrackerDTCAnalyzer_params = cms.PSet ( - InputTagAccepted = cms.InputTag( "TrackerDTCProducer", "StubAccepted" ), # dtc passed stubs selection - InputTagLost = cms.InputTag( "TrackerDTCProducer", "StubLost" ), # dtc lost stubs selection - InputTagTTStubDetSetVec = cms.InputTag( "TTStubsFromPhase2TrackerDigis", "StubAccepted" ), # original TTStub selection - InputTagTTClusterDetSetVec = cms.InputTag( "TTClustersFromPhase2TrackerDigis", "ClusterInclusive" ), # original TTCluster selection - InputTagTTClusterAssMap = cms.InputTag( "TTClusterAssociatorFromPixelDigis", "ClusterAccepted" ), # tag of AssociationMap between TTCluster and TrackingParticles - UseMCTruth = cms.bool( True ) # eneables analyze of TPs # eneables analyze of TPs + InputTagAccepted = cms.InputTag( "ProducerDTC", "StubAccepted" ), # dtc passed stubs selection + InputTagLost = cms.InputTag( "ProducerDTC", "StubLost" ), # dtc lost stubs selection + InputTagReconstructable = cms.InputTag( "StubAssociator", "Reconstructable" ), # + InputTagSelection = cms.InputTag( "StubAssociator", "UseForAlgEff" ), # + UseMCTruth = cms.bool( True ) # eneables analyze of TPs ) diff --git a/L1Trigger/TrackerDTC/python/Customize_cff.py b/L1Trigger/TrackerDTC/python/Customize_cff.py index b62f897ab5aac..6f95f13148217 100644 --- a/L1Trigger/TrackerDTC/python/Customize_cff.py +++ b/L1Trigger/TrackerDTC/python/Customize_cff.py @@ -1,14 +1,28 @@ +# function to manipilate TrackerDTC emulator to match TMTT configuration and support TMTT data formats + import FWCore.ParameterSet.Config as cms +def setupTMTT(process): + from L1Trigger.TrackerDTC.DTC_cfi import TrackerDTC_params + # use Hybrid or TMTT as TT algorithm + process.TrackTriggerSetup.UseHybrid = False + # min track pt in GeV, also defines region overlap shape + process.TrackTriggerSetup.TrackFinding.MinPt = 3.0 + # cut on stub eta + process.TrackTriggerSetup.TrackFinding.MaxEta = 2.4 + # critical radius defining region overlap shape in cm + process.TrackTriggerSetup.TrackFinding.ChosenRofPhi = 67.24 + + def producerUseTMTT(process): - from L1Trigger.TrackerDTC.ProducerED_cfi import TrackerDTCProducer_params - TrackerDTCProducer_params.UseHybrid = cms.bool( False ) - process.TrackerDTCProducer = cms.EDProducer('trackerDTC::ProducerED', TrackerDTCProducer_params) + from L1Trigger.TrackerDTC.DTC_cfi import TrackerDTC_params + setupTMTT(process) + process.ProducerDTC = cms.EDProducer('trackerDTC::ProducerDTC', TrackerDTC_params) return process def analyzerUseTMTT(process): from L1Trigger.TrackerDTC.Analyzer_cfi import TrackerDTCAnalyzer_params - from L1Trigger.TrackerDTC.ProducerED_cfi import TrackerDTCProducer_params - TrackerDTCProducer_params.UseHybrid = cms.bool( False ) - process.TrackerDTCAnalyzer = cms.EDAnalyzer('trackerDTC::Analyzer', TrackerDTCAnalyzer_params, TrackerDTCProducer_params) + from L1Trigger.TrackerDTC.DTC_cfi import TrackerDTC_params + setupTMTT(process) + process.AnalyzerDTC = cms.EDAnalyzer('trackerDTC::Analyzer', TrackerDTCAnalyzer_params, TrackerDTC_params) return process diff --git a/L1Trigger/TrackerDTC/python/ProducerED_cff.py b/L1Trigger/TrackerDTC/python/DTC_cff.py similarity index 51% rename from L1Trigger/TrackerDTC/python/ProducerED_cff.py rename to L1Trigger/TrackerDTC/python/DTC_cff.py index e559be729703f..3fb8662f13b8d 100644 --- a/L1Trigger/TrackerDTC/python/ProducerED_cff.py +++ b/L1Trigger/TrackerDTC/python/DTC_cff.py @@ -6,8 +6,9 @@ #=== Import default values for all parameters & define EDProducer. -from L1Trigger.TrackerDTC.ProducerED_cfi import TrackerDTCProducer_params -from L1Trigger.TrackTrigger.ProducerSetup_cff import TrackTriggerSetup -from L1Trigger.TrackerDTC.ProducerLayerEncoding_cff import TrackerDTCLayerEncoding +from L1Trigger.TrackerDTC.DTC_cfi import TrackerDTC_params +from L1Trigger.TrackTrigger.Setup_cff import TrackTriggerSetup +from L1Trigger.TrackerDTC.LayerEncoding_cff import TrackerDTCLayerEncoding +from L1Trigger.TrackerTFP.DataFormats_cff import TrackTriggerDataFormats -TrackerDTCProducer = cms.EDProducer('trackerDTC::ProducerED', TrackerDTCProducer_params) +ProducerDTC = cms.EDProducer('trackerDTC::ProducerDTC', TrackerDTC_params) diff --git a/L1Trigger/TrackerDTC/python/DTC_cfi.py b/L1Trigger/TrackerDTC/python/DTC_cfi.py new file mode 100644 index 0000000000000..3db62785cfad3 --- /dev/null +++ b/L1Trigger/TrackerDTC/python/DTC_cfi.py @@ -0,0 +1,11 @@ +# configuration for ProducerDTC + +import FWCore.ParameterSet.Config as cms + +TrackerDTC_params = cms.PSet ( + + InputTag = cms.InputTag( "TTStubsFromPhase2TrackerDigis", "StubAccepted" ), # original TTStub selection + BranchAccepted = cms.string ( "StubAccepted" ), # label for prodcut with passed stubs + BranchLost = cms.string ( "StubLost" ), # label for prodcut with lost stubs + +) diff --git a/L1Trigger/TrackerDTC/python/LayerEncoding_cff.py b/L1Trigger/TrackerDTC/python/LayerEncoding_cff.py new file mode 100644 index 0000000000000..01467ecaa6436 --- /dev/null +++ b/L1Trigger/TrackerDTC/python/LayerEncoding_cff.py @@ -0,0 +1,3 @@ +import FWCore.ParameterSet.Config as cms + +TrackerDTCLayerEncoding = cms.ESProducer("trackerDTC::ProducerLayerEncoding") diff --git a/L1Trigger/TrackerDTC/python/ProducerED_cfi.py b/L1Trigger/TrackerDTC/python/ProducerED_cfi.py deleted file mode 100644 index ba6303791d629..0000000000000 --- a/L1Trigger/TrackerDTC/python/ProducerED_cfi.py +++ /dev/null @@ -1,12 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -TrackerDTCProducer_params = cms.PSet ( - - InputTag = cms.InputTag( "TTStubsFromPhase2TrackerDigis", "StubAccepted" ), # original TTStub selection - BranchAccepted = cms.string ( "StubAccepted" ), # label for prodcut with passed stubs - BranchLost = cms.string ( "StubLost" ), # label for prodcut with lost stubs - CheckHistory = cms.bool ( False ), # checks if input sample production is configured as current process - UseHybrid = cms.bool ( True ), # use Hybrid or TMTT as TT algorithm - EnableTruncation = cms.bool ( True ) # enable emulation of truncation, lost stubs are filled in BranchLost - -) diff --git a/L1Trigger/TrackerDTC/python/ProducerLayerEncoding_cff.py b/L1Trigger/TrackerDTC/python/ProducerLayerEncoding_cff.py deleted file mode 100644 index 49935c483846d..0000000000000 --- a/L1Trigger/TrackerDTC/python/ProducerLayerEncoding_cff.py +++ /dev/null @@ -1,5 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -from L1Trigger.TrackerDTC.ProducerLayerEncoding_cfi import TrackerDTCLayerEncoding_params - -TrackerDTCLayerEncoding = cms.ESProducer("trackerDTC::ProducerLayerEncoding", TrackerDTCLayerEncoding_params) diff --git a/L1Trigger/TrackerDTC/python/ProducerLayerEncoding_cfi.py b/L1Trigger/TrackerDTC/python/ProducerLayerEncoding_cfi.py deleted file mode 100644 index 8f82c976fe812..0000000000000 --- a/L1Trigger/TrackerDTC/python/ProducerLayerEncoding_cfi.py +++ /dev/null @@ -1,7 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -TrackerDTCLayerEncoding_params = cms.PSet ( - - - -) diff --git a/L1Trigger/TrackerDTC/src/DTC.cc b/L1Trigger/TrackerDTC/src/DTC.cc index babcea183e29f..2d84d4c970317 100644 --- a/L1Trigger/TrackerDTC/src/DTC.cc +++ b/L1Trigger/TrackerDTC/src/DTC.cc @@ -5,35 +5,31 @@ #include #include -using namespace std; -using namespace edm; -using namespace tt; - namespace trackerDTC { - DTC::DTC(const ParameterSet& iConfig, - const Setup* setup, + DTC::DTC(const tt::Setup* setup, + const trackerTFP::DataFormats* dataFormats, const LayerEncoding* layerEncoding, int dtcId, const std::vector>& stubsDTC) : setup_(setup), - enableTruncation_(iConfig.getParameter("EnableTruncation")), + dataFormats_(dataFormats), region_(dtcId / setup->numDTCsPerRegion()), board_(dtcId % setup->numDTCsPerRegion()), modules_(setup->dtcModules(dtcId)), input_(setup->dtcNumRoutingBlocks(), Stubss(setup->dtcNumModulesPerRoutingBlock())), lost_(setup->numOverlappingRegions()) { // count number of stubs on this dtc - auto acc = [](int sum, const vector& stubsModule) { return sum + stubsModule.size(); }; - const int nStubs = accumulate(stubsDTC.begin(), stubsDTC.end(), 0, acc); + auto acc = [](int sum, const std::vector& stubsModule) { return sum + stubsModule.size(); }; + const int nStubs = std::accumulate(stubsDTC.begin(), stubsDTC.end(), 0, acc); stubs_.reserve(nStubs); // convert and assign Stubs to DTC routing block channel for (int modId = 0; modId < setup->numModulesPerDTC(); modId++) { - const vector& ttStubRefs = stubsDTC[modId]; + const std::vector& ttStubRefs = stubsDTC[modId]; if (ttStubRefs.empty()) continue; // Module which produced this ttStubRefs - SensorModule* module = modules_.at(modId); + const tt::SensorModule* module = modules_.at(modId); // DTC routing block id [0-1] const int blockId = modId / setup->dtcNumModulesPerRoutingBlock(); // DTC routing blockc channel id [0-35] @@ -41,23 +37,26 @@ namespace trackerDTC { // convert TTStubs and fill input channel Stubs& stubs = input_[blockId][channelId]; for (const TTStubRef& ttStubRef : ttStubRefs) { - stubs_.emplace_back(iConfig, setup, layerEncoding, module, ttStubRef); + stubs_.emplace_back(setup, dataFormats, layerEncoding, module, ttStubRef); Stub& stub = stubs_.back(); if (stub.valid()) // passed pt and eta cut stubs.push_back(&stub); } // sort stubs by bend - sort(stubs.begin(), stubs.end(), [](Stub* lhs, Stub* rhs) { return abs(lhs->bend()) < abs(rhs->bend()); }); + std::sort(stubs.begin(), stubs.end(), [](Stub* lhs, Stub* rhs) { + return std::abs(lhs->bend()) < std::abs(rhs->bend()); + }); // truncate stubs if desired - if (!enableTruncation_ || (int)stubs.size() <= setup->numFramesFE()) + if (!setup_->enableTruncation() || (int)stubs.size() <= setup->numFramesFE()) continue; // begin of truncated stubs - const auto limit = next(stubs.begin(), setup->numFramesFE()); + const auto limit = std::next(stubs.begin(), setup->numFramesFE()); // copy truncated stubs into lost output channel for (int region = 0; region < setup->numOverlappingRegions(); region++) - copy_if( - limit, stubs.end(), back_inserter(lost_[region]), [region](Stub* stub) { return stub->inRegion(region); }); + std::copy_if(limit, stubs.end(), std::back_inserter(lost_[region]), [region](Stub* stub) { + return stub->inRegion(region); + }); // remove truncated stubs form input channel stubs.erase(limit, stubs.end()); } @@ -73,7 +72,7 @@ namespace trackerDTC { // copy lost stubs during merge into lost output channel for (int region = 0; region < setup_->numOverlappingRegions(); region++) { auto inRegion = [region](Stub* stub) { return stub->inRegion(region); }; - copy_if(lost.begin(), lost.end(), back_inserter(lost_[region]), inRegion); + std::copy_if(lost.begin(), lost.end(), std::back_inserter(lost_[region]), inRegion); } // router step 2: merges stubs of all routing blocks and splits stubs into one stream per overlapping region Stubss regionStubs(setup_->numOverlappingRegions()); @@ -88,17 +87,17 @@ namespace trackerDTC { // for each input one fifo Stubss stacks(inputs.size()); // clock accurate firmware emulation, each while trip describes one clock tick - while (!all_of(inputs.begin(), inputs.end(), [](const Stubs& channel) { return channel.empty(); }) or - !all_of(stacks.begin(), stacks.end(), [](const Stubs& channel) { return channel.empty(); })) { + while (!std::all_of(inputs.begin(), inputs.end(), [](const Stubs& channel) { return channel.empty(); }) || + !std::all_of(stacks.begin(), stacks.end(), [](const Stubs& channel) { return channel.empty(); })) { // fill fifos - for (int iInput = 0; iInput < (int)inputs.size(); iInput++) { + for (int iInput = 0; iInput < static_cast(inputs.size()); iInput++) { Stubs& input = inputs[iInput]; Stubs& stack = stacks[iInput]; if (input.empty()) continue; Stub* stub = pop_front(input); if (stub) { - if (enableTruncation_ && (int)stack.size() == setup_->dtcDepthMemory() - 1) + if (setup_->enableTruncation() && static_cast(stack.size()) == setup_->dtcDepthMemory() - 1) // kill current first stub when fifo overflows lost.push_back(pop_front(stack)); stack.push_back(stub); @@ -120,9 +119,9 @@ namespace trackerDTC { output.push_back(nullptr); } // truncate if desired - if (enableTruncation_ && (int)output.size() > setup_->numFramesIO()) { - const auto limit = next(output.begin(), setup_->numFramesIO()); - copy_if(limit, output.end(), back_inserter(lost), [](Stub* stub) { return stub; }); + if (setup_->enableTruncation() && (int)output.size() > setup_->numFramesIOHigh()) { + const auto limit = std::next(output.begin(), setup_->numFramesIOHigh()); + std::copy_if(limit, output.end(), std::back_inserter(lost), [](Stub* stub) { return stub; }); output.erase(limit, output.end()); } // remove all gaps between end and last stub @@ -140,7 +139,7 @@ namespace trackerDTC { int i(0); for (Stubs& input : inputs) { Stubs& stream = streams[i++]; - transform(input.begin(), input.end(), back_inserter(stream), regionMask); + std::transform(input.begin(), input.end(), back_inserter(stream), regionMask); for (auto it = stream.end(); it != stream.begin();) it = (*--it) ? stream.begin() : stream.erase(it); } @@ -151,13 +150,11 @@ namespace trackerDTC { // conversion from Stubss to TTDTC void DTC::produce(const Stubss& stubss, TTDTC& product) { int channel(0); - auto toFrame = [&channel](Stub* stub) { - return stub ? make_pair(stub->ttStubRef(), stub->frame(channel)) : FrameStub(); - }; + auto toFrame = [&channel](Stub* stub) { return stub ? stub->frame(channel) : tt::FrameStub(); }; for (const Stubs& stubs : stubss) { - StreamStub stream; + tt::StreamStub stream; stream.reserve(stubs.size()); - transform(stubs.begin(), stubs.end(), back_inserter(stream), toFrame); + std::transform(stubs.begin(), stubs.end(), std::back_inserter(stream), toFrame); product.setStream(region_, board_, channel++, stream); } } diff --git a/L1Trigger/TrackerDTC/src/LayerEncoding.cc b/L1Trigger/TrackerDTC/src/LayerEncoding.cc index c72d8968c038e..a9a00f131987b 100644 --- a/L1Trigger/TrackerDTC/src/LayerEncoding.cc +++ b/L1Trigger/TrackerDTC/src/LayerEncoding.cc @@ -7,25 +7,20 @@ #include #include -using namespace std; -using namespace edm; -using namespace tt; - namespace trackerDTC { - LayerEncoding::LayerEncoding(const ParameterSet& iConfig, const Setup* setup) - : setup_(setup), numDTCsPerRegion_(setup->numDTCsPerRegion()) { + LayerEncoding::LayerEncoding(const tt::Setup* setup) : setup_(setup), numDTCsPerRegion_(setup->numDTCsPerRegion()) { encodingsLayerId_.reserve(numDTCsPerRegion_); for (int dtcInRegion = 0; dtcInRegion < setup->numDTCsPerRegion(); dtcInRegion++) { - set encodingLayerId; + std::set encodingLayerId; for (int region = 0; region < setup->numRegions(); region++) { const int dtcId = dtcInRegion + region * setup->numDTCsPerRegion(); - const vector& modules = setup->dtcModules(dtcId); - for (SensorModule* sm : modules) + const std::vector& modules = setup->dtcModules(dtcId); + for (tt::SensorModule* sm : modules) encodingLayerId.insert(sm->layerId()); } // check configuration - if ((int)encodingLayerId.size() > setup->hybridNumLayers()) { + if (static_cast(encodingLayerId.size()) > setup->hybridNumLayers()) { cms::Exception exception("overflow"); exception << "Cabling map connects more than " << setup->hybridNumLayers() << " layers to a DTC."; exception.addContext("trackerDTC::LayerEncoding::LayerEncoding"); @@ -36,10 +31,10 @@ namespace trackerDTC { } // decode layer id for given sensor module - int LayerEncoding::decode(SensorModule* sm) const { - const vector& encoding = encodingsLayerId_.at(sm->dtcId() % setup_->numDTCsPerRegion()); - const auto pos = find(encoding.begin(), encoding.end(), sm->layerId()); - return distance(encoding.begin(), pos); + int LayerEncoding::decode(const tt::SensorModule* sm) const { + const std::vector& encoding = encodingsLayerId_.at(sm->dtcId() % setup_->numDTCsPerRegion()); + const auto pos = std::find(encoding.begin(), encoding.end(), sm->layerId()); + return std::distance(encoding.begin(), pos); } } // namespace trackerDTC diff --git a/L1Trigger/TrackerDTC/src/LayerEncodingRcd.cc b/L1Trigger/TrackerDTC/src/LayerEncodingRcd.cc deleted file mode 100644 index 1f00389ed818c..0000000000000 --- a/L1Trigger/TrackerDTC/src/LayerEncodingRcd.cc +++ /dev/null @@ -1,4 +0,0 @@ -#include "L1Trigger/TrackerDTC/interface/LayerEncodingRcd.h" -#include "FWCore/Framework/interface/eventsetuprecord_registration_macro.h" - -EVENTSETUP_RECORD_REG(trackerDTC::LayerEncodingRcd); diff --git a/L1Trigger/TrackerDTC/src/Stub.cc b/L1Trigger/TrackerDTC/src/Stub.cc index 3d8fda73d2574..420bc87f1d8c6 100644 --- a/L1Trigger/TrackerDTC/src/Stub.cc +++ b/L1Trigger/TrackerDTC/src/Stub.cc @@ -5,168 +5,152 @@ #include #include -using namespace edm; -using namespace std; -using namespace tt; - namespace trackerDTC { - Stub::Stub(const ParameterSet& iConfig, - const Setup* setup, - const LayerEncoding* layerEncoding, - SensorModule* sm, - const TTStubRef& ttStubRef) - : setup_(setup), - layerEncoding_(layerEncoding), + Stub::Stub(const trackerTFP::DataFormats* dataFormats, const tt::SensorModule* sm, const TTStubRef& ttStubRef) + : setup_(dataFormats->setup()), + dataFormats_(dataFormats), + layerEncoding_(nullptr), sm_(sm), ttStubRef_(ttStubRef), - hybrid_(iConfig.getParameter("UseHybrid")), - valid_(true) { - regions_.reserve(setup->numOverlappingRegions()); + valid_(true), + regions_(0, setup_->numOverlappingRegions()) { + const trackerTFP::DataFormat& dfR = dataFormats_->format(trackerTFP::Variable::r, trackerTFP::Process::dtc); + const trackerTFP::DataFormat& dfPhi = dataFormats_->format(trackerTFP::Variable::phi, trackerTFP::Process::dtc); + const trackerTFP::DataFormat& dfZ = dataFormats_->format(trackerTFP::Variable::z, trackerTFP::Process::dtc); + const trackerTFP::DataFormat& dfInv2R = dataFormats_->format(trackerTFP::Variable::inv2R, trackerTFP::Process::ht); // get stub local coordinates const MeasurementPoint& mp = ttStubRef->clusterRef(0)->findAverageLocalCoordinatesCentered(); - // convert to uniformed local coordinates - // column number in pitch units - col_ = (int)floor(pow(-1, sm->signCol()) * (mp.y() - sm->numColumns() / 2) / setup->baseCol()); + col_ = std::floor(std::pow(-1, sm_->signCol()) * (mp.y() - sm_->numColumns() / 2) / setup_->baseCol()); // row number in half pitch units - row_ = (int)floor(pow(-1, sm->signRow()) * (mp.x() - sm->numRows() / 2) / setup->baseRow()); + row_ = std::floor(std::pow(-1, sm_->signRow()) * (mp.x() - sm_->numRows() / 2) / setup_->baseRow()); // bend number in quarter pitch units - bend_ = (int)floor(pow(-1, sm->signBend()) * (ttStubRef->bendBE()) / setup->baseBend()); + bend_ = std::floor(std::pow(-1, sm_->signBend()) * (ttStubRef->bendBE()) / setup_->baseBend()); // reduced row number for look up - rowLUT_ = (int)floor((double)row_ / pow(2., setup->widthRow() - setup->dtcWidthRowLUT())); + rowLUT_ = std::floor(static_cast(row_) / std::pow(2., setup_->widthRow() - setup_->dtcWidthRowLUT())); // sub row number inside reduced row number - rowSub_ = row_ - (rowLUT_ + .5) * pow(2, setup->widthRow() - setup->dtcWidthRowLUT()); - + rowSub_ = row_ - (rowLUT_ + .5) * std::pow(2, setup_->widthRow() - setup_->dtcWidthRowLUT()); // convert local to global coordinates - - const double y = (col_ + .5) * setup->baseCol() * sm->pitchCol(); + const double y = (col_ + .5) * setup_->baseCol() * sm_->pitchCol(); // radius of a column of strips/pixel in cm - d_ = sm->r() + y * sm->sinTilt(); + d_ = sm_->r() + y * sm_->sinTilt(); // stub z in cm - z_ = digi(sm->z() + y * sm->cosTilt(), setup->tmttBaseZ()); - - const double x0 = rowLUT_ * setup->baseRow() * setup->dtcNumMergedRows() * sm->pitchRow(); - const double x1 = (rowLUT_ + 1) * setup->baseRow() * setup->dtcNumMergedRows() * sm->pitchRow(); - const double x = (rowLUT_ + .5) * setup->baseRow() * setup->dtcNumMergedRows() * sm->pitchRow(); - // stub r in cm - r_ = sqrt(d_ * d_ + x * x); - - const double phi0 = sm->phi() + atan2(x0, d_); - const double phi1 = sm->phi() + atan2(x1, d_); + z_ = dfZ.digi(sm_->z() + y * sm_->cosTilt()); + const double x = (rowLUT_ + .5) * setup_->baseRow() * setup_->dtcNumMergedRows() * sm_->pitchRow(); + // stub r wrt chosen RofPhi in cm + r_ = dfR.digi(std::sqrt(d_ * d_ + x * x) - setup_->chosenRofPhi()); + const double x0 = rowLUT_ * setup_->baseRow() * setup_->dtcNumMergedRows() * sm_->pitchRow(); + const double x1 = (rowLUT_ + 1) * setup_->baseRow() * setup_->dtcNumMergedRows() * sm_->pitchRow(); + const double phi0 = sm_->phi() + std::atan2(x0, d_); + const double phi1 = sm_->phi() + std::atan2(x1, d_); const double c = (phi0 + phi1) / 2.; - const double m = (phi1 - phi0) / setup->dtcNumMergedRows(); - + const double m = (phi1 - phi0) / setup_->dtcNumMergedRows(); // intercept of linearized stub phi in rad - c_ = digi(c, setup->tmttBasePhi()); + c_ = digi(c, dfPhi.base() / 2.); // slope of linearized stub phi in rad / strip - m_ = digi(m, setup->dtcBaseM()); - - if (hybrid_) { - if (abs(z_ / r_) > setup->hybridMaxCot()) - // did not pass eta cut - valid_ = false; - } else { - // extrapolated z at radius T assuming z0=0 - const double zT = setup->chosenRofZ() * z_ / r_; - // extrapolated z0 window at radius T - const double dZT = setup->beamWindowZ() * abs(1. - setup->chosenRofZ() / r_); - double zTMin = zT - dZT; - double zTMax = zT + dZT; - if (zTMin >= setup->maxZT() || zTMax < -setup->maxZT()) - // did not pass "eta" cut - valid_ = false; - else { - zTMin = max(zTMin, -setup->maxZT()); - zTMax = min(zTMax, setup->maxZT()); - } - // range of stub cot(theta) - cot_ = {zTMin / setup->chosenRofZ(), zTMax / setup->chosenRofZ()}; - } - - // stub r w.r.t. chosenRofPhi in cm - static const double chosenRofPhi = hybrid_ ? setup->hybridChosenRofPhi() : setup->chosenRofPhi(); - r_ = digi(r_ - chosenRofPhi, setup->tmttBaseR()); - + m_ = digi(m, setup_->dtcBaseM()); + // stub phi w.r.t. detector region centre in rad + phi_ = dfPhi.digi(c_ + rowSub_ * m_); + // assaign stub to processing regions // radial (cylindrical) component of sensor separation - const double dr = sm->sep() / (sm->cosTilt() - sm->sinTilt() * z_ / d_); + const double dr = sm_->sep() / (sm_->cosTilt() - sm_->sinTilt() * z_ / d_); // converts bend into inv2R in 1/cm - const double inv2ROverBend = sm->pitchRow() / dr / d_; + const double inv2ROverBend = sm_->pitchRow() / dr / d_; // inv2R in 1/cm - const double inv2R = -bend_ * setup->baseBend() * inv2ROverBend; + const double inv2R = -bend_ * setup_->baseBend() * inv2ROverBend; // inv2R uncertainty in 1/cm - const double dInv2R = setup->bendCut() * inv2ROverBend; - const double minPt = hybrid_ ? setup->hybridMinPtStub() : setup->minPt(); - const double maxInv2R = setup->invPtToDphi() / minPt - setup->dtcBaseInv2R() / 2.; - double inv2RMin = digi(inv2R - dInv2R, setup->dtcBaseInv2R()); - double inv2RMax = digi(inv2R + dInv2R, setup->dtcBaseInv2R()); - if (inv2RMin > maxInv2R || inv2RMax < -maxInv2R) { - // did not pass pt cut + const double dInv2R = setup_->bendCut() * inv2ROverBend; + inv2R_.first = dfInv2R.digi(inv2R - dInv2R); + inv2R_.second = dfInv2R.digi(inv2R + dInv2R); + const double maxInv2R = dfInv2R.range() / 2.; + // cut on pt + if (inv2R_.first > maxInv2R || inv2R_.second < -maxInv2R) valid_ = false; - } else { - inv2RMin = max(inv2RMin, -maxInv2R); - inv2RMax = min(inv2RMax, maxInv2R); + else { + inv2R_.first = std::max(inv2R_.first, -maxInv2R); + inv2R_.second = std::min(inv2R_.second, maxInv2R); } - // range of stub inv2R in 1/cm - inv2R_ = {inv2RMin, inv2RMax}; - - // stub phi w.r.t. detector region centre in rad - phi_ = c_ + rowSub_ * m_; - // range of stub extrapolated phi to radius chosenRofPhi in rad phiT_.first = phi_ - r_ * inv2R_.first; phiT_.second = phi_ - r_ * inv2R_.second; if (phiT_.first > phiT_.second) - swap(phiT_.first, phiT_.second); - + std::swap(phiT_.first, phiT_.second); if (phiT_.first < 0.) - regions_.push_back(0); + regions_.set(0); if (phiT_.second >= 0.) - regions_.push_back(1); + regions_.set(1); + } + Stub::Stub(const tt::Setup* setup, + const trackerTFP::DataFormats* dataFormats, + const LayerEncoding* layerEncoding, + const tt::SensorModule* sm, + const TTStubRef& ttStubRef) + : setup_(setup), dataFormats_(dataFormats), layerEncoding_(layerEncoding), sm_(sm), ttStubRef_(ttStubRef) { + const Stub stub(dataFormats, sm, ttStubRef); + bend_ = stub.bend_; + valid_ = stub.valid_; + row_ = stub.row_; + col_ = stub.col_; + r_ = stub.r_; + phi_ = stub.phi_; + z_ = stub.z_; + phiT_ = stub.phiT_; + inv2R_ = stub.inv2R_; + regions_ = stub.regions_; + // apply "eta" cut + const trackerTFP::DataFormat& dfZT = dataFormats->format(trackerTFP::Variable::zT, trackerTFP::Process::gp); + const double r = r_ + setup->chosenRofPhi(); + const double ratioRZ = setup->chosenRofZ() / r; + // extrapolated z at radius T assuming z0=0 + const double zT = z_ * ratioRZ; + // extrapolated z0 window at radius T + const double dZT = setup->beamWindowZ() * std::abs(1. - ratioRZ); + zT_ = {zT - dZT, zT + dZT}; + if (std::abs(zT) > dfZT.range() / 2. + dZT) + valid_ = false; // apply data format specific manipulations - if (!hybrid_) + if (!setup_->useHybrid()) return; - // stub r w.r.t. an offset in cm - r_ -= sm->offsetR() - chosenRofPhi; + r_ -= sm->offsetR() - setup->chosenRofPhi(); // stub z w.r.t. an offset in cm z_ -= sm->offsetZ(); - if (sm->type() == SensorModule::Disk2S) { + if (sm->type() == tt::SensorModule::Disk2S) { // encoded r r_ = sm->encodedR() + (sm->side() ? -col_ : (col_ + sm->numColumns() / 2)); r_ = (r_ + 0.5) * setup->hybridBaseR(sm->type()); } - // encode bend - const vector& encodingBend = setup->encodingBend(sm->windowSize(), sm->psModule()); - const auto pos = find(encodingBend.begin(), encodingBend.end(), abs(ttStubRef->bendBE())); - const int uBend = distance(encodingBend.begin(), pos); - bend_ = pow(-1, signbit(bend_)) * uBend; + const std::vector& encodingBend = setup->encodingBend(sm->windowSize(), sm->psModule()); + const auto pos = std::find(encodingBend.begin(), encodingBend.end(), std::abs(ttStubRef->bendBE())); + const int uBend = std::distance(encodingBend.begin(), pos); + bend_ = std::pow(-1, std::signbit(bend_)) * uBend; } // returns bit accurate representation of Stub - Frame Stub::frame(int region) const { return hybrid_ ? formatHybrid(region) : formatTMTT(region); } - - // returns true if stub belongs to region - bool Stub::inRegion(int region) const { return find(regions_.begin(), regions_.end(), region) != regions_.end(); } + tt::FrameStub Stub::frame(int region) const { + return make_pair(ttStubRef_, setup_->useHybrid() ? formatHybrid(region) : formatTMTT(region)); + } // truncates double precision to f/w integer equivalent - double Stub::digi(double value, double precision) const { return (floor(value / precision) + .5) * precision; } + double Stub::digi(double value, double precision) const { + return (std::floor(value / precision + 1.e-12) + .5) * precision; + } // returns 64 bit stub in hybrid data format - Frame Stub::formatHybrid(int region) const { - const SensorModule::Type type = sm_->type(); + tt::Frame Stub::formatHybrid(int region) const { + const tt::SensorModule::Type type = sm_->type(); // layer encoding const int decodedLayerId = layerEncoding_->decode(sm_); // stub phi w.r.t. processing region border in rad double phi = phi_ - (region - .5) * setup_->baseRegion() + setup_->hybridRangePhi() / 2.; - if (phi >= setup_->hybridRangePhi()) - phi = setup_->hybridRangePhi() - setup_->hybridBasePhi(type) / 2.; // convert stub variables into bit vectors - const TTBV hwR(r_, setup_->hybridBaseR(type), setup_->hybridWidthR(type), true); - const TTBV hwPhi(phi, setup_->hybridBasePhi(type), setup_->hybridWidthPhi(type), true); + const bool twosR = type == tt::SensorModule::BarrelPS || type == tt::SensorModule::Barrel2S; + const TTBV hwR(r_, setup_->hybridBaseR(type), setup_->hybridWidthR(type), twosR); + const TTBV hwPhi(phi, setup_->hybridBasePhi(type), setup_->hybridWidthPhi(type)); const TTBV hwZ(z_, setup_->hybridBaseZ(type), setup_->hybridWidthZ(type), true); const TTBV hwAlpha(row_, setup_->hybridBaseAlpha(type), setup_->hybridWidthAlpha(type), true); const TTBV hwBend(bend_, setup_->hybridWidthBend(type), true); @@ -174,79 +158,39 @@ namespace trackerDTC { const TTBV hwGap(0, setup_->hybridNumUnusedBits(type)); const TTBV hwValid(1, 1); // assemble final bitset - return Frame(hwGap.str() + hwR.str() + hwZ.str() + hwPhi.str() + hwAlpha.str() + hwBend.str() + hwLayer.str() + - hwValid.str()); + return tt::Frame(hwGap.str() + hwR.str() + hwZ.str() + hwPhi.str() + hwAlpha.str() + hwBend.str() + hwLayer.str() + + hwValid.str()); } - Frame Stub::formatTMTT(int region) const { - int layerM = sm_->layerId(); - // convert unique layer id [1-6,11-15] into reduced layer id [0-6] - // a fiducial track may not cross more then 7 detector layers, for stubs from a given track the reduced layer id is actually unique - int layer(-1); - if (layerM == 1) - layer = 0; - else if (layerM == 2) - layer = 1; - else if (layerM == 6 || layerM == 11) - layer = 2; - else if (layerM == 5 || layerM == 12) - layer = 3; - else if (layerM == 4 || layerM == 13) - layer = 4; - else if (layerM == 14) - layer = 5; - else if (layerM == 3 || layerM == 15) - layer = 6; - // assign stub to phi sectors within a processing region, to be generalized - TTBV sectorsPhi(0, setup_->numOverlappingRegions() * setup_->numSectorsPhi()); - if (phiT_.first < 0.) { - if (phiT_.first < -setup_->baseSector()) - sectorsPhi.set(0); - else - sectorsPhi.set(1); - if (phiT_.second < 0. && phiT_.second >= -setup_->baseSector()) - sectorsPhi.set(1); - } - if (phiT_.second >= 0.) { - if (phiT_.second < setup_->baseSector()) - sectorsPhi.set(2); - else - sectorsPhi.set(3); - if (phiT_.first >= 0. && phiT_.first < setup_->baseSector()) - sectorsPhi.set(2); - } - // assign stub to eta sectors within a processing region - pair sectorEta({0, setup_->numSectorsEta() - 1}); - for (int bin = 0; bin < setup_->numSectorsEta(); bin++) - if (asinh(cot_.first) < setup_->boundarieEta(bin + 1)) { - sectorEta.first = bin; - break; - } - for (int bin = sectorEta.first; bin < setup_->numSectorsEta(); bin++) - if (asinh(cot_.second) < setup_->boundarieEta(bin + 1)) { - sectorEta.second = bin; - break; - } - // stub phi w.r.t. processing region centre in rad - const double phi = phi_ - (region - .5) * setup_->baseRegion(); - // convert stub variables into bit vectors - const TTBV hwValid(1, 1); - const TTBV hwGap(0, setup_->tmttNumUnusedBits()); - const TTBV hwLayer(layer, setup_->tmttWidthLayer()); - const TTBV hwSectorEtaMin(sectorEta.first, setup_->tmttWidthSectorEta()); - const TTBV hwSectorEtaMax(sectorEta.second, setup_->tmttWidthSectorEta()); - const TTBV hwR(r_, setup_->tmttBaseR(), setup_->tmttWidthR(), true); - const TTBV hwPhi(phi, setup_->tmttBasePhi(), setup_->tmttWidthPhi(), true); - const TTBV hwZ(z_, setup_->tmttBaseZ(), setup_->tmttWidthZ(), true); - const TTBV hwInv2RMin(inv2R_.first, setup_->tmttBaseInv2R(), setup_->tmttWidthInv2R(), true); - const TTBV hwInv2RMax(inv2R_.second, setup_->tmttBaseInv2R(), setup_->tmttWidthInv2R(), true); - TTBV hwSectorPhis(0, setup_->numSectorsPhi()); - for (int sectorPhi = 0; sectorPhi < setup_->numSectorsPhi(); sectorPhi++) - hwSectorPhis[sectorPhi] = sectorsPhi[region * setup_->numSectorsPhi() + sectorPhi]; - // assemble final bitset - return Frame(hwGap.str() + hwValid.str() + hwR.str() + hwPhi.str() + hwZ.str() + hwLayer.str() + - hwSectorPhis.str() + hwSectorEtaMin.str() + hwSectorEtaMax.str() + hwInv2RMin.str() + - hwInv2RMax.str()); + tt::Frame Stub::formatTMTT(int region) const { + const trackerTFP::DataFormat& dfInv2R = dataFormats_->format(trackerTFP::Variable::inv2R, trackerTFP::Process::ht); + const trackerTFP::DataFormat& dfPhiT = dataFormats_->format(trackerTFP::Variable::phiT, trackerTFP::Process::gp); + const trackerTFP::DataFormat& dfZT = dataFormats_->format(trackerTFP::Variable::zT, trackerTFP::Process::gp); + const double offset = (region - .5) * dfPhiT.range(); + const double r = r_; + const double phi = phi_ - offset; + const double z = z_; + const int indexLayerId = setup_->indexLayerId(ttStubRef_); + TTBV layer(indexLayerId, dataFormats_->width(trackerTFP::Variable::layer, trackerTFP::Process::dtc)); + if (sm_->barrel()) { + layer.set(4); + if (sm_->tilted()) + layer.set(3); + } else if (sm_->psModule()) + layer.set(3); + int phiTMin = std::max(dfPhiT.integer(phiT_.first - offset), -setup_->gpNumBinsPhiT() / 2); + int phiTMax = std::min(dfPhiT.integer(phiT_.second - offset), setup_->gpNumBinsPhiT() / 2 - 1); + if (phiTMin > setup_->gpNumBinsPhiT() / 2 - 1) + phiTMin = setup_->gpNumBinsPhiT() / 2 - 1; + if (phiTMax < -setup_->gpNumBinsPhiT() / 2) + phiTMax = -setup_->gpNumBinsPhiT() / 2; + const int zTMin = std::max(dfZT.integer(zT_.first), -setup_->gpNumBinsZT() / 2); + const int zTMax = std::min(dfZT.integer(zT_.second), setup_->gpNumBinsZT() / 2 - 1); + const int inv2RMin = std::max(dfInv2R.integer(inv2R_.first), -setup_->htNumBinsInv2R() / 2); + const int inv2RMax = std::min(dfInv2R.integer(inv2R_.second), setup_->htNumBinsInv2R() / 2 - 1); + const trackerTFP::StubDTC stub( + ttStubRef_, dataFormats_, r, phi, z, layer, phiTMin, phiTMax, zTMin, zTMax, inv2RMin, inv2RMax); + return stub.frame().second; } } // namespace trackerDTC diff --git a/L1Trigger/TrackerDTC/test/Analyzer.cc b/L1Trigger/TrackerDTC/test/Analyzer.cc index 7392f24abb066..e355a1158633c 100644 --- a/L1Trigger/TrackerDTC/test/Analyzer.cc +++ b/L1Trigger/TrackerDTC/test/Analyzer.cc @@ -10,18 +10,15 @@ #include "FWCore/Utilities/interface/InputTag.h" #include "FWCore/Utilities/interface/Exception.h" #include "CommonTools/UtilAlgos/interface/TFileService.h" -#include "SimDataFormats/TrackingAnalysis/interface/TrackingParticle.h" -#include "SimDataFormats/Associations/interface/TTClusterAssociationMap.h" -#include "SimTracker/Common/interface/TrackingParticleSelector.h" #include "DataFormats/DetId/interface/DetId.h" #include "DataFormats/Common/interface/Ptr.h" #include "DataFormats/Common/interface/Handle.h" -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" #include "DataFormats/L1TrackTrigger/interface/TTDTC.h" #include "DataFormats/GeometryVector/interface/GlobalPoint.h" #include "DataFormats/GeometrySurface/interface/Plane.h" #include "DataFormats/SiStripDetId/interface/StripSubdetector.h" +#include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" #include "L1Trigger/TrackTrigger/interface/Setup.h" #include "L1Trigger/TrackerDTC/interface/LayerEncoding.h" @@ -42,90 +39,57 @@ #include #include -using namespace std; -using namespace edm; -using namespace tt; - namespace trackerDTC { - // mc truth types - typedef TTClusterAssociationMap TTClusterAssMap; - typedef edm::Ptr TPPtr; // stub resolution plots helper enum Resolution { R, Phi, Z, NumResolution }; - constexpr initializer_list AllResolution = {R, Phi, Z}; + constexpr std::initializer_list AllResolution = {R, Phi, Z}; constexpr auto NameResolution = {"R", "Phi", "Z"}; - inline string name(Resolution r) { return string(*(NameResolution.begin() + r)); } + inline std::string name(Resolution r) { return std::string(*(NameResolution.begin() + r)); } // max tracking efficiency plots helper enum Efficiency { Phi0, Pt, InvPt, D0, Z0, Eta, NumEfficiency }; - constexpr initializer_list AllEfficiency = {Phi0, Pt, InvPt, D0, Z0, Eta}; + constexpr std::initializer_list AllEfficiency = {Phi0, Pt, InvPt, D0, Z0, Eta}; constexpr auto NameEfficiency = {"Phi0", "Pt", "InvPt", "D0", "Z0", "Eta"}; - inline string name(Efficiency e) { return string(*(NameEfficiency.begin() + e)); } + inline std::string name(Efficiency e) { return std::string(*(NameEfficiency.begin() + e)); } /*! \class trackerDTC::Analyzer * \brief Class to analyze hardware like structured TTStub Collection used by Track Trigger emulators, runs DTC stub emulation, plots performance & stub occupancy * \author Thomas Schuh * \date 2020, Apr */ - class Analyzer : public one::EDAnalyzer { + class Analyzer : public edm::one::EDAnalyzer { public: - Analyzer(const ParameterSet& iConfig); + Analyzer(const edm::ParameterSet& iConfig); void beginJob() override {} - void beginRun(const Run& iEvent, const EventSetup& iSetup) override; - void analyze(const Event& iEvent, const EventSetup& iSetup) override; - void endRun(const Run& iEvent, const EventSetup& iSetup) override {} + void beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override; + void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override; + void endRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override {} void endJob() override; private: - // configuring track particle selector - void configTPSelector(); - // book histograms - void bookHistograms(); - // associate TPPtr with TTStubRef - void assoc(const Handle&, const Handle&, map>&); - // organize reconstrucable TrackingParticles used for efficiency measurements - void convert(const map>&, map>&); - // checks if a stub selection is considered reconstructable - bool reconstructable(const set& ttStubRefs) const; - // checks if TrackingParticle is selected for efficiency measurements - bool select(const TrackingParticle& tp) const; // fills kinematic tp histograms - void fill(const TPPtr& tpPtr, const vector th1fs) const; - // analyze DTC products and find still reconstrucable TrackingParticles - void analyzeStubs(const TTDTC*, const TTDTC*, const map>&, map>&); + void fill(const TPPtr& tpPtr, const std::vector th1fs) const; // fill stub related histograms - void analyzeStream(const StreamStub& stream, int region, int channel, int& sum, TH2F* th2f); - // returns layerId [1-6, 11-15] of stub - int layerId(const TTStubRef& ttStubRef) const; - // analyze survived TPs - void analyzeTPs(const map>& mapTPsStubs); + void fill(const tt::StreamStub& stream, int region, int channel, int& sum, TH2F* th2f); // prints out MC summary void endJobMC(); // prints out DTC summary void endJobDTC(); // ED input token of DTC stubs - EDGetTokenT getTokenTTDTCAccepted_; + edm::EDGetTokenT edGetTokenTTDTCAccepted_; // ED input token of lost DTC stubs - EDGetTokenT getTokenTTDTCLost_; - // ED input token of TT stubs - EDGetTokenT getTokenTTStubDetSetVec_; - // ED input token of TTClsuter - EDGetTokenT getTokenTTClusterDetSetVec_; - // ED input token of TTCluster to TPPtr association - EDGetTokenT getTokenTTClusterAssMap_; + edm::EDGetTokenT edGetTokenTTDTCLost_; + // ED input token of TTStubRef to TPPtr association for tracking efficiency + edm::EDGetTokenT edGetTokenSelection_; + // ED input token of TTStubRef to recontructable TPPtr association + edm::EDGetTokenT edGetTokenReconstructable_; // Setup token - ESGetToken esGetToken_; + edm::ESGetToken esGetToken_; // stores, calculates and provides run-time constants - const Setup* setup_ = nullptr; - // selector to partly select TPs for efficiency measurements - TrackingParticleSelector tpSelector_; - // - TrackingParticleSelector tpSelectorLoose_; + const tt::Setup* setup_; // enables analyze of TPs bool useMCTruth_; - // specifies used TT algorithm - bool hybrid_; // int nEvents_ = 0; @@ -138,78 +102,163 @@ namespace trackerDTC { TH2F* hisRZStubs_; TH2F* hisRZStubsLost_; TH2F* hisRZStubsEff_; - vector hisResolution_; - vector profResolution_; - vector hisEff_; - vector hisEffMC_; - vector eff_; + std::vector hisResolution_; + std::vector profResolution_; + std::vector hisEff_; + std::vector hisEffMC_; + std::vector eff_; // printout - stringstream log_; + std::stringstream log_; }; - Analyzer::Analyzer(const ParameterSet& iConfig) - : useMCTruth_(iConfig.getParameter("UseMCTruth")), hybrid_(iConfig.getParameter("UseHybrid")) { + Analyzer::Analyzer(const edm::ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { usesResource("TFileService"); // book in- and output ED products - const auto& inputTagAccepted = iConfig.getParameter("InputTagAccepted"); - const auto& inputTagLost = iConfig.getParameter("InputTagLost"); - getTokenTTDTCAccepted_ = consumes(inputTagAccepted); - getTokenTTDTCLost_ = consumes(inputTagLost); + const auto& inputTagAccepted = iConfig.getParameter("InputTagAccepted"); + const auto& inputTagLost = iConfig.getParameter("InputTagLost"); + edGetTokenTTDTCAccepted_ = consumes(inputTagAccepted); + edGetTokenTTDTCLost_ = consumes(inputTagLost); if (useMCTruth_) { - const auto& inputTagTTStubDetSetVec = iConfig.getParameter("InputTagTTStubDetSetVec"); - const auto& inputTagTTClusterDetSetVec = iConfig.getParameter("InputTagTTClusterDetSetVec"); - const auto& inputTagTTClusterAssMap = iConfig.getParameter("InputTagTTClusterAssMap"); - getTokenTTStubDetSetVec_ = consumes(inputTagTTStubDetSetVec); - getTokenTTClusterDetSetVec_ = consumes(inputTagTTClusterDetSetVec); - getTokenTTClusterAssMap_ = consumes(inputTagTTClusterAssMap); + const auto& inputTagSelection = iConfig.getParameter("InputTagSelection"); + const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); + edGetTokenSelection_ = consumes(inputTagSelection); + edGetTokenReconstructable_ = consumes(inputTagReconstructable); } // book ES product - esGetToken_ = esConsumes(); + esGetToken_ = esConsumes(); // log config - log_.setf(ios::fixed, ios::floatfield); + log_.setf(std::ios::fixed, std::ios::floatfield); log_.precision(4); } - void Analyzer::beginRun(const Run& iEvent, const EventSetup& iSetup) { + void Analyzer::beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) { // helper class to store configurations setup_ = &iSetup.getData(esGetToken_); - // configuring track particle selector - configTPSelector(); // book histograms - bookHistograms(); + edm::Service fs; + TFileDirectory dir; + // mc + dir = fs->mkdir("MC"); + profMC_ = dir.make("Counts", ";", 6, 0.5, 6.5); + profMC_->GetXaxis()->SetBinLabel(1, "Stubs"); + profMC_->GetXaxis()->SetBinLabel(2, "Matched Stubs"); + profMC_->GetXaxis()->SetBinLabel(3, "reco TPs"); + profMC_->GetXaxis()->SetBinLabel(4, "eff TPs"); + profMC_->GetXaxis()->SetBinLabel(5, "total eff TPs"); + profMC_->GetXaxis()->SetBinLabel(6, "Cluster"); + constexpr std::array binsEff{{9 * 8, 10, 16, 10, 30, 24}}; + constexpr std::array, NumEfficiency> rangesEff{ + {{-M_PI, M_PI}, {0., 100.}, {-1. / 3., 1. / 3.}, {-5., 5.}, {-15., 15.}, {-2.4, 2.4}}}; + if (useMCTruth_) { + hisEffMC_.reserve(NumEfficiency); + for (Efficiency e : AllEfficiency) + hisEffMC_.emplace_back( + dir.make(("HisTP" + name(e)).c_str(), ";", binsEff[e], rangesEff[e].first, rangesEff[e].second)); + } + // dtc + dir = fs->mkdir("DTC"); + profDTC_ = dir.make("Counts", ";", 3, 0.5, 3.5); + profDTC_->GetXaxis()->SetBinLabel(1, "Stubs"); + profDTC_->GetXaxis()->SetBinLabel(2, "Lost Stubs"); + profDTC_->GetXaxis()->SetBinLabel(3, "TPs"); + // channel occupancy + constexpr int maxOcc = 180; + const int numChannels = setup_->numDTCs() * setup_->numOverlappingRegions(); + hisChannel_ = dir.make("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5); + profChannel_ = dir.make("Prof Channel Occupancy", ";", numChannels, -.5, numChannels - .5); + // max tracking efficiencies + if (useMCTruth_) { + dir = fs->mkdir("DTC/Effi"); + hisEff_.reserve(NumEfficiency); + for (Efficiency e : AllEfficiency) + hisEff_.emplace_back( + dir.make(("HisTP" + name(e)).c_str(), ";", binsEff[e], rangesEff[e].first, rangesEff[e].second)); + eff_.reserve(NumEfficiency); + for (Efficiency e : AllEfficiency) + eff_.emplace_back( + dir.make(("Eff" + name(e)).c_str(), ";", binsEff[e], rangesEff[e].first, rangesEff[e].second)); + } + // lost stub fraction in r-z + dir = fs->mkdir("DTC/Loss"); + constexpr int bins = 400; + constexpr double maxZ = 300.; + constexpr double maxR = 120.; + hisRZStubs_ = dir.make("RZ Stubs", ";;", bins, -maxZ, maxZ, bins, 0., maxR); + hisRZStubsLost_ = dir.make("RZ Stubs Lost", ";;", bins, -maxZ, maxZ, bins, 0., maxR); + hisRZStubsEff_ = dir.make("RZ Stubs Eff", ";;", bins, -maxZ, maxZ, bins, 0., maxR); + // stub parameter resolutions + dir = fs->mkdir("DTC/Res"); + constexpr std::array ranges{{.2, .0001, .5}}; + constexpr int binsHis = 100; + hisResolution_.reserve(NumResolution); + profResolution_.reserve(NumResolution); + for (Resolution r : AllResolution) { + hisResolution_.emplace_back(dir.make(("HisRes" + name(r)).c_str(), ";", binsHis, -ranges[r], ranges[r])); + profResolution_.emplace_back( + dir.make(("ProfRes" + name(r)).c_str(), ";;", bins, -maxZ, maxZ, bins, 0., maxR)); + } } - void Analyzer::analyze(const Event& iEvent, const EventSetup& iSetup) { - // read in TrackingParticle - map> mapAllStubsTPs; + void Analyzer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + // read in dtc products + edm::Handle handleTTDTCAccepted; + iEvent.getByToken(edGetTokenTTDTCAccepted_, handleTTDTCAccepted); + edm::Handle handleTTDTCLost; + iEvent.getByToken(edGetTokenTTDTCLost_, handleTTDTCLost); + // read in MCTruth + const tt::StubAssociation* selection = nullptr; + const tt::StubAssociation* reconstructable = nullptr; if (useMCTruth_) { - Handle handleTTStubDetSetVec; - iEvent.getByToken(getTokenTTStubDetSetVec_, handleTTStubDetSetVec); - Handle handleTTClusterAssMap; - iEvent.getByToken(getTokenTTClusterAssMap_, handleTTClusterAssMap); - // associate TPPtr with TTStubRef - map> mapAllTPsAllStubs; - assoc(handleTTStubDetSetVec, handleTTClusterAssMap, mapAllTPsAllStubs); - // organize reconstrucable TrackingParticles used for efficiency measurements - convert(mapAllTPsAllStubs, mapAllStubsTPs); - Handle handleTTClusterDetSetVec; - iEvent.getByToken(getTokenTTClusterDetSetVec_, handleTTClusterDetSetVec); - int nCluster(0); - for (const auto& detSet : *handleTTClusterDetSetVec) - nCluster += detSet.size(); - profMC_->Fill(6, nCluster / (double)setup_->numRegions()); + edm::Handle handleSelection; + iEvent.getByToken(edGetTokenSelection_, handleSelection); + selection = handleSelection.product(); + edm::Handle handleReconstructable; + iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); + reconstructable = handleReconstructable.product(); + profMC_->Fill(3, reconstructable->numTPs() / (double)setup_->numRegions()); + profMC_->Fill(4, selection->numTPs() / (double)setup_->numRegions()); + profMC_->Fill(5, selection->numTPs()); + for (const auto& p : selection->getTrackingParticleToTTStubsMap()) + fill(p.first, hisEffMC_); } - // read in dtc products - Handle handleTTDTCAccepted; - iEvent.getByToken(getTokenTTDTCAccepted_, handleTTDTCAccepted); - Handle handleTTDTCLost; - iEvent.getByToken(getTokenTTDTCLost_, handleTTDTCLost); - map> mapTPsTTStubs; - // analyze DTC products and find still reconstrucable TrackingParticles - analyzeStubs(handleTTDTCAccepted.product(), handleTTDTCLost.product(), mapAllStubsTPs, mapTPsTTStubs); - // analyze survived TPs - analyzeTPs(mapTPsTTStubs); + // analyze dtc products and find still reconstrucable TrackingParticles + std::set tpPtrs; + for (int region = 0; region < setup_->numRegions(); region++) { + int nStubs(0); + int nLost(0); + std::map> mapTPsTTStubs; + for (int channel = 0; channel < setup_->numDTCsPerTFP(); channel++) { + const tt::StreamStub& accepted = handleTTDTCAccepted->stream(region, channel); + const tt::StreamStub& lost = handleTTDTCLost->stream(region, channel); + hisChannel_->Fill(accepted.size()); + profChannel_->Fill(channel, accepted.size()); + fill(accepted, region, channel, nStubs, hisRZStubs_); + fill(lost, region, channel, nLost, hisRZStubsLost_); + if (!useMCTruth_) + continue; + for (const tt::FrameStub& frame : accepted) { + if (frame.first.isNull()) + continue; + for (const TPPtr& tpPtr : selection->findTrackingParticlePtrs(frame.first)) { + auto it = mapTPsTTStubs.find(tpPtr); + if (it == mapTPsTTStubs.end()) { + it = mapTPsTTStubs.emplace(tpPtr, std::vector()).first; + it->second.reserve(selection->findTTStubRefs(tpPtr).size()); + } + it->second.push_back(frame.first); + } + } + for (const auto& p : mapTPsTTStubs) + if (setup_->reconstructable(p.second)) + tpPtrs.insert(p.first); + } + profDTC_->Fill(1, nStubs); + profDTC_->Fill(2, nLost); + } + for (const TPPtr& tpPtr : tpPtrs) + fill(tpPtr, hisEff_); + profDTC_->Fill(3, tpPtrs.size()); nEvents_++; } @@ -229,148 +278,40 @@ namespace trackerDTC { eff_[e]->SetTotalHistogram(*hisEffMC_[e], "f"); } } - log_ << "'Lost' below refers to truncation losses" << endl; + log_ << "'Lost' below refers to truncation losses" << std::endl; // printout MC summary endJobMC(); // printout DTC summary endJobDTC(); log_ << "============================================================="; - LogPrint("L1Trigger/TrackerDTC") << log_.str(); - } - - // associate TPPtr with TTStubRef - void Analyzer::assoc(const Handle& handleTTStubDetSetVec, - const Handle& handleTTClusterAssMap, - map>& mapTPsStubs) { - int nStubs(0); - int nStubsMatched(0); - for (TTStubDetSetVec::const_iterator ttModule = handleTTStubDetSetVec->begin(); - ttModule != handleTTStubDetSetVec->end(); - ttModule++) { - nStubs += ttModule->size(); - for (TTStubDetSet::const_iterator ttStub = ttModule->begin(); ttStub != ttModule->end(); ttStub++) { - set tpPtrs; - for (unsigned int iClus = 0; iClus < 2; iClus++) { - const vector& assocPtrs = handleTTClusterAssMap->findTrackingParticlePtrs(ttStub->clusterRef(iClus)); - copy_if(assocPtrs.begin(), assocPtrs.end(), inserter(tpPtrs, tpPtrs.begin()), [](const TPPtr& tpPtr) { - return tpPtr.isNonnull(); - }); - } - for (const TPPtr& tpPtr : tpPtrs) - mapTPsStubs[tpPtr].emplace(makeRefTo(handleTTStubDetSetVec, ttStub)); - if (!tpPtrs.empty()) - nStubsMatched++; - } - } - profMC_->Fill(1, nStubs / (double)setup_->numRegions()); - profMC_->Fill(2, nStubsMatched / (double)setup_->numRegions()); - } - - // organize reconstrucable TrackingParticles used for efficiency measurements - void Analyzer::convert(const map>& mapTPsStubs, map>& mapStubsTPs) { - int nTPsReco(0); - int nTPsEff(0); - for (const auto& mapTPStubs : mapTPsStubs) { - if (!tpSelectorLoose_(*mapTPStubs.first) || !reconstructable(mapTPStubs.second)) - continue; - nTPsReco++; - const bool useForAlgEff = select(*mapTPStubs.first); - if (useForAlgEff) { - nTPsEff++; - fill(mapTPStubs.first, hisEffMC_); - for (const TTStubRef& ttStubRef : mapTPStubs.second) - mapStubsTPs[ttStubRef].insert(mapTPStubs.first); - } - } - profMC_->Fill(3, nTPsReco / (double)setup_->numRegions()); - profMC_->Fill(4, nTPsEff / (double)setup_->numRegions()); - profMC_->Fill(5, nTPsEff); - } - - // checks if a stub selection is considered reconstructable - bool Analyzer::reconstructable(const set& ttStubRefs) const { - const TrackerGeometry* trackerGeometry = setup_->trackerGeometry(); - const TrackerTopology* trackerTopology = setup_->trackerTopology(); - set hitPattern; - set hitPatternPS; - for (const TTStubRef& ttStubRef : ttStubRefs) { - const DetId detId = ttStubRef->getDetId(); - const bool barrel = detId.subdetId() == StripSubdetector::TOB; - const bool psModule = trackerGeometry->getDetectorType(detId) == TrackerGeometry::ModuleType::Ph2PSP; - const int layerId = barrel ? trackerTopology->layer(detId) : trackerTopology->tidWheel(detId) + 10; - hitPattern.insert(layerId); - if (psModule) - hitPatternPS.insert(layerId); - } - return (int)hitPattern.size() >= setup_->tpMinLayers() && (int)hitPatternPS.size() >= setup_->tpMinLayersPS(); - } - - // checks if TrackingParticle is selected for efficiency measurements - bool Analyzer::select(const TrackingParticle& tp) const { - const bool selected = tpSelector_(tp); - const double cot = sinh(tp.eta()); - const double s = sin(tp.phi()); - const double c = cos(tp.phi()); - const TrackingParticle::Point& v = tp.vertex(); - const double z0 = v.z() - (v.x() * c + v.y() * s) * cot; - const double d0 = v.x() * s - v.y() * c; - return selected && (fabs(d0) < setup_->tpMaxD0()) && (fabs(z0) < setup_->tpMaxVertZ()); + edm::LogPrint(moduleDescription().moduleName()) << log_.str(); } // fills kinematic tp histograms - void Analyzer::fill(const TPPtr& tpPtr, const vector th1fs) const { + void Analyzer::fill(const TPPtr& tpPtr, const std::vector th1fs) const { const double s = sin(tpPtr->phi()); const double c = cos(tpPtr->phi()); const TrackingParticle::Point& v = tpPtr->vertex(); - const vector x = {tpPtr->phi(), - tpPtr->pt(), - tpPtr->charge() / tpPtr->pt(), - v.x() * s - v.y() * c, - v.z() - (v.x() * c + v.y() * s) * sinh(tpPtr->eta()), - tpPtr->eta()}; + const std::vector x = {tpPtr->phi(), + tpPtr->pt(), + tpPtr->charge() / tpPtr->pt(), + v.x() * s - v.y() * c, + v.z() - (v.x() * c + v.y() * s) * sinh(tpPtr->eta()), + tpPtr->eta()}; for (Efficiency e : AllEfficiency) th1fs[e]->Fill(x[e]); } - // analyze DTC products and find still reconstrucable TrackingParticles - void Analyzer::analyzeStubs(const TTDTC* accepted, - const TTDTC* lost, - const map>& mapStubsTPs, - map>& mapTPsStubs) { - for (int region = 0; region < setup_->numRegions(); region++) { - int nStubs(0); - int nLost(0); - for (int channel = 0; channel < setup_->numDTCsPerTFP(); channel++) { - const StreamStub& stream = accepted->stream(region, channel); - hisChannel_->Fill(stream.size()); - profChannel_->Fill(region * setup_->numDTCsPerTFP() + channel, stream.size()); - for (const FrameStub& frame : stream) { - if (frame.first.isNull()) - continue; - const auto it = mapStubsTPs.find(frame.first); - if (it == mapStubsTPs.end()) - continue; - for (const TPPtr& tp : it->second) - mapTPsStubs[tp].insert(frame.first); - } - analyzeStream(stream, region, channel, nStubs, hisRZStubs_); - analyzeStream(lost->stream(region, channel), region, channel, nLost, hisRZStubsLost_); - } - profDTC_->Fill(1, nStubs); - profDTC_->Fill(2, nLost); - } - } - // fill stub related histograms - void Analyzer::analyzeStream(const StreamStub& stream, int region, int channel, int& sum, TH2F* th2f) { - for (const FrameStub& frame : stream) { + void Analyzer::fill(const tt::StreamStub& stream, int region, int channel, int& sum, TH2F* th2f) { + for (const tt::FrameStub& frame : stream) { if (frame.first.isNull()) continue; sum++; - const GlobalPoint& pos = setup_->stubPos(hybrid_, frame, region); + const GlobalPoint& pos = setup_->stubPos(frame, region); const GlobalPoint& ttPos = setup_->stubPos(frame.first); - const vector resolutions = { - ttPos.perp() - pos.perp(), deltaPhi(ttPos.phi() - pos.phi()), ttPos.z() - pos.z()}; + const std::vector resolutions = { + ttPos.perp() - pos.perp(), tt::deltaPhi(ttPos.phi() - pos.phi()), ttPos.z() - pos.z()}; for (Resolution r : AllResolution) { hisResolution_[r]->Fill(resolutions[r]); profResolution_[r]->Fill(ttPos.z(), ttPos.perp(), abs(resolutions[r])); @@ -379,27 +320,7 @@ namespace trackerDTC { } } - // returns layerId [1-6, 11-15] of stub - int Analyzer::layerId(const TTStubRef& ttStubRef) const { - const TrackerTopology* trackerTopology = setup_->trackerTopology(); - const DetId detId = ttStubRef->getDetId() + setup_->offsetDetIdDSV(); - const bool barrel = detId.subdetId() == StripSubdetector::TOB; - return barrel ? trackerTopology->layer(detId) : trackerTopology->tidWheel(detId) + setup_->offsetLayerDisks(); - } - - // analyze survived TPs - void Analyzer::analyzeTPs(const map>& mapTPsStubs) { - int nTPs(0); - for (const auto& mapTPStubs : mapTPsStubs) { - if (!reconstructable(mapTPStubs.second)) - continue; - nTPs++; - fill(mapTPStubs.first, hisEff_); - } - profDTC_->Fill(3, nTPs); - } - - // prints out MC summary + // prints out Monte Carlo summary void Analyzer::endJobMC() { const double numStubs = profMC_->GetBinContent(1); const double numStubsMatched = profMC_->GetBinContent(2); @@ -411,22 +332,22 @@ namespace trackerDTC { const double errTPsEff = profMC_->GetBinError(4); const double numCluster = profMC_->GetBinContent(6); const double errCluster = profMC_->GetBinError(6); - const vector nums = {numStubs, numStubsMatched, numTPsReco, numTPsEff, numCluster}; - const vector errs = {errStubs, errStubsMatched, errTPsReco, errTPsEff, errCluster}; - const int wNums = ceil(log10(*max_element(nums.begin(), nums.end()))) + 5; - const int wErrs = ceil(log10(*max_element(errs.begin(), errs.end()))) + 5; - log_ << "=============================================================" << endl; - log_ << " MC SUMMARY " << endl; - log_ << "number of cluster per TFP = " << setw(wNums) << numCluster << " +- " << setw(wErrs) << errCluster - << endl; - log_ << "number of stubs per TFP = " << setw(wNums) << numStubs << " +- " << setw(wErrs) << errStubs - << endl; - log_ << "number of matched stubs per TFP = " << setw(wNums) << numStubsMatched << " +- " << setw(wErrs) - << errStubsMatched << endl; - log_ << "number of TPs per TFP = " << setw(wNums) << numTPsReco << " +- " << setw(wErrs) << errTPsReco - << endl; - log_ << "number of TPs for eff per TFP = " << setw(wNums) << numTPsEff << " +- " << setw(wErrs) << errTPsEff - << endl; + const std::vector nums = {numStubs, numStubsMatched, numTPsReco, numTPsEff, numCluster}; + const std::vector errs = {errStubs, errStubsMatched, errTPsReco, errTPsEff, errCluster}; + const int wNums = std::ceil(std::log10(*std::max_element(nums.begin(), nums.end()))) + 5; + const int wErrs = std::ceil(std::log10(*std::max_element(errs.begin(), errs.end()))) + 5; + log_ << "=============================================================" << std::endl; + log_ << " Monte Carlo SUMMARY " << std::endl; + log_ << "number of cluster per TFP = " << std::setw(wNums) << numCluster << " +- " << std::setw(wErrs) + << errCluster << std::endl; + log_ << "number of stubs per TFP = " << std::setw(wNums) << numStubs << " +- " << std::setw(wErrs) + << errStubs << std::endl; + log_ << "number of matched stubs per TFP = " << std::setw(wNums) << numStubsMatched << " +- " << std::setw(wErrs) + << errStubsMatched << std::endl; + log_ << "number of TPs per TFP = " << std::setw(wNums) << numTPsReco << " +- " << std::setw(wErrs) + << errTPsReco << std::endl; + log_ << "number of TPs for eff per TFP = " << std::setw(wNums) << numTPsEff << " +- " << std::setw(wErrs) + << errTPsEff << std::endl; } // prints out DTC summary @@ -439,100 +360,18 @@ namespace trackerDTC { const double totalTPs = profMC_->GetBinContent(5); const double eff = numTPs / totalTPs; const double errEff = sqrt(eff * (1. - eff) / totalTPs / nEvents_); - const vector nums = {numStubs, numStubsLost}; - const vector errs = {errStubs, errStubsLost}; - const int wNums = ceil(log10(*max_element(nums.begin(), nums.end()))) + 5; - const int wErrs = ceil(log10(*max_element(errs.begin(), errs.end()))) + 5; - log_ << "=============================================================" << endl; - log_ << " DTC SUMMARY " << endl; - log_ << "number of stubs per TFP = " << setw(wNums) << numStubs << " +- " << setw(wErrs) << errStubs << endl; - log_ << "number of lost stubs per TFP = " << setw(wNums) << numStubsLost << " +- " << setw(wErrs) << errStubsLost - << endl; - log_ << " max tracking efficiency = " << setw(wNums) << eff << " +- " << setw(wErrs) << errEff << endl; - } - - // configuring track particle selector - void Analyzer::configTPSelector() { - const double ptMin = hybrid_ ? setup_->hybridMinPtStub() : setup_->minPt(); - constexpr double ptMax = 9999999999.; - const double etaMax = setup_->tpMaxEta(); - const double tip = setup_->tpMaxVertR(); - const double lip = setup_->tpMaxVertZ(); - constexpr int minHit = 0; - constexpr bool signalOnly = true; - constexpr bool intimeOnly = true; - constexpr bool chargedOnly = true; - constexpr bool stableOnly = false; - tpSelector_ = TrackingParticleSelector( - ptMin, ptMax, -etaMax, etaMax, tip, lip, minHit, signalOnly, intimeOnly, chargedOnly, stableOnly); - tpSelectorLoose_ = - TrackingParticleSelector(ptMin, ptMax, -etaMax, etaMax, tip, lip, minHit, false, false, false, stableOnly); - } - - // book histograms - void Analyzer::bookHistograms() { - Service fs; - TFileDirectory dir; - // mc - dir = fs->mkdir("MC"); - profMC_ = dir.make("Counts", ";", 6, 0.5, 6.5); - profMC_->GetXaxis()->SetBinLabel(1, "Stubs"); - profMC_->GetXaxis()->SetBinLabel(2, "Matched Stubs"); - profMC_->GetXaxis()->SetBinLabel(3, "reco TPs"); - profMC_->GetXaxis()->SetBinLabel(4, "eff TPs"); - profMC_->GetXaxis()->SetBinLabel(5, "total eff TPs"); - profMC_->GetXaxis()->SetBinLabel(6, "Cluster"); - constexpr array binsEff{{9 * 8, 10, 16, 10, 30, 24}}; - constexpr array, NumEfficiency> rangesEff{ - {{-M_PI, M_PI}, {0., 100.}, {-1. / 3., 1. / 3.}, {-5., 5.}, {-15., 15.}, {-2.4, 2.4}}}; - if (useMCTruth_) { - hisEffMC_.reserve(NumEfficiency); - for (Efficiency e : AllEfficiency) - hisEffMC_.emplace_back( - dir.make(("HisTP" + name(e)).c_str(), ";", binsEff[e], rangesEff[e].first, rangesEff[e].second)); - } - // dtc - dir = fs->mkdir("DTC"); - profDTC_ = dir.make("Counts", ";", 3, 0.5, 3.5); - profDTC_->GetXaxis()->SetBinLabel(1, "Stubs"); - profDTC_->GetXaxis()->SetBinLabel(2, "Lost Stubs"); - profDTC_->GetXaxis()->SetBinLabel(3, "TPs"); - // channel occupancy - constexpr int maxOcc = 180; - const int numChannels = setup_->numDTCs() * setup_->numOverlappingRegions(); - hisChannel_ = dir.make("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5); - profChannel_ = dir.make("Prof Channel Occupancy", ";", numChannels, -.5, numChannels - .5); - // max tracking efficiencies - if (useMCTruth_) { - dir = fs->mkdir("DTC/Effi"); - hisEff_.reserve(NumEfficiency); - for (Efficiency e : AllEfficiency) - hisEff_.emplace_back( - dir.make(("HisTP" + name(e)).c_str(), ";", binsEff[e], rangesEff[e].first, rangesEff[e].second)); - eff_.reserve(NumEfficiency); - for (Efficiency e : AllEfficiency) - eff_.emplace_back( - dir.make(("Eff" + name(e)).c_str(), ";", binsEff[e], rangesEff[e].first, rangesEff[e].second)); - } - // lost stub fraction in r-z - dir = fs->mkdir("DTC/Loss"); - constexpr int bins = 400; - constexpr double maxZ = 300.; - constexpr double maxR = 120.; - hisRZStubs_ = dir.make("RZ Stubs", ";;", bins, -maxZ, maxZ, bins, 0., maxR); - hisRZStubsLost_ = dir.make("RZ Stubs Lost", ";;", bins, -maxZ, maxZ, bins, 0., maxR); - hisRZStubsEff_ = dir.make("RZ Stubs Eff", ";;", bins, -maxZ, maxZ, bins, 0., maxR); - // stub parameter resolutions - dir = fs->mkdir("DTC/Res"); - constexpr array ranges{{.2, .0001, .5}}; - constexpr int binsHis = 100; - hisResolution_.reserve(NumResolution); - profResolution_.reserve(NumResolution); - for (Resolution r : AllResolution) { - hisResolution_.emplace_back(dir.make(("HisRes" + name(r)).c_str(), ";", binsHis, -ranges[r], ranges[r])); - profResolution_.emplace_back( - dir.make(("ProfRes" + name(r)).c_str(), ";;", bins, -maxZ, maxZ, bins, 0., maxR)); - } + const std::vector nums = {numStubs, numStubsLost}; + const std::vector errs = {errStubs, errStubsLost}; + const int wNums = std::ceil(std::log10(*std::max_element(nums.begin(), nums.end()))) + 5; + const int wErrs = std::ceil(std::log10(*std::max_element(errs.begin(), errs.end()))) + 5; + log_ << "=============================================================" << std::endl; + log_ << " DTC SUMMARY " << std::endl; + log_ << "number of stubs per TFP = " << std::setw(wNums) << numStubs << " +- " << std::setw(wErrs) << errStubs + << std::endl; + log_ << "number of lost stubs per TFP = " << std::setw(wNums) << numStubsLost << " +- " << std::setw(wErrs) + << errStubsLost << std::endl; + log_ << " max tracking efficiency = " << std::setw(wNums) << eff << " +- " << std::setw(wErrs) << errEff + << std::endl; } } // namespace trackerDTC diff --git a/L1Trigger/TrackerDTC/test/AnalyzerDAQ.cc b/L1Trigger/TrackerDTC/test/AnalyzerDAQ.cc index 35dc71675e255..97b7452f31856 100644 --- a/L1Trigger/TrackerDTC/test/AnalyzerDAQ.cc +++ b/L1Trigger/TrackerDTC/test/AnalyzerDAQ.cc @@ -20,10 +20,6 @@ #include #include -using namespace std; -using namespace edm; -using namespace tt; - namespace trackerDTC { /*! \class trackerDTC::AnalyzerDAQ @@ -31,22 +27,19 @@ namespace trackerDTC { * \author Thomas Schuh * \date 2020, Oct */ - class AnalyzerDAQ : public one::EDAnalyzer { + class AnalyzerDAQ : public edm::one::EDAnalyzer { public: - AnalyzerDAQ(const ParameterSet& iConfig); - void beginJob() override {} - void beginRun(const Run& iEvent, const EventSetup& iSetup) override; - void analyze(const Event& iEvent, const EventSetup& iSetup) override; - void endRun(const Run& iEvent, const EventSetup& iSetup) override {} + AnalyzerDAQ(const edm::ParameterSet& iConfig); + void beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override; + void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override; + void endRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override {} void endJob() override {} private: // ED input token of accepted TTClusters - EDGetTokenT edGetToken_; + edm::EDGetTokenT edGetToken_; // Setup token - ESGetToken esGetTokenSetup_; - // stores, calculates and provides run-time constants - const Setup* setup_ = nullptr; + edm::ESGetToken esGetTokenSetup_; // Histograms @@ -57,29 +50,29 @@ namespace trackerDTC { TH1F* hisTracker_; }; - AnalyzerDAQ::AnalyzerDAQ(const ParameterSet& iConfig) { + AnalyzerDAQ::AnalyzerDAQ(const edm::ParameterSet& iConfig) { usesResource("TFileService"); // book input ED products - const auto& inputTag = iConfig.getParameter("InputTagTTClusterDetSetVec"); + const auto& inputTag = iConfig.getParameter("InputTagTTClusterDetSetVec"); edGetToken_ = consumes(inputTag); // book ES products - esGetTokenSetup_ = esConsumes(); + esGetTokenSetup_ = esConsumes(); } - void AnalyzerDAQ::beginRun(const Run& iEvent, const EventSetup& iSetup) { + void AnalyzerDAQ::beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) { // helper class to store configurations - setup_ = &iSetup.getData(esGetTokenSetup_); + const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_); // book histograms - Service fs; + edm::Service fs; TFileDirectory dir; dir = fs->mkdir("Modules"); int maxOcc = 150; - int numChannels = setup_->numDTCs() * setup_->numModulesPerDTC(); + int numChannels = setup->numDTCs() * setup->numModulesPerDTC(); hisModules_ = dir.make("His Module Occupancy", ";", maxOcc, -.5, maxOcc - .5); profModules_ = dir.make("Prof Module Occupancy", ";", numChannels, -.5, numChannels - .5); dir = fs->mkdir("DTCs"); maxOcc = 3456; - numChannels = setup_->numDTCs(); + numChannels = setup->numDTCs(); hisDTCs_ = dir.make("His DTC Occupancy", ";", maxOcc / 16, -.5, maxOcc - .5); profDTCs_ = dir.make("Prof DTC Occupancy", ";", numChannels, -.5, numChannels - .5); dir = fs->mkdir("Tracker"); @@ -87,22 +80,23 @@ namespace trackerDTC { hisTracker_ = dir.make("His Tracker Occupancy", ";", maxOcc * pow(2., -12), -.5, maxOcc - .5); } - void AnalyzerDAQ::analyze(const Event& iEvent, const EventSetup& iSetup) { + void AnalyzerDAQ::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_); // read in original TTCluster collection - Handle handle; + edm::Handle handle; iEvent.getByToken(edGetToken_, handle); // apply cabling map, reorganise cluster collections - vector>> dtcs(setup_->numDTCs(), - vector>(setup_->numModulesPerDTC())); + std::vector>> dtcs( + setup->numDTCs(), std::vector>(setup->numModulesPerDTC())); for (auto itModule = handle->begin(); itModule != handle->end(); itModule++) { // DetSetVec->detId - 1 or + 0 = tk layout det id depending from which of both sensor planes the cluster has been constructed const DetId& detIdModule = itModule->detId(); - const int offset = setup_->trackerTopology()->isLower(detIdModule) ? 0 : setup_->offsetDetIdTP(); + const int offset = setup->trackerTopology()->isLower(detIdModule) ? 0 : setup->offsetDetIdTP(); const DetId detId = detIdModule + offset; // corresponding sensor module - SensorModule* sm = setup_->sensorModule(detId); + tt::SensorModule* sm = setup->sensorModule(detId); // empty cluster collection - deque& module = dtcs[sm->dtcId()][sm->modId()]; + std::deque& module = dtcs[sm->dtcId()][sm->modId()]; for (TTClusterDetSet::const_iterator itCluster = itModule->begin(); itCluster != itModule->end(); itCluster++) module.emplace_back(makeRefTo(handle, itCluster)); } @@ -110,9 +104,9 @@ namespace trackerDTC { int iDTC(0); int iModule(0); int nAll(0); - for (const vector>& dtc : dtcs) { + for (const std::vector>& dtc : dtcs) { int nCluster(0); - for (const deque& module : dtc) { + for (const std::deque& module : dtc) { nCluster += module.size(); hisModules_->Fill(module.size()); profModules_->Fill(iModule++, module.size()); diff --git a/L1Trigger/TrackerDTC/test/testDAQ_cfg.py b/L1Trigger/TrackerDTC/test/testDAQ_cfg.py index e3c3e48262f73..6e5fc978d2533 100644 --- a/L1Trigger/TrackerDTC/test/testDAQ_cfg.py +++ b/L1Trigger/TrackerDTC/test/testDAQ_cfg.py @@ -21,12 +21,12 @@ process.GlobalTag = GlobalTag(process.GlobalTag, '140X_mcRun4_realistic_v3', '') # load code that produces DTCStubs -process.load( 'L1Trigger.TrackerDTC.ProducerED_cff' ) +process.load( 'L1Trigger.TrackerDTC.DTC_cff' ) # load code that analyzes TTCluster process.load( 'L1Trigger.TrackerDTC.AnalyzerDAQ_cff' ) # build schedule (not essential to rerun producer). -process.produce = cms.Path( process.TrackerDTCProducer ) +process.produce = cms.Path( process.ProducerDTC ) process.analyzeDAQ = cms.Path( process.TrackerDTCAnalyzerDAQ ) process.schedule = cms.Schedule( process.produce, process.analyzeDAQ ) diff --git a/L1Trigger/TrackerDTC/test/test_cfg.py b/L1Trigger/TrackerDTC/test/test_cfg.py index 8196b0508dc7b..cfc4788d9ad29 100644 --- a/L1Trigger/TrackerDTC/test/test_cfg.py +++ b/L1Trigger/TrackerDTC/test/test_cfg.py @@ -21,7 +21,7 @@ process.GlobalTag = GlobalTag(process.GlobalTag, '140X_mcRun4_realistic_v3', '') # load code that produces DTCStubs -process.load( 'L1Trigger.TrackerDTC.ProducerED_cff' ) +process.load( 'L1Trigger.TrackerDTC.DTC_cff' ) # load code that analyzes DTCStubs process.load( 'L1Trigger.TrackerDTC.Analyzer_cff' ) # cosutmize TT algorithm @@ -30,8 +30,8 @@ #analyzerUseTMTT(process) # build schedule (not essential to rerun producer) -process.produce = cms.Path( process.TrackerDTCProducer ) -process.analyze = cms.Path( process.TrackerDTCAnalyzer ) +process.produce = cms.Path( process.ProducerDTC ) +process.analyze = cms.Path( process.AnalyzerDTC ) process.schedule = cms.Schedule( process.produce, process.analyze ) # create options diff --git a/L1Trigger/TrackerTFP/BuildFile.xml b/L1Trigger/TrackerTFP/BuildFile.xml index 8f490f87eed7e..33536297880e0 100644 --- a/L1Trigger/TrackerTFP/BuildFile.xml +++ b/L1Trigger/TrackerTFP/BuildFile.xml @@ -1,4 +1,5 @@ + diff --git a/L1Trigger/TrackerTFP/README.md b/L1Trigger/TrackerTFP/README.md index 434b589553b04..dbafccfdf95ee 100644 --- a/L1Trigger/TrackerTFP/README.md +++ b/L1Trigger/TrackerTFP/README.md @@ -4,9 +4,9 @@ This directory contains L1 tracking code used by the TMTT & Hybrid algorithms. cmsRun L1Trigger/TrackerTFP/test/test_cfg.py Events= -runs the clock and bit accurate emulation of the TMTT chain. In the run script one may want to change the used event files or tracker geometry. The option CheckHistory in L1Trigger/TrackerTFP/python/Producer_cfi.py is set to false by default but is highly recommended to be set to true if one runs the emulator. This will automatically test if the configuration of the emulation run is consistent with the configuration of the input evevnt production and points out for example if one chooses a different tracker geometry. +runs the clock and bit accurate emulation of the TMTT chain. In the run script one may want to change the used event files or tracker geometry. -Apart from producing TTTrack collection as the f/w will, test_cfg.py analyses the results. It provides a end-of-job summary, which reports data rates and tracking efficiencies at the end of each processing step. The definition of which Tracking Particles are taken into account for this efficiency measurements are described here: L1Trigger/TrackTrigger/python/ProducerSetup_cfi.py in the PSet TrackTrigger_params.TrackingParticle. The "maximal possible tracking efficiency" reported for tracking steps part way through the chain is derived assuming zero efficiency loss in subsequent steps. This method allows to assess which processing steps cause most inefficiency. Additionally a "lost tracking efficiency" is reported, which is the loss due to truncation as a result of bottlenecks in the data throughput of the implemented design. Beside this end job summary test_cfg.py produces Hist.root which contains histograms with more details like efficiencies over certain tracking particle parameter. +Apart from producing TTTrack collection as the f/w will, test_cfg.py analyses the results. It provides a end-of-job summary, which reports data rates and tracking efficiencies at the end of each processing step. The definition of which Tracking Particles are taken into account for this efficiency measurements are described here: L1Trigger/TrackTrigger/python/ProducerSetup_cfi.py in the PSet TrackTrigger_params.TrackingParticle. The "maximal possible tracking efficiency" reported for tracking steps part way through the chain is derived assuming zero efficiency loss in subsequent steps. This method allows to assess which processing steps cause most inefficiency. Beside this end job summary test_cfg.py produces Hist.root which contains histograms with more details like efficiencies over certain tracking particle parameter. cmsRun L1Trigger/TrackerTFP/test/demonstrator_cfg.py Events= @@ -18,11 +18,31 @@ All configuration params to manipulate the algorithms one may want to play with === Code structure === -There are 6 TMTT algorithm steps: GP (Geometric Process), HT (Hough Transform), MHT (Mini Hough Transform), ZHT (r-z Hough Transform), KF (Kalman Filter), DR (Duplicate Removal). Each comes with one EDProducer, one EDAnalyzer and one class which contains the actual emulation of this step for one nonant (1/9 phi slice of outer tracker). Their EDProducts combine the connection to MCTruth (and does not conatain MCTruth) via edm::Refs of either TTStubs or TTTracks with the actual bits used in h/w via std::bitset<64> using a std::pair of those objects. -The track-finding firmware is described in a highly parallel fashion. On the one hand, one has multiple worker nodes for each step and on the other hand is the process pipelined in a way to receive potentially one product per clock tick. This parallelism is reflected by a two dimensional vector of the earlier mentioned pairs. The inner vector describes the output (also called Frame) of one working node per clock tick. If the f/w produces no valid product in a given clock tick, then the bitset will be all '0' and the edm:ref will be null. Valid products do not necessarily form a contiguous block of valid products. The outer vector will have one entry per worker node (also called channel) where all nodes for the whole tracker are counted. Each EDProducer will produce two branches: Accepted Track or Stub and Lost Track or Stub. The Lost branch contains the Tracks or Stubs which are lost since they got not processed in time. Since the KF uses Tracks and Stubs as input the EDProducer ProducerZHTout is used to form TTTracks after the ZHT and ProducerKFin to create the edm::ref to this TTTracks. Finally ProducerTT takes the h/w liked structured output from the KF and produces one collection of TTTracks and ProducerAS creates a map between KF input TTracks to KF output TTTracks. +There are 7 TMTT algorithm steps: GP (Geometric Process), HT (Hough Transform), CTB (Clean Track Builder), KF (Kalman Filter), DR (Duplicate Removal), TQ (Track Quality), TFP (Track Finding Processor). Each comes with one EDProducer, one EDAnalyzer and one class which contains the actual emulation of this step for one nonant (1/9 phi slice of outer tracker). Their EDProducts combine the connection to MCTruth (and does not conatain MCTruth) via edm::Refs of either TTStubs or TTTracks with the actual bits used in h/w via std::bitset<64> using a std::pair of those objects. +The track-finding firmware is described in a highly parallel fashion. On the one hand, one has multiple worker nodes for each step and on the other hand is the process pipelined in a way to receive potentially one product per clock tick. This parallelism is reflected by a two dimensional vector of the earlier mentioned pairs. The inner vector describes the output (also called Frame) of one working node per clock tick. If the f/w produces no valid product in a given clock tick, then the bitset will be all '0' and the edm:ref will be null. Valid products do not necessarily form a contiguous block of valid products. The outer vector will have one entry per worker node (also called channel) where all nodes for the whole tracker are counted. Since the KF uses Tracks and Stubs as input the EDProducer ProducerCTB is used to form TTTracks after the HT. Finally ProducerTFP takes the h/w liked structured output from the TQ and produces one collection of TTTracks. There are 5 additional classes in L1Trigger/TrackerTFP. DataFormats describes Stubs and Tracks for each process step and automates the conversion from floating points to bits as used in h/w and vice versa. Demonstrator allows one to compare s/w with f/w. KalmanFilterFormats describes the used precisions in the Kalman Filter. LayerEncoding allows one to transform the layer encoding used before the KF into the encoding after KF. State is a helper class to simplify the KalmanFilter code. In order to simplify the conversion of floating point values into arbitrary long (within 64 bit) binary or twos-complement number, the class DataFormats/L1TrackTrigger/interface/TTBV.h has been created. In order to simplify the tracking efficiency measurement the class StubAssociator in SimTracker/TrackTriggerAssociation/ has been created. + +=== Details to commonly used Classes === + +Frame is a typedef for std::bitset<64> representing the h/w words which level-1 track finder or level-1 trigger boards will receive and transmit per optical link and internal clock tick. + +TTBV Class representing a BitVector used by TrackTrigger emulators. Based on Frame. The class is mainly used to convert h/w-like structured bits into integers and vice versa. A typical constructors receive an integer values, a bit width (number of bits used to represent this value, an error will be thrown when not enough bits are provided.) and a boolean to distinguish between binary and two's complement representation. Multiple operators are provided, e.g bit wise or, or concatenation with another TTBV. + +FrameStub is a typedef for std::pair. This object is used to represent a Stub in TrackTrigger emulators. On the one hand side it connects to the original TTStub and on the other hand it has the bit string used in h/w to represent this stub. + +FrameTrack same as FrameStub but for Tracks + +StreamStub h/w-like structured collection of stubs. Clock ticks where no Stub can be provided are represented by default constructed FrameStubs (edm:Ref recognising being a null ref and bit set being zero'd). This enables to store stubs bit and clock accurately. + +StreamTrack same as StreamStub but for Tracks + +DataFormat Base class to represent formats of a specific variable at a specific processing step. A format is given by a bit width, an boolean to distinguish between signed and unsigned cover as well as an conversion factor to transform between floating point and biased integer representation. These formats are used to transform h/w words (TTBVs) into variables (supporting conversion to int, double, bool or TTBV). + +DataFormats ESProduct which provides access to all DataFormats used by Track Trigger emulators + +Setup ESProduct providing run time constants configuring Track Trigger emulators diff --git a/L1Trigger/TrackerTFP/interface/CleanTrackBuilder.h b/L1Trigger/TrackerTFP/interface/CleanTrackBuilder.h new file mode 100644 index 0000000000000..77ae9919ae1f4 --- /dev/null +++ b/L1Trigger/TrackerTFP/interface/CleanTrackBuilder.h @@ -0,0 +1,157 @@ +#ifndef L1Trigger_TrackerTFP_CleanTrackBuilder_h +#define L1Trigger_TrackerTFP_CleanTrackBuilder_h + +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackerTFP/interface/DataFormats.h" +#include "L1Trigger/TrackerTFP/interface/LayerEncoding.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" + +#include +#include + +namespace trackerTFP { + + // Class to clean and transform stream of stubs into a stream of tracks with one stub stream per kf layer + class CleanTrackBuilder { + public: + CleanTrackBuilder(const tt::Setup* setup, + const DataFormats* dataFormats, + const LayerEncoding* layerEncoding, + const DataFormat& cot, + std::vector& stubs, + std::vector& tracks); + ~CleanTrackBuilder() {} + // fill output products + void produce(const std::vector>& streamsIn, + std::vector>& regionTracks, + std::vector>>& regionStubs); + void put(TrackCTB* track, const std::vector>& stubs, int region, tt::TTTracks& ttTracks) const; + + private: + // struct to represent internal stubs + struct Stub { + // construct Stub from StubHT + Stub(StubHT* stub, int trackId, const TTBV& hitsPhi, const TTBV& hitsZ, int layerId, double dPhi, double dZ) + : stubHT_(stub), + trackId_(trackId), + hitsPhi_(hitsPhi), + hitsZ_(hitsZ), + layerId_(layerId), + dPhi_(dPhi), + dZ_(dZ) {} + // + void update(const TTBV& phi, const TTBV& z, std::vector& ids, int max); + // original ht stub + StubHT* stubHT_; + // + bool valid_ = true; + // + int trackId_; + // + int stubId_ = -1; + // + TTBV hitsPhi_; + // + TTBV hitsZ_; + // + int layerId_; + // + double dPhi_; + // + double dZ_; + }; + + // struct to represent internal tracks + struct Track { + // construct Track from Stubs + Track(const tt::Setup* setup, + int trackId, + const TTBV& hitsPhi, + const TTBV& hitsZ, + const std::vector& stubs, + double inv2R); + // + bool valid_; + // stubs + std::vector stubs_; + // track id + int trackId_; + // + TTBV hitsPhi_; + // + TTBV hitsZ_; + // + double inv2R_; + // size: number of stubs on most occupied layer + int size_; + }; + // + void cleanStream(const std::vector& input, + std::deque& tracks, + std::deque& stubs, + int channelId); + // run single track through r-phi and r-z hough transform + void cleanTrack(const std::vector& track, + std::deque& tracks, + std::deque& stubs, + double inv2R, + int zT, + int trackId); + // + void route(std::vector>& inputs, std::deque& output) const; + // + void route(std::vector>& input, std::vector>& outputs) const; + // + void sort(std::deque& track, std::vector>& stubs) const; + // + void convert(const std::deque& iTracks, + const std::vector>& iStubs, + std::deque& oTracks, + std::vector>& oStubs); + // remove and return first element of deque, returns nullptr if empty + template + T* pop_front(std::deque& ts) const; + // provides run-time constants + const tt::Setup* setup_; + // provides dataformats + const DataFormats* dataFormats_; + // + const LayerEncoding* layerEncoding_; + // + DataFormat cot_; + // container of internal stubs + std::vector stubs_; + // container of internal tracks + std::vector tracks_; + // container of output stubs + std::vector& stubsCTB_; + // container of output tracks + std::vector& tracksCTB_; + // number of output channel + int numChannelOut_; + // number of channel + int numChannel_; + // number of processing regions + int numRegions_; + // number of kf layers + int numLayers_; + int wlayer_; + const DataFormat& r_; + const DataFormat& phi_; + const DataFormat& z_; + const DataFormat& phiT_; + const DataFormat& zT_; + int numBinsInv2R_; + int numBinsPhiT_; + int numBinsCot_; + int numBinsZT_; + double baseInv2R_; + double basePhiT_; + double baseCot_; + double baseZT_; + }; + +} // namespace trackerTFP + +#endif diff --git a/L1Trigger/TrackerTFP/interface/DataFormats.h b/L1Trigger/TrackerTFP/interface/DataFormats.h index 054f97807e20f..f573dfee2a745 100644 --- a/L1Trigger/TrackerTFP/interface/DataFormats.h +++ b/L1Trigger/TrackerTFP/interface/DataFormats.h @@ -10,7 +10,6 @@ and in undigitized format in an std::tuple. (This saves CPU) ----------------------------------------------------------------------*/ #include "FWCore/Framework/interface/data_default_record_trait.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" #include "L1Trigger/TrackerTFP/interface/DataFormatsRcd.h" #include "L1Trigger/TrackTrigger/interface/Setup.h" #include "DataFormats/L1TrackTrigger/interface/TTBV.h" @@ -25,55 +24,27 @@ and in undigitized format in an std::tuple. (This saves CPU) namespace trackerTFP { // track trigger processes - enum class Process { begin, fe = begin, dtc, pp, gp, ht, mht, zht, kfin, kf, dr, end, x }; + enum class Process { begin, dtc = begin, pp, gp, ht, ctb, kf, dr, tfp, end, x }; // track trigger variables - enum class Variable { - begin, - r = begin, - phi, - z, - layer, - sectorsPhi, - sectorEta, - sectorPhi, - phiT, - inv2R, - zT, - cot, - dPhi, - dZ, - match, - hitPattern, - phi0, - z0, - end, - x - }; + enum class Variable { begin, r = begin, phi, z, dPhi, dZ, inv2R, phiT, cot, zT, layer, match, end, x }; // track trigger process order - constexpr std::initializer_list Processes = {Process::fe, - Process::dtc, - Process::pp, - Process::gp, - Process::ht, - Process::mht, - Process::zht, - Process::kfin, - Process::kf, - Process::dr}; + constexpr std::initializer_list Processes = { + Process::dtc, Process::pp, Process::gp, Process::ht, Process::ctb, Process::kf, Process::dr, Process::tfp}; // conversion: Process to int inline constexpr int operator+(Process p) { return static_cast(p); } // conversion: Variable to int inline constexpr int operator+(Variable v) { return static_cast(v); } - // increment of Process - inline constexpr Process operator++(Process p) { return Process(+p + 1); } - // increment of Variable - inline constexpr Variable operator++(Variable v) { return Variable(+v + 1); } + inline constexpr Process operator+(Process p, int i) { return Process(+p + i); } + inline constexpr Variable operator+(Variable v, int i) { return Variable(+v + i); } //Base class representing format of a variable class DataFormat { public: - DataFormat(bool twos) : twos_(twos), width_(0), base_(1.), range_(0.) {} - ~DataFormat() {} + DataFormat() {} + DataFormat(bool twos, bool biased = true) : twos_(twos), width_(0), base_(1.), range_(0.) {} + DataFormat(bool twos, int width, double base, double range) + : twos_(twos), width_(width), base_(base), range_(range) {} + virtual ~DataFormat() {} // converts int to bitvector TTBV ttBV(int i) const { return TTBV(i, width_, twos_); } // converts double to bitvector @@ -84,12 +55,14 @@ namespace trackerTFP { void extract(TTBV& in, double& out) const { out = in.extract(base_, width_, twos_); } // extracts double from bitvector, removing these bits from bitvector void extract(TTBV& in, TTBV& out) const { out = in.slice(width_, twos_); } + // extracts bool from bitvector, removing these bits from bitvector + void extract(TTBV& in, bool& out) const { out = in.extract(); } // attaches integer to bitvector void attach(const int i, TTBV& ttBV) const { ttBV += TTBV(i, width_, twos_); } // attaches double to bitvector void attach(const double d, TTBV& ttBV) const { ttBV += TTBV(d, base_, width_, twos_); } // attaches bitvector to bitvector - void attach(const TTBV bv, TTBV& ttBV) const { ttBV += bv; } + void attach(const TTBV& bv, TTBV& ttBV) const { ttBV += bv; } // converts int to double double floating(int i) const { return (i + .5) * base_; } // converts double to int @@ -102,8 +75,10 @@ namespace trackerTFP { int toUnsigned(int i) const { return i + std::pow(2, width_) / 2; } // converts floating point value to binary integer value int toUnsigned(double d) const { return this->integer(d) + std::pow(2, width_) / 2; } + // biggest representable floating point value + //double limit() const { return (range_ - base_) / (twos_ ? 2. : 1.); } // returns false if data format would oferflow for this double value - bool inRange(double d, bool digi = false) const { + bool inRange(double d, bool digi = true) const { const double range = digi ? base_ * pow(2, width_) : range_; return d >= -range / 2. && d < range / 2.; } @@ -129,84 +104,72 @@ namespace trackerTFP { double range_; }; - // class representing format of a specific variable + // function template for DataFormat generation template - class Format : public DataFormat { - public: - Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); - ~Format() {} - }; + DataFormat makeDataFormat(const tt::Setup* setup); + + // specializations template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); - template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); - template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); - template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); - template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); - template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); - template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); - template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); - template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); + template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); + template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); + template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); + template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); + template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); + template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + DataFormat makeDataFormat(const tt::Setup* setup); /*! \class trackerTFP::DataFormats * \brief Class to calculate and provide dataformats used by Track Trigger emulator @@ -217,295 +180,180 @@ namespace trackerTFP { private: // variable flavour mapping, Each row below declares which processing steps use the variable named in the comment at the end of the row static constexpr std::array, +Variable::end> config_ = {{ - // Process::fe Process::dtc Process::pp Process::gp Process::ht Process::mht Process::zht Process::kfin Process::kf Process::dr - {{Process::x, - Process::ht, - Process::ht, - Process::ht, - Process::ht, - Process::ht, - Process::ht, - Process::ht, - Process::ht, - Process::x}}, // Variable::r - {{Process::x, + // Process::dtc Process::pp Process::gp Process::ht Process::ctb Process::kf Process::dr, Process::tfp + {{Process::dtc, Process::dtc, Process::dtc, - Process::gp, - Process::ht, - Process::mht, - Process::zht, - Process::kfin, - Process::kfin, - Process::x}}, // Variable::phi - {{Process::x, Process::dtc, + Process::dtc, + Process::dtc, + Process::dtc, + Process::x}}, // Variable::r + {{Process::dtc, Process::dtc, Process::gp, - Process::gp, - Process::gp, - Process::zht, - Process::kfin, - Process::kfin, - Process::x}}, // Variable::z - {{Process::x, - Process::ht, - Process::ht, - Process::ht, Process::ht, Process::ht, - Process::ht, - Process::x, - Process::x, - Process::x}}, // Variable::layer - {{Process::x, - Process::dtc, + Process::kf, + Process::kf, + Process::x}}, // Variable::phi + {{Process::dtc, Process::dtc, - Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::x}}, // Variable::sectorsPhi - {{Process::x, - Process::gp, Process::gp, Process::gp, Process::gp, Process::gp, Process::gp, - Process::gp, - Process::gp, - Process::x}}, // Variable::sectorEta + Process::x}}, // Variable::z {{Process::x, Process::x, Process::x, - Process::gp, - Process::gp, - Process::gp, - Process::gp, - Process::gp, - Process::gp, - Process::x}}, // Variable::sectorPhi + Process::x, + Process::ctb, + Process::ctb, + Process::ctb, + Process::x}}, // Variable::dPhi {{Process::x, + Process::x, + Process::x, + Process::x, + Process::ctb, + Process::ctb, + Process::ctb, + Process::x}}, // Variable::dZ + {{Process::ht, Process::ht, Process::ht, Process::ht, Process::ht, - Process::mht, - Process::mht, - Process::mht, Process::kf, - Process::x}}, // Variable::phiT - {{Process::x, - Process::ht, - Process::ht, + Process::kf, + Process::tfp}}, // Variable::inv2R + {{Process::gp, + Process::gp, + Process::gp, Process::ht, Process::ht, - Process::mht, - Process::mht, - Process::mht, Process::kf, - Process::dr}}, // Variable::inv2R - {{Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::zht, - Process::zht, Process::kf, - Process::x}}, // Variable::zT + Process::tfp}}, // Variable::phiT {{Process::x, Process::x, + Process::gp, Process::x, - Process::x, - Process::x, - Process::x, - Process::zht, - Process::zht, + Process::gp, Process::kf, - Process::dr}}, // Variable::cot - {{Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::kfin, - Process::kfin, - Process::x}}, // Variable::dPhi - {{Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::kfin, - Process::kfin, - Process::x}}, // Variable::dZ - {{Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::x, + Process::dr, + Process::tfp}}, // Variable::cot + {{Process::gp, + Process::gp, + Process::gp, + Process::gp, + Process::gp, Process::kf, - Process::x}}, // Variable::match - {{Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::kfin, - Process::x, - Process::x}}, // Variable::hitPattern - {{Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::dr}}, // Variable::phi0 - {{Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::x, - Process::x, + Process::kf, + Process::tfp}}, // Variable::zT + {{Process::dtc, + Process::dtc, + Process::gp, + Process::gp, + Process::ctb, Process::x, Process::x, - Process::dr}} // Variable::z0 + Process::x}}, // Variable::layer + {{Process::x, Process::x, Process::x, Process::x, Process::x, Process::kf, Process::x, Process::x}} // Variable::match }}; // stub word assembly, shows which stub variables are used by each process static constexpr std::array, +Process::end> stubs_ = {{ - {}, // Process::fe {Variable::r, Variable::phi, Variable::z, Variable::layer, - Variable::sectorsPhi, - Variable::sectorEta, - Variable::sectorEta, + Variable::phiT, + Variable::phiT, + Variable::zT, + Variable::zT, Variable::inv2R, Variable::inv2R}, // Process::dtc {Variable::r, Variable::phi, Variable::z, Variable::layer, - Variable::sectorsPhi, - Variable::sectorEta, - Variable::sectorEta, - Variable::inv2R, - Variable::inv2R}, // Process::pp - {Variable::r, Variable::phi, Variable::z, Variable::layer, Variable::inv2R, Variable::inv2R}, // Process::gp - {Variable::r, - Variable::phi, - Variable::z, - Variable::layer, - Variable::sectorPhi, - Variable::sectorEta, - Variable::phiT}, // Process::ht - {Variable::r, - Variable::phi, - Variable::z, - Variable::layer, - Variable::sectorPhi, - Variable::sectorEta, Variable::phiT, - Variable::inv2R}, // Process::mht - {Variable::r, - Variable::phi, - Variable::z, - Variable::layer, - Variable::sectorPhi, - Variable::sectorEta, Variable::phiT, - Variable::inv2R, Variable::zT, - Variable::cot}, // Process::zht - {Variable::r, Variable::phi, Variable::z, Variable::dPhi, Variable::dZ}, // Process::kfin - {Variable::r, Variable::phi, Variable::z, Variable::dPhi, Variable::dZ}, // Process::kf - {} // Process::dr + Variable::zT, + Variable::inv2R, + Variable::inv2R}, // Process::pp + {Variable::r, Variable::phi, Variable::z, Variable::layer, Variable::inv2R, Variable::inv2R}, // Process::gp + {Variable::r, Variable::phi, Variable::z, Variable::layer, Variable::phiT, Variable::zT}, // Process::ht + {Variable::r, Variable::phi, Variable::z, Variable::dPhi, Variable::dZ}, // Process::ctb + {Variable::r, Variable::phi, Variable::z, Variable::dPhi, Variable::dZ}, // Process::kf + {Variable::r, Variable::phi, Variable::z, Variable::dPhi, Variable::dZ}, // Process::dr + {} // Process::tfp }}; // track word assembly, shows which track variables are used by each process static constexpr std::array, +Process::end> tracks_ = {{ - {}, // Process::fe - {}, // Process::dtc - {}, // Process::pp - {}, // Process::gp - {}, // Process::ht - {}, // Process::mht - {}, // Process::zht - {Variable::hitPattern, - Variable::sectorPhi, - Variable::sectorEta, - Variable::phiT, - Variable::inv2R, - Variable::zT, - Variable::cot}, // Process::kfin - {Variable::match, - Variable::sectorPhi, - Variable::sectorEta, - Variable::phiT, - Variable::inv2R, - Variable::cot, - Variable::zT}, // Process::kf - {Variable::phi0, Variable::inv2R, Variable::z0, Variable::cot} // Process::dr + {}, // Process::dtc + {}, // Process::pp + {}, // Process::gp + {}, // Process::ht + {Variable::inv2R, Variable::phiT, Variable::zT}, // Process::ctb + {Variable::inv2R, Variable::phiT, Variable::cot, Variable::zT, Variable::match}, // Process::kf + {Variable::inv2R, Variable::phiT, Variable::cot, Variable::zT}, // Process::dr + {} // Process::tfp }}; public: DataFormats(); - DataFormats(const edm::ParameterSet& iConfig, const tt::Setup* setup); - ~DataFormats() {} - // bool indicating if hybrid or tmtt being used - bool hybrid() const { return iConfig_.getParameter("UseHybrid"); } + DataFormats(const tt::Setup* setup); + ~DataFormats() = default; // converts bits to ntuple of variables template - void convertStub(Process p, const tt::Frame& bv, std::tuple& data) const; + void convertStub(Process p, const tt::Frame& bv, std::tuple& data) const { + TTBV ttBV(bv); + extractStub(p, ttBV, data); + } // converts ntuple of variables to bits template - void convertStub(Process p, const std::tuple& data, tt::Frame& bv) const; + void convertStub(Process p, const std::tuple& data, tt::Frame& bv) const { + TTBV ttBV(1, numUnusedBitsStubs_[+p]); + attachStub(p, data, ttBV); + bv = ttBV.bs(); + } // converts bits to ntuple of variables template - void convertTrack(Process p, const tt::Frame& bv, std::tuple& data) const; + void convertTrack(Process p, const tt::Frame& bv, std::tuple& data) const { + TTBV ttBV(bv); + extractTrack(p, ttBV, data); + } // converts ntuple of variables to bits template - void convertTrack(Process p, const std::tuple& data, tt::Frame& bv) const; + void convertTrack(Process p, const std::tuple& data, tt::Frame& bv) const { + TTBV ttBV(1, numUnusedBitsTracks_[+p]); + attachTrack(p, data, ttBV); + bv = ttBV.bs(); + } // access to run-time constants const tt::Setup* setup() const { return setup_; } // number of bits being used for specific variable flavour int width(Variable v, Process p) const { return formats_[+v][+p]->width(); } // precision being used for specific variable flavour double base(Variable v, Process p) const { return formats_[+v][+p]->base(); } + // covered range for specific variable flavour + double range(Variable v, Process p) const { return formats_[+v][+p]->range(); } // number of unused frame bits for a given Stub flavour int numUnusedBitsStubs(Process p) const { return numUnusedBitsStubs_[+p]; } // number of unused frame bits for a given Track flavour int numUnusedBitsTracks(Process p) const { return numUnusedBitsTracks_[+p]; } // number of channels of a given process on a TFP int numChannel(Process p) const { return numChannel_[+p]; } - // number of channels of a given process for whole system - int numStreams(Process p) const { return numStreams_[+p]; } - // + // number of stub channels of a given process for whole system int numStreamsStubs(Process p) const { return numStreamsStubs_[+p]; } - // + // number of track channels of a given process for whole system int numStreamsTracks(Process p) const { return numStreamsTracks_[+p]; } // access to spedific format const DataFormat& format(Variable v, Process p) const { return *formats_[+v][+p]; } - // critical radius defining region overlap shape in cm - double chosenRofPhi() const { return hybrid() ? setup_->hybridChosenRofPhi() : setup_->chosenRofPhi(); } private: // number of unique data formats @@ -521,18 +369,36 @@ namespace trackerTFP { void fillFormats(); // helper (loop) to convert bits to ntuple of variables template - void extractStub(Process p, TTBV& ttBV, std::tuple& data) const; + void extractStub(Process p, TTBV& ttBV, std::tuple& data) const { + Variable v = *std::next(stubs_[+p].begin(), sizeof...(Ts) - 1 - it); + formats_[+v][+p]->extract(ttBV, std::get(data)); + if constexpr (it + 1 != sizeof...(Ts)) + extractStub(p, ttBV, data); + } // helper (loop) to convert bits to ntuple of variables template - void extractTrack(Process p, TTBV& ttBV, std::tuple& data) const; + void extractTrack(Process p, TTBV& ttBV, std::tuple& data) const { + Variable v = *std::next(tracks_[+p].begin(), sizeof...(Ts) - 1 - it); + formats_[+v][+p]->extract(ttBV, std::get(data)); + if constexpr (it + 1 != sizeof...(Ts)) + extractTrack(p, ttBV, data); + } // helper (loop) to convert ntuple of variables to bits template - void attachStub(Process p, const std::tuple& data, TTBV& ttBV) const; + void attachStub(Process p, const std::tuple& data, TTBV& ttBV) const { + Variable v = *std::next(stubs_[+p].begin(), it); + formats_[+v][+p]->attach(std::get(data), ttBV); + if constexpr (it + 1 != sizeof...(Ts)) + attachStub(p, data, ttBV); + } // helper (loop) to convert ntuple of variables to bits template - void attachTrack(Process p, const std::tuple& data, TTBV& ttBV) const; - // configuration during construction - edm::ParameterSet iConfig_; + void attachTrack(Process p, const std::tuple& data, TTBV& ttBV) const { + Variable v = *std::next(tracks_[+p].begin(), it); + formats_[+v][+p]->attach(std::get(data), ttBV); + if constexpr (it + 1 != sizeof...(Ts)) + attachTrack(p, data, ttBV); + } // stored run-time constants const tt::Setup* setup_; // collection of unique formats @@ -545,11 +411,9 @@ namespace trackerTFP { std::vector numUnusedBitsTracks_; // number of channels of all processes on a TFP std::vector numChannel_; - // number of channels of all processes for whole system - std::vector numStreams_; - // + // number of stub channels of all processes for whole system std::vector numStreamsStubs_; - // + // number of track channels of all processes for whole system std::vector numStreamsTracks_; }; @@ -558,12 +422,20 @@ namespace trackerTFP { class Stub { public: // construct Stub from Frame - Stub(const tt::FrameStub& frame, const DataFormats* dataFormats, Process p); + Stub(const tt::FrameStub& fs, const DataFormats* df, Process p) : dataFormats_(df), p_(p), frame_(fs) { + dataFormats_->convertStub(p_, frame_.second, data_); + } template // construct Stub from other Stub - Stub(const Stub& stub, Ts... data); + Stub(const Stub& stub, Ts... data) + : dataFormats_(stub.dataFormats()), p_(stub.p() + 1), frame_(stub.frame()), data_(data...) { + dataFormats_->convertStub(p_, data_, frame_.second); + } // construct Stub from TTStubRef - Stub(const TTStubRef& ttStubRef, const DataFormats* dataFormats, Process p, Ts... data); + Stub(const TTStubRef& ttStubRef, const DataFormats* df, Process p, Ts... data) + : dataFormats_(df), p_(p), frame_(ttStubRef, tt::Frame()), data_(data...) { + dataFormats_->convertStub(p_, data_, frame_.second); + } Stub() {} ~Stub() {} // true if frame valid, false if gap in data stream @@ -573,21 +445,9 @@ namespace trackerTFP { // stub flavour Process p() const { return p_; } // acess to frame - tt::FrameStub frame() const { return frame_; } - // access to TTStubRef - TTStubRef ttStubRef() const { return frame_.first; } - // access to bitvector - tt::Frame bv() const { return frame_.second; } - // id of collection this stub belongs to - int trackId() const { return trackId_; } + const tt::FrameStub& frame() const { return frame_; } protected: - // number of used bits for given variable - int width(Variable v) const { return dataFormats_->width(v, p_); } - // precision of given variable - double base(Variable v) const { return dataFormats_->base(v, p_); } - // format of given variable - DataFormat format(Variable v) const { return dataFormats_->format(v, p_); } // all dataformats const DataFormats* dataFormats_; // stub flavour @@ -596,208 +456,131 @@ namespace trackerTFP { tt::FrameStub frame_; // ntuple of variables this stub is assemled of std::tuple data_; - // id of collection this stub belongs to - int trackId_; + }; + + // class to represent stubs generated by process DTC + class StubDTC : public Stub { + public: + // construct StubDTC from TTStubRef + StubDTC(const TTStubRef& ttStubRef, + const DataFormats* df, + double r, + double phi, + double z, + const TTBV& layer, + int phiTMin, + int phiTMax, + int zTMin, + int zTMax, + int inv2RMin, + int inv2RMax) + : Stub(ttStubRef, df, Process::dtc, r, phi, z, layer, phiTMin, phiTMax, zTMin, zTMax, inv2RMin, inv2RMax) {} + ~StubDTC() {} + // stub radius wrt chosenRofPhi + double r() const { return std::get<0>(data_); } + // stub phi wrt processing nonant centre + double phi() const { return std::get<1>(data_); } + // stub z + double z() const { return std::get<2>(data_); } + // enhanced layer id + TTBV layer() const { return std::get<3>(data_); } + // first phi sector this stub belongs to + int phiTMin() const { return std::get<4>(data_); } + // last phi sector this stub belongs to + int phiTMax() const { return std::get<5>(data_); } + // first eta sector this stub belongs to + int zTMin() const { return std::get<6>(data_); } + // last eta sector this stub belongs to + int zTMax() const { return std::get<7>(data_); } + // first inv2R bin this stub belongs to + int inv2RMin() const { return std::get<8>(data_); } + // last inv2R bin this stub belongs to + int inv2RMax() const { return std::get<9>(data_); } }; // class to represent stubs generated by process patch pannel - class StubPP : public Stub { + class StubPP : public Stub { public: // construct StubPP from Frame - StubPP(const tt::FrameStub& frame, const DataFormats* dataFormats); + StubPP(const tt::FrameStub& fs, const DataFormats* df) : Stub(fs, df, Process::pp) {} ~StubPP() {} - // true if stub belongs to given sector - bool inSector(int sector) const { return sectors_[sector]; } - // sectors this stub belongs to - std::vector sectors() const { return sectors_.ids(); } // stub radius wrt chosenRofPhi double r() const { return std::get<0>(data_); } // stub phi wrt processing nonant centre double phi() const { return std::get<1>(data_); } // stub z double z() const { return std::get<2>(data_); } - // reduced layer id - int layer() const { return std::get<3>(data_); } - // phi sector map to which this stub belongs to - TTBV sectorsPhi() const { return std::get<4>(data_); } + // enhanced layer id + const TTBV& layer() const { return std::get<3>(data_); } + // first phi sector this stub belongs to + int phiTMin() const { return std::get<4>(data_); } + // last phi sector this stub belongs to + int phiTMax() const { return std::get<5>(data_); } // first eta sector this stub belongs to - int sectorEtaMin() const { return std::get<5>(data_); } + int zTMin() const { return std::get<6>(data_); } // last eta sector this stub belongs to - int sectorEtaMax() const { return std::get<6>(data_); } + int zTMax() const { return std::get<7>(data_); } // first inv2R bin this stub belongs to - int inv2RMin() const { return std::get<7>(data_); } + int inv2RMin() const { return std::get<8>(data_); } // last inv2R bin this stub belongs to - int inv2RMax() const { return std::get<8>(data_); } - - private: - // sectors this stub belongs to - TTBV sectors_; + int inv2RMax() const { return std::get<9>(data_); } }; // class to represent stubs generated by process geometric processor - class StubGP : public Stub { + class StubGP : public Stub { public: // construct StubGP from Frame - StubGP(const tt::FrameStub& frame, const DataFormats* dataFormats, int sectorPhi, int sectorEta); - // construct StubGO from StubPP - StubGP(const StubPP& stub, int sectorPhi, int sectorEta); + StubGP(const tt::FrameStub& fs, const DataFormats* df) : Stub(fs, df, Process::gp) {} + // construct StubGP from StubPP + StubGP(const StubPP& stub, double r, double phi, double z, const TTBV& layer, int inv2RMin, int inv2RMax) + : Stub(stub, r, phi, z, layer, inv2RMin, inv2RMax) {} ~StubGP() {} - // true if stub belongs to given inv2R bin - bool inInv2RBin(int inv2RBin) const { return inv2RBins_[inv2RBin]; } - // inv2R bins this stub belongs to - std::vector inv2RBins() const { return inv2RBins_.ids(); } - // stub phi sector - int sectorPhi() const { return sectorPhi_; } - // stub eta sector - int sectorEta() const { return sectorEta_; } // stub radius wrt chosenRofPhi double r() const { return std::get<0>(data_); } // stub phi wrt phi sector centre double phi() const { return std::get<1>(data_); } // stub z residual wrt eta sector double z() const { return std::get<2>(data_); } - // reduced layer id - int layer() const { return std::get<3>(data_); } + // enhanced layer id + const TTBV& layer() const { return std::get<3>(data_); } // first inv2R bin this stub belongs to int inv2RMin() const { return std::get<4>(data_); } // last inv2R bin this stub belongs to int inv2RMax() const { return std::get<5>(data_); } - - private: - // inv2R bins this stub belongs to - TTBV inv2RBins_; - // stub phi sector - int sectorPhi_; - // stub eta sector - int sectorEta_; }; // class to represent stubs generated by process hough transform - class StubHT : public Stub { + class StubHT : public Stub { public: // construct StubHT from Frame - StubHT(const tt::FrameStub& frame, const DataFormats* dataFormats, int inv2R); - // construct StubHT from StubGP and HT cell assignment - StubHT(const StubGP& stub, int phiT, int inv2R); + StubHT(const tt::FrameStub& fs, const DataFormats* df) : Stub(fs, df, Process::ht) {} + // construct StubHT from StubGP + StubHT(const StubGP& stub, double r, double phi, double z, const TTBV& layer, int phiT, int zT) + : Stub(stub, r, phi, z, layer, phiT, zT) {} ~StubHT() {} - // stub qOver pt - int inv2R() const { return inv2R_; } // stub radius wrt chosenRofPhi double r() const { return std::get<0>(data_); }; // stub phi residual wrt track parameter double phi() const { return std::get<1>(data_); }; // stub z residual wrt eta sector double z() const { return std::get<2>(data_); }; - // reduced layer id - int layer() const { return std::get<3>(data_); }; - // phi sector - int sectorPhi() const { return std::get<4>(data_); }; + // enhanced layer id + const TTBV& layer() const { return std::get<3>(data_); } + // stub phi at radius chosenRofPhi wrt processing nonant centre + int phiT() const { return std::get<4>(data_); }; // eta sector - int sectorEta() const { return std::get<5>(data_); }; - // stub phi at radius chosenRofPhi wrt phi sector centre - int phiT() const { return std::get<6>(data_); }; - - private: - // fills track id - void fillTrackId(); - // stub qOver pt - int inv2R_; - }; - - // class to represent stubs generated by process mini hough transform - class StubMHT : public Stub { - public: - // construct StubMHT from Frame - StubMHT(const tt::FrameStub& frame, const DataFormats* dataFormats); - // construct StubMHT from StubHT and MHT cell assignment - StubMHT(const StubHT& stub, int phiT, int inv2R); - ~StubMHT() {} - // stub radius wrt choenRofPhi - double r() const { return std::get<0>(data_); } - // stub phi residual wrt finer track parameter - double phi() const { return std::get<1>(data_); } - // stub z rsidual wrt eta sector - double z() const { return std::get<2>(data_); } - // reduced layer id - int layer() const { return std::get<3>(data_); } - // phi sector - int sectorPhi() const { return std::get<4>(data_); } - // eta sector - int sectorEta() const { return std::get<5>(data_); } - // stub phi at radius chosenRofPhi wrt phi sector centre - int phiT() const { return std::get<6>(data_); } - // stub inv2R - int inv2R() const { return std::get<7>(data_); } - - private: - // fills track id - void fillTrackId(); + int zT() const { return std::get<5>(data_); }; }; - // class to represent stubs generated by process z hough transform - class StubZHT : public Stub { + // class to represent stubs generated by process CTB + class StubCTB : public Stub { public: - // construct StubZHT from Frame - StubZHT(const tt::FrameStub& frame, const DataFormats* dataFormats); - // construct StubZHT from StubMHT - StubZHT(const StubMHT& stub); - // - StubZHT(const StubZHT& stub, double zT, double cot, int id); - // - StubZHT(const StubZHT& stub, int cot, int zT); - ~StubZHT() {} - // stub radius wrt chonseRofPhi - double r() const { return std::get<0>(data_); } - // stub phiresiudal wrt finer track parameter - double phi() const { return std::get<1>(data_); } - // stub z residual to track parameter - double z() const { return std::get<2>(data_); } - // reduced layer id - int layer() const { return std::get<3>(data_); } - // phi sector - int sectorPhi() const { return std::get<4>(data_); } - // eta sector - int sectorEta() const { return std::get<5>(data_); } - // stub phi at radius chosenRofPhi wrt phi sector centre - int phiT() const { return std::get<6>(data_); } - // stub inv2R - int inv2R() const { return std::get<7>(data_); } - // stub z at radius chosenRofZ wrt eta sector centre - int zT() const { return std::get<8>(data_); } - // stub cotTheta wrt eta sector cotTheta - int cot() const { return std::get<9>(data_); } - double cotf() const { return cot_; } - double ztf() const { return zT_; } - double chi() const { return chi_; } - - private: - // fills track id - void fillTrackId(); - double r_; - double chi_; - double cot_; - double zT_; - }; - - // class to represent stubs generated by process kfin - class StubKFin : public Stub { - public: - // construct StubKFin from Frame - StubKFin(const tt::FrameStub& frame, const DataFormats* dataFormats, int layer); - // construct StubKFin from StubZHT - StubKFin(const StubZHT& stub, double dPhi, double dZ, int layer); - // construct StubKFin from TTStubRef - StubKFin(const TTStubRef& ttStubRef, - const DataFormats* dataFormats, - double r, - double phi, - double z, - double dPhi, - double dZ, - int layer); - ~StubKFin() {} - // kf layer id - int layer() const { return layer_; } + // construct StubTB from Frame + StubCTB(const tt::FrameStub& fs, const DataFormats* df) : Stub(fs, df, Process::ctb) {} + // construct StubTB from StubZHT + StubCTB(const StubHT& stub, double r, double phi, double z, double dPhi, double dZ) + : Stub(stub, r, phi, z, dPhi, dZ) {} + ~StubCTB() {} // stub radius wrt chosenRofPhi double r() const { return std::get<0>(data_); } // stub phi residual wrt finer track parameter @@ -808,22 +591,17 @@ namespace trackerTFP { double dPhi() const { return std::get<3>(data_); } // stub z uncertainty double dZ() const { return std::get<4>(data_); } - - private: - // kf layer id - int layer_; }; // class to represent stubs generated by process kalman filter class StubKF : public Stub { public: // construct StubKF from Frame - StubKF(const tt::FrameStub& frame, const DataFormats* dataFormats, int layer); - // construct StubKF from StubKFin - StubKF(const StubKFin& stub, double inv2R, double phiT, double cot, double zT); + StubKF(const tt::FrameStub& fs, const DataFormats* df) : Stub(fs, df, Process::kf) {} + // construct StubKF from StubCTB + StubKF(const StubCTB& stub, double r, double phi, double z, double dPhi, double dZ) + : Stub(stub, r, phi, z, dPhi, dZ) {} ~StubKF() {} - // kf layer id - int layer() const { return layer_; } // stub radius wrt choenRofPhi double r() const { return std::get<0>(data_); } // stub phi residual wrt fitted parameter @@ -834,10 +612,27 @@ namespace trackerTFP { double dPhi() const { return std::get<3>(data_); } // stub z uncertainty double dZ() const { return std::get<4>(data_); } + }; - private: - // kf layer id - int layer_; + // class to represent stubs generated by process duplicate removal + class StubDR : public Stub { + public: + // construct StubDR from Frame + StubDR(const tt::FrameStub& fs, const DataFormats* df) : Stub(fs, df, Process::dr) {} + // construct StubDR from StubKF + StubDR(const StubKF& stub, double r, double phi, double z, double dPhi, double dZ) + : Stub(stub, r, phi, z, dPhi, dZ) {} + ~StubDR() {} + // stub radius wrt choenRofPhi + double r() const { return std::get<0>(data_); } + // stub phi residual wrt fitted parameter + double phi() const { return std::get<1>(data_); } + // stub z residual wrt fitted parameter + double z() const { return std::get<2>(data_); } + // stub phi uncertainty + double dPhi() const { return std::get<3>(data_); } + // stub z uncertainty + double dZ() const { return std::get<4>(data_); } }; // base class to represent tracks @@ -845,15 +640,20 @@ namespace trackerTFP { class Track { public: // construct Track from Frame - Track(const tt::FrameTrack& frame, const DataFormats* dataFormats, Process p); + Track(const tt::FrameTrack& ft, const DataFormats* df, Process p) : dataFormats_(df), p_(p), frame_(ft) { + dataFormats_->convertTrack(p_, frame_.second, data_); + } + // construct Track from TTTrackRef + Track(const TTTrackRef& ttTrackRef, const DataFormats* df, Process p, Ts... data) + : dataFormats_(df), p_(p), frame_(ttTrackRef, tt::Frame()), data_(data...) { + dataFormats_->convertTrack(p_, data_, frame_.second); + } // construct Track from other Track template - Track(const Track& track, Ts... data); - // construct Track from Stub - template - Track(const Stub& stub, const TTTrackRef& ttTrackRef, Ts... data); - // construct Track from TTTrackRef - Track(const TTTrackRef& ttTrackRef, const DataFormats* dataFormats, Process p, Ts... data); + Track(const Track& track, Ts... data) + : dataFormats_(track.dataFormats()), p_(track.p() + 1), frame_(track.frame()), data_(data...) { + dataFormats_->convertTrack(p_, data_, frame_.second); + } ~Track() {} // true if frame valid, false if gap in data stream explicit operator bool() const { return frame_.first.isNonnull(); } @@ -862,25 +662,9 @@ namespace trackerTFP { // track flavour Process p() const { return p_; } // acces to frame - tt::FrameTrack frame() const { return frame_; } - // access to TTTrackRef - TTTrackRef ttTrackRef() const { return frame_.first; } - // access to bitvector - tt::Frame bv() const { return frame_.second; } - // access to ntuple of variables this track is assemled of - std::tuple data() const { return data_; } + const tt::FrameTrack& frame() const { return frame_; } protected: - //number of bits uesd of given variable - int width(Variable v) const { return dataFormats_->width(v, p_); } - // precision of given variable - double base(Variable v) const { return dataFormats_->base(v, p_); } - // access to run-time constants - const tt::Setup* setup() const { return dataFormats_->setup(); } - // format of given variable - DataFormat format(Variable v) const { return dataFormats_->format(v, p_); } - // format of given variable and process - DataFormat format(Variable v, Process p) const { return dataFormats_->format(v, p); } // all data formats const DataFormats* dataFormats_; // track flavour @@ -891,168 +675,61 @@ namespace trackerTFP { std::tuple data_; }; - class TrackKFin : public Track { + // class to represent tracks generated by process Clean Track Builder + class TrackCTB : public Track { public: - // construct TrackKFin from Frame - TrackKFin(const tt::FrameTrack& frame, const DataFormats* dataFormats, const std::vector& stubs); - // construct TrackKFin from StubKFin - TrackKFin(const StubZHT& stub, const TTTrackRef& ttTrackRef, const TTBV& maybePattern); - // construct TrackKFin from TTTrackRef - TrackKFin(const TTTrackRef& ttTrackRef, - const DataFormats* dataFormats, - const TTBV& maybePattern, - double phiT, - double qOverPt, - double zT, - double cot, - int sectorPhi, - int sectorEta); - ~TrackKFin() {} - // pattern of layers which are only maybe crossed by found candidate - const TTBV& maybePattern() const { return std::get<0>(data_); } - // phi sector - int sectorPhi() const { return std::get<1>(data_); } - // eta sector - int sectorEta() const { return std::get<2>(data_); } - // track phi at radius chosenRofPhi wrt phi sector centre - double phiT() const { return std::get<3>(data_); } + // construct TrackTB from Frame + TrackCTB(const tt::FrameTrack& ft, const DataFormats* df) : Track(ft, df, Process::ctb) {} + // construct TrackTB from StubsCTB + TrackCTB(const TTTrackRef& tTTrackRef, const DataFormats* df, double inv2R, double phiT, double zT) + : Track(tTTrackRef, df, Process::ctb, inv2R, phiT, zT) {} + ~TrackCTB() {} // track inv2R - double inv2R() const { return std::get<4>(data_); } - // track z at radius chosenRofZ wrt eta sector centre - double zT() const { return std::get<5>(data_); } - // track cotTheta wrt seta sector cotTheta - double cot() const { return std::get<6>(data_); } - // - TTBV hitPattern() const { return hitPattern_; } - // true if given layer has a hit - bool hitPattern(int index) const { return hitPattern_[index]; } - // true if given layer has a hit or is a maybe layer - bool maybePattern(int index) const { return hitPattern_[index] || maybePattern()[index]; } - // stubs on a given layer - std::vector layerStubs(int layer) const { return stubs_[layer]; } - // firts stub on a given layer - StubKFin* layerStub(int layer) const { return stubs_[layer].front(); } - // selection of ttStubRefs for given hit ids on given layers - std::vector ttStubRefs(const TTBV& hitPattern, const std::vector& layerMap) const; - // stubs organized in layer - std::vector> stubs() const { return stubs_; } - // global cotTheta - double cotGlobal() const { return cot() + setup()->sectorCot(sectorEta()); } - - private: - // stubs organized in layer - std::vector> stubs_; - // - TTBV hitPattern_; + double inv2R() const { return std::get<0>(data_); } + // track phi at radius chosenRofPhi wrt pprocessing centre + double phiT() const { return std::get<1>(data_); } + // track z at radius chosenRofZ + double zT() const { return std::get<2>(data_); } }; // class to represent tracks generated by process kalman filter - class TrackKF : public Track { + class TrackKF : public Track { public: // construct TrackKF from Frame - TrackKF(const tt::FrameTrack& frame, const DataFormats* dataFormats); - // construct TrackKF from TrackKFKFin - TrackKF(const TrackKFin& track, double phiT, double inv2R, double zT, double cot); + TrackKF(const tt::FrameTrack& ft, const DataFormats* df) : Track(ft, df, Process::kf) {} + // construct TrackKF from TrackCTB + TrackKF(const TrackCTB& track, double inv2R, double phiT, double cot, double zT, const TTBV& match) + : Track(track, inv2R, phiT, cot, zT, match) {} ~TrackKF() {} - // true if kf prameter consistent with mht parameter - bool match() const { return std::get<0>(data_); } - // phi sector - int sectorPhi() const { return std::get<1>(data_); } - // eta sector - int sectorEta() const { return std::get<2>(data_); } - // track phi at radius chosenRofPhi wrt phi sector centre - double phiT() const { return std::get<3>(data_); } // track qOver pt - double inv2R() const { return std::get<4>(data_); } + double inv2R() const { return std::get<0>(data_); } + // track phi at radius chosenRofPhi wrt processing nonant centre + double phiT() const { return std::get<1>(data_); } // track cotTheta wrt eta sector cotTheta - double cot() const { return std::get<5>(data_); } - // track z at radius chosenRofZ wrt eta sector centre - double zT() const { return std::get<6>(data_); } - // global cotTheta - double cotGlobal() const { return cot() + setup()->sectorCot(sectorEta()); } - // conversion to TTTrack with given stubs - TTTrack ttTrack(const std::vector& stubs) const; - - private: - }; - - //Class to represent KFout 96-bit track for use in distribution server - class TrackKFOut { - public: - TrackKFOut() : TrackKFOut(0, 0, 0, 0, 0, tt::FrameTrack(), 0, 0, false) {} - // construct TrackKF from Partial Tracks - TrackKFOut(TTBV PartialTrack1, - TTBV PartialTrack2, - TTBV PartialTrack3, - int sortKey, - int nonantId, - const tt::FrameTrack& track, - int trackID, - int linkID, - bool valid) - : PartialTrack1_(PartialTrack1), - PartialTrack2_(PartialTrack2), - PartialTrack3_(PartialTrack3), - sortKey_(sortKey), - nonantId_(nonantId), - track_(track), - trackID_(trackID), - linkID_(linkID), - valid_(valid) {} - - ~TrackKFOut() {} - - int sortKey() const { return sortKey_; } - int nonantId() const { return nonantId_; } - - bool dataValid() const { return valid_; } - - int trackID() const { return trackID_; } - int linkID() const { return linkID_; } - - TTBV PartialTrack1() const { return PartialTrack1_; } - TTBV PartialTrack2() const { return PartialTrack2_; } - TTBV PartialTrack3() const { return PartialTrack3_; } - - tt::FrameTrack track() const { return track_; } - - private: - TTBV PartialTrack1_; - TTBV PartialTrack2_; - TTBV PartialTrack3_; - int sortKey_; - int nonantId_; - tt::FrameTrack track_; - int trackID_; - int linkID_; - bool valid_; + double cot() const { return std::get<2>(data_); } + // track z at radius chosenRofZ + double zT() const { return std::get<3>(data_); } + // true if kf prameter consistent with mht parameter + const TTBV& match() const { return std::get<4>(data_); } }; - typedef std::vector TrackKFOutSACollection; - typedef std::shared_ptr TrackKFOutSAPtr; - typedef std::vector TrackKFOutSAPtrCollection; - typedef std::vector>> TrackKFOutSAPtrCollections; - typedef std::vector>>> TrackKFOutSAPtrCollectionss; // class to represent tracks generated by process duplicate removal class TrackDR : public Track { public: // construct TrackDR from Frame - TrackDR(const tt::FrameTrack& frame, const DataFormats* dataFormats); + TrackDR(const tt::FrameTrack& ft, const DataFormats* df) : Track(ft, df, Process::dr) {} // construct TrackDR from TrackKF - TrackDR(const TrackKF& track); + TrackDR(const TrackKF& track, double inv2R, double phiT, double cot, double zT) + : Track(track, inv2R, phiT, cot, zT) {} ~TrackDR() {} - // track phi at radius 0 wrt processing nonant centre - double phi0() const { return std::get<0>(data_); } // track inv2R - double inv2R() const { return std::get<1>(data_); } - // track z at radius 0 - double z0() const { return std::get<2>(data_); } + double inv2R() const { return std::get<0>(data_); } + // track phi at radius 0 wrt processing nonant centre + double phiT() const { return std::get<1>(data_); } // track cotThea - double cot() const { return std::get<3>(data_); } - // conversion to TTTrack - TTTrack ttTrack() const; - - private: + double cot() const { return std::get<2>(data_); } + // track z at radius 0 + double zT() const { return std::get<3>(data_); } }; } // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/interface/Demonstrator.h b/L1Trigger/TrackerTFP/interface/Demonstrator.h index b76b38f64e76b..2be82cb907e10 100644 --- a/L1Trigger/TrackerTFP/interface/Demonstrator.h +++ b/L1Trigger/TrackerTFP/interface/Demonstrator.h @@ -2,7 +2,6 @@ #define L1Trigger_TrackerTFP_Demonstrator_h #include "FWCore/Framework/interface/data_default_record_trait.h" -#include "L1Trigger/TrackerTFP/interface/DemonstratorRcd.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "L1Trigger/TrackTrigger/interface/Setup.h" @@ -12,30 +11,39 @@ namespace trackerTFP { /*! \class trackerTFP::Demonstrator - * \brief Compares emulator with f/w - * \author Thomas Schuh + * \brief ESProduct providing the algorithm to run input data through modelsim + * and to compares results with expected output data * \date 2021, April */ class Demonstrator { public: + // configuration + struct Config { + std::string dirIPBB_; + double runTime_; + std::vector linkMappingIn_; + std::vector linkMappingOut_; + }; Demonstrator() {} - Demonstrator(const edm::ParameterSet& iConfig, const tt::Setup* setup); - ~Demonstrator() {} + Demonstrator(const Config& iConfig, const tt::Setup* setup); + //~Demonstrator() {} // plays input through modelsim and compares result with output bool analyze(const std::vector>& input, const std::vector>& output) const; private: // converts streams of bv into stringstream - void convert(const std::vector>& bits, std::stringstream& ss) const; + void convert(const std::vector>& bits, + std::stringstream& ss, + const std::vector& mapping) const; // plays stringstream through modelsim void sim(const std::stringstream& ss) const; // compares stringstream with modelsim output bool compare(std::stringstream& ss) const; // creates emp file header - std::string header(int numChannel) const; + std::string header(const std::vector& links) const; // creates 6 frame gap between packets - std::string infraGap(int& nFrame, int numChannel) const; + std::string infraGap(int& nFrame, int numLinks) const; // creates frame number std::string frame(int& nFrame) const; // converts bv into hex @@ -45,6 +53,10 @@ namespace trackerTFP { std::string dirIPBB_; // runtime in ms double runTime_; + // + std::vector linkMappingIn_; + // + std::vector linkMappingOut_; // path to input text file std::string dirIn_; // path to output text file @@ -63,6 +75,6 @@ namespace trackerTFP { } // namespace trackerTFP -EVENTSETUP_DATA_DEFAULT_RECORD(trackerTFP::Demonstrator, trackerTFP::DemonstratorRcd); +EVENTSETUP_DATA_DEFAULT_RECORD(trackerTFP::Demonstrator, tt::SetupRcd); #endif diff --git a/L1Trigger/TrackerTFP/interface/DemonstratorRcd.h b/L1Trigger/TrackerTFP/interface/DemonstratorRcd.h deleted file mode 100644 index 8be74ebeac572..0000000000000 --- a/L1Trigger/TrackerTFP/interface/DemonstratorRcd.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef L1Trigger_TrackerTFP_DemonstratorRcd_h -#define L1Trigger_TrackerTFP_DemonstratorRcd_h - -#include "FWCore/Framework/interface/DependentRecordImplementation.h" -#include "L1Trigger/TrackTrigger/interface/SetupRcd.h" -#include "FWCore/Utilities/interface/mplVector.h" - -namespace trackerTFP { - - typedef edm::mpl::Vector RcdsDemonstrator; - - // record of trackerTFP::Demonstrator - class DemonstratorRcd : public edm::eventsetup::DependentRecordImplementation {}; - -} // namespace trackerTFP - -#endif diff --git a/L1Trigger/TrackerTFP/interface/DuplicateRemoval.h b/L1Trigger/TrackerTFP/interface/DuplicateRemoval.h new file mode 100644 index 0000000000000..56ddd67837b81 --- /dev/null +++ b/L1Trigger/TrackerTFP/interface/DuplicateRemoval.h @@ -0,0 +1,65 @@ +#ifndef L1Trigger_TrackerTFP_DuplicateRemoval_h +#define L1Trigger_TrackerTFP_DuplicateRemoval_h + +#include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackerTFP/interface/DataFormats.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" + +#include + +namespace trackerTFP { + + // Class to do duplicate removal in a region. + class DuplicateRemoval { + public: + DuplicateRemoval(const tt::Setup* setup, + const DataFormats* dataFormats, + std::vector& tracks, + std::vector& stubs); + ~DuplicateRemoval() {} + // fill output products + void produce(const std::vector>& tracksIn, + const std::vector>& stubsIn, + std::vector>& tracksOut, + std::vector>& stubsOut); + + private: + struct Track { + Track(TrackKF* track, const std::vector& stubs, bool match, int inv2R, int phiT, int zT) + : track_(track), stubs_(stubs), match_(match), inv2R_(inv2R), phiT_(phiT), zT_(zT) {} + // + TrackKF* track_; + // + std::vector stubs_; + // + bool match_; + // + int inv2R_; + // + int phiT_; + // + int zT_; + }; + // provides run-time constants + const tt::Setup* setup_; + // provides dataformats + const DataFormats* dataFormats_; + // container of output tracks + std::vector& tracks_; + // container of output stubs + std::vector& stubs_; + // number of channel + int numChannel_; + // number of kf layers + int numLayers_; + // number of bins in inv2R + int numInv2R_; + // number of bins in phiT + int numPhiT_; + // number of bins in zT + int numZT_; + }; + +} // namespace trackerTFP + +#endif diff --git a/L1Trigger/TrackerTFP/interface/GeometricProcessor.h b/L1Trigger/TrackerTFP/interface/GeometricProcessor.h index 07fc8858c872f..385260c4dd866 100644 --- a/L1Trigger/TrackerTFP/interface/GeometricProcessor.h +++ b/L1Trigger/TrackerTFP/interface/GeometricProcessor.h @@ -1,9 +1,11 @@ #ifndef L1Trigger_TrackerTFP_GeometricProcessor_h #define L1Trigger_TrackerTFP_GeometricProcessor_h +#include "FWCore/ParameterSet/interface/ParameterSet.h" #include "L1Trigger/TrackTrigger/interface/Setup.h" #include "L1Trigger/TrackerTFP/interface/DataFormats.h" -#include "DataFormats/L1TrackTrigger/interface/TTDTC.h" +#include "L1Trigger/TrackerTFP/interface/LayerEncoding.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" #include #include @@ -13,36 +15,33 @@ namespace trackerTFP { // Class to route Stubs of one region to one stream per sector class GeometricProcessor { public: - GeometricProcessor(const edm::ParameterSet& iConfig, - const tt::Setup* setup_, + GeometricProcessor(const tt::Setup* setup_, const DataFormats* dataFormats, - int region); + const LayerEncoding* layerEncoding, + std::vector& stubs); ~GeometricProcessor() {} - // read in and organize input product (fill vector input_) - void consume(const TTDTC& ttDTC); - // fill output products - void produce(tt::StreamsStub& accepted, tt::StreamsStub& lost); + // fill output data + void produce(const std::vector>& streamsIn, std::vector>& streamsOut); private: + // convert stub + StubGP* produce(const StubPP& stub, int phiT, int zT); // remove and return first element of deque, returns nullptr if empty template T* pop_front(std::deque& ts) const; - - // true if truncation is enbaled - bool enableTruncation_; // provides run-time constants const tt::Setup* setup_; // provides dataformats const DataFormats* dataFormats_; - // processing region (0 - 8) - const int region_; - // storage of input stubs - std::vector stubsPP_; + // provides layer encoding + const LayerEncoding* layerEncoding_; // storage of output stubs - std::vector stubsGP_; - // h/w liked organized pointer to input stubs - std::vector>> input_; + std::vector& stubs_; + // number of input channel + int numChannelIn_; + // number of output channel + int numChannelOut_; }; } // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/interface/HoughTransform.h b/L1Trigger/TrackerTFP/interface/HoughTransform.h index 680a76b325aa9..c3bc12ca93847 100644 --- a/L1Trigger/TrackerTFP/interface/HoughTransform.h +++ b/L1Trigger/TrackerTFP/interface/HoughTransform.h @@ -3,10 +3,10 @@ #include "L1Trigger/TrackTrigger/interface/Setup.h" #include "L1Trigger/TrackerTFP/interface/DataFormats.h" +#include "L1Trigger/TrackerTFP/interface/LayerEncoding.h" #include "DataFormats/L1TrackTrigger/interface/TTTypes.h" #include -#include #include namespace trackerTFP { @@ -14,51 +14,50 @@ namespace trackerTFP { // Class to find initial rough candidates in r-phi in a region class HoughTransform { public: - HoughTransform(const edm::ParameterSet& iConfig, const tt::Setup* setup, const DataFormats* dataFormats, int region); + HoughTransform(const tt::Setup* setup, + const DataFormats* dataFormats, + const LayerEncoding* layerEncoding, + std::vector& stubs); ~HoughTransform() {} - - // read in and organize input product - void consume(const tt::StreamsStub& streams); // fill output products - void produce(tt::StreamsStub& accepted, tt::StreamsStub& lost); + void produce(const std::vector>& streamsIn, std::vector>& streamsOut); private: // remove and return first element of deque, returns nullptr if empty template T* pop_front(std::deque& ts) const; // associate stubs with phiT bins in this inv2R column - void fillIn(int inv2R, - std::deque& inputSector, - std::vector& acceptedSector, - std::vector& lostSector); + void fillIn(int inv2R, int sector, const std::vector& input, std::vector& output); // identify tracks - void readOut(const std::vector& acceptedSector, - const std::vector& lostSector, - std::deque& acceptedAll, - std::deque& lostAll) const; - // identify lost tracks - void analyze(); - // store tracks - void put() const; - - // true if truncation is enbaled - bool enableTruncation_; + void readOut(const std::vector& input, std::deque& output) const; + // + bool noTrack(const TTBV& pattern, int zT) const; // provides run-time constants const tt::Setup* setup_; // provides dataformats const DataFormats* dataFormats_; + // + const LayerEncoding* layerEncoding_; // data format of inv2R - DataFormat inv2R_; + const DataFormat* inv2R_; // data format of phiT - DataFormat phiT_; - // processing region (0 - 8) - int region_; - // container of input stubs - std::vector stubsGP_; - // container of output stubs - std::vector stubsHT_; - // h/w liked organized pointer to input stubs - std::vector>> input_; + const DataFormat* phiT_; + // data format of zT + const DataFormat* zT_; + // data format of phi + const DataFormat* phi_; + // data format of z + const DataFormat* z_; + // container of stubs + std::vector& stubs_; + // number of input channel + int numChannelIn_; + // number of output channel + int numChannelOut_; + // + int chan_; + // + int mux_; }; } // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/interface/KalmanFilter.h b/L1Trigger/TrackerTFP/interface/KalmanFilter.h index d875f6ad7756f..adeb64b425521 100644 --- a/L1Trigger/TrackerTFP/interface/KalmanFilter.h +++ b/L1Trigger/TrackerTFP/interface/KalmanFilter.h @@ -3,110 +3,143 @@ #include "L1Trigger/TrackTrigger/interface/Setup.h" #include "L1Trigger/TrackerTFP/interface/DataFormats.h" +#include "L1Trigger/TrackerTFP/interface/LayerEncoding.h" #include "L1Trigger/TrackerTFP/interface/KalmanFilterFormats.h" #include "L1Trigger/TrackerTFP/interface/State.h" #include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include #include +#include namespace trackerTFP { // Class to do helix fit to all tracks in a region. class KalmanFilter { public: - KalmanFilter(const edm::ParameterSet& iConfig, - const tt::Setup* setup, + typedef State::Stub Stub; + KalmanFilter(const tt::Setup* setup, const DataFormats* dataFormats, + const LayerEncoding* layerEncoding, KalmanFilterFormats* kalmanFilterFormats, - int region); + std::vector& tracks, + std::vector& stubs); ~KalmanFilter() {} - // read in and organize input tracks and stubs - void consume(const tt::StreamsTrack& streamsTrack, const tt::StreamsStub& streamsStub); // fill output products - void produce(tt::StreamsStub& accpetedStubs, - tt::StreamsTrack& acceptedTracks, - tt::StreamsStub& lostStubs, - tt::StreamsTrack& lostTracks, + void produce(const std::vector>& tracksIn, + const std::vector>& stubsIn, + std::vector>& tracksOut, + std::vector>>& stubsOut, int& numAcceptedStates, - int& numLostStates); + int& numLostStates, + std::deque>& chi2s); private: + // + struct Track { + Track() {} + Track(int trackId, + int numConsistent, + int numConsistentPS, + double inv2R, + double phiT, + double cot, + double zT, + double chi20, + double chi21, + const TTBV& hitPattern, + TrackCTB* track, + const std::vector& stubs, + const std::vector& phi, + const std::vector& z) + : trackId_(trackId), + numConsistent_(numConsistent), + numConsistentPS_(numConsistentPS), + inv2R_(inv2R), + phiT_(phiT), + cot_(cot), + zT_(zT), + chi20_(chi20), + chi21_(chi21), + hitPattern_(hitPattern), + track_(track), + stubs_(stubs), + phi_(phi), + z_(z) {} + int trackId_; + int numConsistent_; + int numConsistentPS_; + double inv2R_; + double phiT_; + double cot_; + double zT_; + double chi20_; + double chi21_; + TTBV hitPattern_; + TrackCTB* track_; + std::vector stubs_; + std::vector phi_; + std::vector z_; + }; // remove and return first element of deque, returns nullptr if empty template T* pop_front(std::deque& ts) const; - // remove and return first element of vector, returns nullptr if empty - template - T* pop_front(std::vector& ts) const; + // constraints double precision + double digi(VariableKF var, double val) const { return kalmanFilterFormats_->format(var).digi(val); } + // + int integer(VariableKF var, double val) const { return kalmanFilterFormats_->format(var).integer(val); } + // + void updateRangeActual(VariableKF var, double val) { + return kalmanFilterFormats_->format(var).updateRangeActual(val); + } + // + double base(VariableKF var) const { return kalmanFilterFormats_->format(var).base(); } + // + int width(VariableKF var) const { return kalmanFilterFormats_->format(var).width(); } + // + int inRange(VariableKF var, double val) const { return kalmanFilterFormats_->format(var).inRange(val); } + // create Proto States + void createProtoStates(const std::vector>& tracksIn, + const std::vector>& stubsIn, + int channel, + std::deque& stream); + // calulcate seed parameter + void calcSeeds(std::deque& stream); + // apply final cuts + void finalize(const std::deque& stream, std::vector& finals); + // Transform States into Tracks + void conv(const std::vector& best, std::vector& tracks, std::vector>& stubs); // adds a layer to states void addLayer(std::deque& stream); + // adds a layer to states to build seeds + void addSeedLayer(std::deque& stream); // Assign next combinatoric (i.e. not first in layer) stub to state void comb(State*& state); // best state selection - void accumulator(std::deque& stream); + void accumulator(std::vector& finals, std::vector& best); // updates state void update(State*& state); - // true if truncation is enbaled - bool enableTruncation_; // provides run-time constants const tt::Setup* setup_; // provides dataformats const DataFormats* dataFormats_; + // provides layer Encoding + const LayerEncoding* layerEncoding_; // provides dataformats of Kalman filter internals KalmanFilterFormats* kalmanFilterFormats_; - // processing region (0 - 8) - int region_; - // container of input stubs - std::vector stubs_; - // container of input tracks - std::vector tracks_; + // container of output tracks + std::vector& tracks_; + // container of output stubs + std::vector& stubs_; // container of all Kalman Filter states std::deque states_; - // h/w liked organized pointer to input stubs - std::vector> input_; + // + std::vector finals_; // current layer used during state propagation int layer_; - - // dataformats of Kalman filter internals - - DataFormatKF* x0_; - DataFormatKF* x1_; - DataFormatKF* x2_; - DataFormatKF* x3_; - DataFormatKF* H00_; - DataFormatKF* H12_; - DataFormatKF* m0_; - DataFormatKF* m1_; - DataFormatKF* v0_; - DataFormatKF* v1_; - DataFormatKF* r0_; - DataFormatKF* r1_; - DataFormatKF* S00_; - DataFormatKF* S01_; - DataFormatKF* S12_; - DataFormatKF* S13_; - DataFormatKF* K00_; - DataFormatKF* K10_; - DataFormatKF* K21_; - DataFormatKF* K31_; - DataFormatKF* R00_; - DataFormatKF* R11_; - DataFormatKF* R00Rough_; - DataFormatKF* R11Rough_; - DataFormatKF* invR00Approx_; - DataFormatKF* invR11Approx_; - DataFormatKF* invR00Cor_; - DataFormatKF* invR11Cor_; - DataFormatKF* invR00_; - DataFormatKF* invR11_; - DataFormatKF* C00_; - DataFormatKF* C01_; - DataFormatKF* C11_; - DataFormatKF* C22_; - DataFormatKF* C23_; - DataFormatKF* C33_; }; } // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/interface/KalmanFilterFormats.h b/L1Trigger/TrackerTFP/interface/KalmanFilterFormats.h index 918e61a69fc2c..9e0afef87c161 100644 --- a/L1Trigger/TrackerTFP/interface/KalmanFilterFormats.h +++ b/L1Trigger/TrackerTFP/interface/KalmanFilterFormats.h @@ -6,8 +6,6 @@ Classes to calculate and provide dataformats used by Kalman Filter emulator enabling tuning of bit widths ----------------------------------------------------------------------*/ -#include "FWCore/Framework/interface/data_default_record_trait.h" -#include "L1Trigger/TrackerTFP/interface/KalmanFilterFormatsRcd.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "L1Trigger/TrackerTFP/interface/DataFormats.h" @@ -39,6 +37,10 @@ namespace trackerTFP { S01, S12, S13, + S00Shifted, + S01Shifted, + S12Shifted, + S13Shifted, K00, K10, K21, @@ -59,142 +61,246 @@ namespace trackerTFP { C22, C23, C33, + r0Shifted, + r1Shifted, + r02, + r12, + chi20, + chi21, + dH, + invdH, + invdH2, + H2, + Hm0, + Hm1, + Hv0, + Hv1, + H2v0, + H2v1, end, x }; inline constexpr int operator+(VariableKF v) { return static_cast(v); } - inline constexpr VariableKF operator++(VariableKF v) { return VariableKF(+v + 1); } + inline constexpr VariableKF operator+(VariableKF v, int i) { return VariableKF(+v + i); } + + // Configuration + struct ConfigKF { + bool enableIntegerEmulation_; + int widthR00_; + int widthR11_; + int widthC00_; + int widthC01_; + int widthC11_; + int widthC22_; + int widthC23_; + int widthC33_; + int baseShiftx0_; + int baseShiftx1_; + int baseShiftx2_; + int baseShiftx3_; + int baseShiftr0_; + int baseShiftr1_; + int baseShiftS00_; + int baseShiftS01_; + int baseShiftS12_; + int baseShiftS13_; + int baseShiftR00_; + int baseShiftR11_; + int baseShiftInvR00Approx_; + int baseShiftInvR11Approx_; + int baseShiftInvR00Cor_; + int baseShiftInvR11Cor_; + int baseShiftInvR00_; + int baseShiftInvR11_; + int baseShiftS00Shifted_; + int baseShiftS01Shifted_; + int baseShiftS12Shifted_; + int baseShiftS13Shifted_; + int baseShiftK00_; + int baseShiftK10_; + int baseShiftK21_; + int baseShiftK31_; + int baseShiftC00_; + int baseShiftC01_; + int baseShiftC11_; + int baseShiftC22_; + int baseShiftC23_; + int baseShiftC33_; + int baseShiftr0Shifted_; + int baseShiftr1Shifted_; + int baseShiftr02_; + int baseShiftr12_; + int baseShiftchi20_; + int baseShiftchi21_; + }; class DataFormatKF { public: - DataFormatKF(const VariableKF& v, bool twos); + DataFormatKF(const VariableKF& v, bool twos, bool enableIntegerEmulation, int width, double base, double range); virtual ~DataFormatKF() {} - double digi(double val) const { return (std::floor(val / base_ + 1.e-12) + .5) * base_; } + double digi(double val) const { + return enableIntegerEmulation_ ? (std::floor(val / base_ + 1.e-11) + .5) * base_ : val; + } bool twos() const { return twos_; } int width() const { return width_; } double base() const { return base_; } double range() const { return range_; } - const std::pair& rangeActual() const { return rangeActual_; } + double min() const { return min_; } + double abs() const { return abs_; } + double max() const { return max_; } // returns false if data format would oferflow for this double value bool inRange(double d) const; void updateRangeActual(double d); - int integer(double d) const { return floor(d / base_); } + int integer(double d) const { return floor(d / base_ + 1.e-11); } protected: VariableKF v_; bool twos_; + bool enableIntegerEmulation_; int width_; double base_; double range_; - std::pair rangeActual_; + double min_; + double abs_; + double max_; }; - template - class FormatKF : public DataFormatKF { + class KalmanFilterFormats { public: - FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); - ~FormatKF() override {} + KalmanFilterFormats(); + ~KalmanFilterFormats() = default; + void beginRun(const DataFormats* dataFormats, const ConfigKF& iConfig); + const tt::Setup* setup() const { return dataFormats_->setup(); } + const DataFormats* dataFormats() const { return dataFormats_; } + DataFormatKF& format(VariableKF v) { return formats_[+v]; } + void endJob(std::stringstream& ss); private: - void calcRange() { range_ = base_ * pow(2, width_); } + template + void fillFormats(); + ConfigKF iConfig_; + const DataFormats* dataFormats_; + std::vector formats_; }; + // function template for DataFormat generation + template + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); - - class KalmanFilterFormats { - public: - KalmanFilterFormats(); - KalmanFilterFormats(const edm::ParameterSet& iConfig, const DataFormats* dataFormats); - ~KalmanFilterFormats() {} - const tt::Setup* setup() const { return setup_; } - const DataFormats* dataFormats() const { return dataFormats_; } - int width(VariableKF v) const { return formats_[+v].width(); } - double base(VariableKF v) const { return formats_[+v].base(); } - DataFormatKF& format(VariableKF v) { return formats_[+v]; } - void endJob(); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); - private: - template - void fillFormats(); - const edm::ParameterSet iConfig_; - const DataFormats* dataFormats_; - const tt::Setup* setup_; - std::vector formats_; - }; + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig); } // namespace trackerTFP -EVENTSETUP_DATA_DEFAULT_RECORD(trackerTFP::KalmanFilterFormats, trackerTFP::KalmanFilterFormatsRcd); - #endif diff --git a/L1Trigger/TrackerTFP/interface/KalmanFilterFormatsRcd.h b/L1Trigger/TrackerTFP/interface/KalmanFilterFormatsRcd.h deleted file mode 100644 index 86345133b31a5..0000000000000 --- a/L1Trigger/TrackerTFP/interface/KalmanFilterFormatsRcd.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef L1Trigger_TrackerTFP_KalmanFilterFormatsRcd_h -#define L1Trigger_TrackerTFP_KalmanFilterFormatsRcd_h - -#include "FWCore/Framework/interface/DependentRecordImplementation.h" -#include "L1Trigger/TrackerTFP/interface/DataFormatsRcd.h" -#include "FWCore/Utilities/interface/mplVector.h" - -namespace trackerTFP { - - typedef edm::mpl::Vector RcdsKalmanFilterFormats; - - class KalmanFilterFormatsRcd - : public edm::eventsetup::DependentRecordImplementation {}; - -} // namespace trackerTFP - -#endif diff --git a/L1Trigger/TrackerTFP/interface/LayerEncoding.h b/L1Trigger/TrackerTFP/interface/LayerEncoding.h index a5adaf15b8b0b..7dfb95ef1d513 100644 --- a/L1Trigger/TrackerTFP/interface/LayerEncoding.h +++ b/L1Trigger/TrackerTFP/interface/LayerEncoding.h @@ -2,7 +2,6 @@ #define L1Trigger_TrackerTFP_LayerEncoding_h #include "FWCore/Framework/interface/data_default_record_trait.h" -#include "L1Trigger/TrackerTFP/interface/LayerEncodingRcd.h" #include "L1Trigger/TrackerTFP/interface/DataFormats.h" #include "L1Trigger/TrackTrigger/interface/SensorModule.h" @@ -12,7 +11,7 @@ namespace trackerTFP { /*! \class trackerTFP::LayerEncoding * \brief Class to encode layer ids for Kalman Filter - * Layers consitent with rough r-z track parameters are counted from 0 onwards. + * Layers (1 to 6 for barrel, 11 to 15 for end caps) consitent with rough r-z track parameters are counted from 0 onwards (0 to 7). * \author Thomas Schuh * \date 2020, July */ @@ -21,21 +20,17 @@ namespace trackerTFP { LayerEncoding() {} LayerEncoding(const DataFormats* dataFormats); ~LayerEncoding() {} - // Set of layers in each (zT,tanL) digi Bin of each eta sector numbered 0->N - const std::vector& layerEncoding(int binEta, int binZT, int binCot) const { - return layerEncoding_.at(binEta).at(binZT).at(binCot); - } - const std::map& layerEncodingMap(int binEta, int binZT, int binCot) const { - return layerEncodingMap_.at(binEta).at(binZT).at(binCot); - } - // maybe layers for given ets sector, bin in zT and bin in cotThea - const std::vector& maybeLayer(int binEta, int binZT, int binCot) const { - return maybeLayer_.at(binEta).at(binZT).at(binCot); - } - // encoded layer id for given eta sector, bin in zT, bin in cotThea and decoed layer id, returns -1 if layer incositent with track - const int layerIdKF(int binEta, int binZT, int binCot, int layerId) const; - // pattern of maybe layers for given eta sector, bin in zT and bin in cotThea - TTBV maybePattern(int binEta, int binZT, int binCot) const; + // Set of layers for given bin in zT + const std::vector& layerEncoding(int zT) const; + // Set of layers for given zT in cm + const std::vector& layerEncoding(double zT) const; + // pattern of maybe layers for given bin in zT + const TTBV& maybePattern(int zT) const; + // pattern of maybe layers for given zT in cm + const TTBV& maybePattern(double zT) const; + // fills numPS, num2S, numMissingPS and numMissingPS for given hitPattern and trajectory + void analyze( + int hitpattern, double cot, double z0, int& numPS, int& num2S, int& numMissingPS, int& numMissing2S) const; private: // helper class providing run-time constants @@ -44,17 +39,16 @@ namespace trackerTFP { const DataFormats* dataFormats_; // data foramt of variable zT const DataFormat* zT_; - // data foramt of variable cotTheta - const DataFormat* cot_; - // outer to inner indices: eta sector, bin in zT, bin in cotTheta, layerId - std::vector>>> layerEncoding_; - std::vector>>> layerEncodingMap_; - // outer to inner indices: eta sector, bin in zT, bin in cotTheta, layerId of maybe layers - std::vector>>> maybeLayer_; + // outer to inner indices: bin in zT, layerId + std::vector> layerEncoding_; + // outer to inner indices: bin in zT, maybe patterns + std::vector maybePattern_; + std::vector nullLE_; + TTBV nullMP_; }; } // namespace trackerTFP -EVENTSETUP_DATA_DEFAULT_RECORD(trackerTFP::LayerEncoding, trackerTFP::LayerEncodingRcd); +EVENTSETUP_DATA_DEFAULT_RECORD(trackerTFP::LayerEncoding, trackerTFP::DataFormatsRcd); #endif diff --git a/L1Trigger/TrackerTFP/interface/LayerEncodingRcd.h b/L1Trigger/TrackerTFP/interface/LayerEncodingRcd.h deleted file mode 100644 index 84294bcc01e5e..0000000000000 --- a/L1Trigger/TrackerTFP/interface/LayerEncodingRcd.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef L1Trigger_TrackerTFP_LayerEncodingRcd_h -#define L1Trigger_TrackerTFP_LayerEncodingRcd_h - -#include "FWCore/Framework/interface/DependentRecordImplementation.h" -#include "L1Trigger/TrackerTFP/interface/DataFormatsRcd.h" -#include "FWCore/Utilities/interface/mplVector.h" - -namespace trackerTFP { - - typedef edm::mpl::Vector RcdsLayerEncoding; - - // record of trackerTFP::LayerEncoding - class LayerEncodingRcd : public edm::eventsetup::DependentRecordImplementation { - }; - -} // namespace trackerTFP - -#endif diff --git a/L1Trigger/TrackerTFP/interface/MiniHoughTransform.h b/L1Trigger/TrackerTFP/interface/MiniHoughTransform.h deleted file mode 100644 index 2c3a622d1c2be..0000000000000 --- a/L1Trigger/TrackerTFP/interface/MiniHoughTransform.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef L1Trigger_TrackerTFP_MiniHoughTransform_h -#define L1Trigger_TrackerTFP_MiniHoughTransform_h - -#include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" - -#include -#include -#include - -namespace trackerTFP { - - // Class to refine HT track candidates in r-phi, by subdividing each HT cell into a finer granularity array - class MiniHoughTransform { - public: - MiniHoughTransform(const edm::ParameterSet& iConfig, - const tt::Setup* setup, - const DataFormats* dataFormats, - int region); - ~MiniHoughTransform() {} - - // read in and organize input product (fill vector input_) - void consume(const tt::StreamsStub& streams); - // fill output products - void produce(tt::StreamsStub& accepted, tt::StreamsStub& lost); - - private: - // remove and return first element of deque, returns nullptr if empty - template - T* pop_front(std::deque& ts) const; - // perform finer pattern recognition per track - void fill(int channel, const std::vector& input, std::vector>& output); - // Static load balancing of inputs: mux 4 streams to 1 stream - void slb(std::vector>& inputs, std::vector& accepted, tt::StreamStub& lost) const; - // Dynamic load balancing of inputs: swapping parts of streams to balance the amount of tracks per stream - void dlb(std::vector>& streams) const; - - // true if truncation is enbaled - bool enableTruncation_; - // provides run-time constants - const tt::Setup* setup_; - // provides dataformats - const DataFormats* dataFormats_; - // dataformat of inv2R - DataFormat inv2R_; - // dataformat of phiT - DataFormat phiT_; - // processing region (0 - 8) - int region_; - // number of inv2R bins used in HT - int numBinsInv2R_; - // number of cells used in MHT - int numCells_; - // number of dynamic load balancing nodes - int numNodes_; - // number of channel per dynamic load balancing node - int numChannel_; - // container of input stubs - std::vector stubsHT_; - // container of output stubs - std::vector stubsMHT_; - // h/w liked organized pointer to input stubs - std::vector> input_; - }; - -} // namespace trackerTFP - -#endif diff --git a/L1Trigger/TrackerTFP/interface/State.h b/L1Trigger/TrackerTFP/interface/State.h index fe6806b1e0ea3..5f49750d2b709 100644 --- a/L1Trigger/TrackerTFP/interface/State.h +++ b/L1Trigger/TrackerTFP/interface/State.h @@ -2,48 +2,59 @@ #define L1Trigger_TrackerTFP_State_h #include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" +#include "L1Trigger/TrackerTFP/interface/KalmanFilterFormats.h" #include #include namespace trackerTFP { - // Class to represent a Kalman Filter State + // Class to represent a Kalman Filter helix State class State { public: - // default constructor + // + struct Stub { + Stub(KalmanFilterFormats* formats, const tt::FrameStub& frame); + StubCTB stubCTB_; + double H12_; + double v0_; + double v1_; + }; + // copy constructor State(State* state); // proto state constructor - State(const DataFormats* dataFormats, TrackKFin* track, int trackId); - // combinatoric state constructor - State(State* state, StubKFin* stub); + State(KalmanFilterFormats* formats, + TrackCTB* track, + const std::vector>& stubs, + const TTBV& maybe, + int trackId); // updated state constructor State(State* state, const std::vector& doubles); + // combinatoric and seed building state constructor + State(State* state, State* parent, Stub* stub, int layer); ~State() {} - - // Determine quality of completed state - void finish(); - // number of skipped layers - int numSkippedLayers() const { return numSkippedLayers_; } - // number of consitent layers - int numConsistentLayers() const { return numConsistentLayers_; } + // + State* comb(std::deque& states, int layer); + // + State* combSeed(std::deque& states, int layer); + // + State* update(std::deque& states, int layer); // input track - TrackKFin* track() const { return track_; } + TrackCTB* track() const { return track_; } // parent state (nullpointer if no parent available) State* parent() const { return parent_; } // stub to add to state - StubKFin* stub() const { return stub_; } + Stub* stub() const { return stub_; } // hitPattern of so far added stubs const TTBV& hitPattern() const { return hitPattern_; } + // shows which layer the found track has stubs on + const TTBV& trackPattern() const { return trackPattern_; } // track id of input track int trackId() const { return trackId_; } // pattern of maybe layers for input track - TTBV maybePattern() const { return track_->maybePattern(); } - // stub id per layer of so far added stubs - const std::vector& layerMap() const { return layerMap_; } + const TTBV& maybePattern() const { return maybePattern_; } // layer id of the current stub to add - int layer() const { return stub_->layer(); } + int layer() const { return layer_; } // helix inv2R wrt input helix double x0() const { return x0_; } // helix phi at radius ChosenRofPhi wrt input helix @@ -52,6 +63,10 @@ namespace trackerTFP { double x2() const { return x2_; } // helix z at radius chosenRofZ wrt input helix double x3() const { return x3_; } + // chi2 for the r-phi plane straight line fit + double chi20() const { return chi20_; } + // chi2 for the r-z plane straight line fit + double chi21() const { return chi21_; } // cov. matrix element double C00() const { return C00_; } // cov. matrix element @@ -65,65 +80,67 @@ namespace trackerTFP { // cov. matrix element double C33() const { return C33_; } // Derivative of predicted stub coords wrt helix params: stub radius minus chosenRofPhi - double H00() const { return stub_->r(); } + double H00() const { return stub_->stubCTB_.r(); } // Derivative of predicted stub coords wrt helix params: stub radius minus chosenRofZ - double H12() const { return stub_->r() + dataFormats_->chosenRofPhi() - setup_->chosenRofZ(); } + double H12() const { return stub_->H12_; } // stub phi residual wrt input helix - double m0() const { return stub_->phi(); } + double m0() const { return stub_->stubCTB_.phi(); } // stub z residual wrt input helix - double m1() const { return stub_->z(); } + double m1() const { return stub_->stubCTB_.z(); } // stub projected phi uncertainty - double dPhi() const { return stub_->dPhi(); } + double dPhi() const { return stub_->stubCTB_.dPhi(); } // stub projected z uncertainty - double dZ() const { return stub_->dZ(); } + double dZ() const { return stub_->stubCTB_.dZ(); } // squared stub projected phi uncertainty instead of wheight (wrong but simpler) - double v0() const { return pow(stub_->dPhi(), 2); } + double v0() const { return stub_->v0_; } // squared stub projected z uncertainty instead of wheight (wrong but simpler) - double v1() const { return pow(stub_->dZ(), 2); } - // output frame - tt::FrameTrack frame() const { return TrackKF(*track_, x1_, x0_, x3_, x2_).frame(); } - // fill collection of stubs added so far to state - void fill(std::vector& stubs) const; + double v1() const { return stub_->v1_; } + //const std::vector>& stubs() const { return stubs_; } private: + // + bool gapCheck(int layer) const; // provides data fomats - const DataFormats* dataFormats_; + KalmanFilterFormats* formats_; // provides run-time constants const tt::Setup* setup_; // input track - TrackKFin* track_; + TrackCTB* track_; + // input track stubs + std::vector> stubs_; + // pattern of maybe layers for input track + TTBV maybePattern_; // track id int trackId_; // previous state, nullptr for first states - State* parent_; + State* parent_ = nullptr; // stub to add - StubKFin* stub_; - // shows which stub on each layer has been added so far - std::vector layerMap_; + Stub* stub_ = nullptr; + // layer id of the current stub to add + int layer_ = 0; // shows which layer has been added so far TTBV hitPattern_; + // shows which layer the found track has stubs on + TTBV trackPattern_; // helix inv2R wrt input helix - double x0_; + double x0_ = 0.; // helix phi at radius ChosenRofPhi wrt input helix - double x1_; + double x1_ = 0.; // helix cot(Theta) wrt input helix - double x2_; + double x2_ = 0.; // helix z at radius chosenRofZ wrt input helix - double x3_; - + double x3_ = 0.; + // chi2 for the r-phi plane straight line fit + double chi20_ = 0.; + // chi2 for the r-z plane straight line fit + double chi21_ = 0.; // cov. matrix - - double C00_; - double C01_; - double C11_; - double C22_; - double C23_; - double C33_; - - // number of skipped layers - int numSkippedLayers_; - // number of consistent layers - int numConsistentLayers_; + double C00_ = 9.e9; + double C01_ = 0.; + double C11_ = 9.e9; + double C22_ = 9.e9; + double C23_ = 0.; + double C33_ = 9.e9; }; } // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/interface/TrackFindingProcessor.h b/L1Trigger/TrackerTFP/interface/TrackFindingProcessor.h new file mode 100644 index 0000000000000..ff6cfcf95a403 --- /dev/null +++ b/L1Trigger/TrackerTFP/interface/TrackFindingProcessor.h @@ -0,0 +1,86 @@ +#ifndef L1Trigger_TrackerTFP_TrackFindingProcessor_h +#define L1Trigger_TrackerTFP_TrackFindingProcessor_h + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackerTFP/interface/DataFormats.h" +#include "L1Trigger/TrackerTFP/interface/TrackQuality.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" + +#include +#include +#include + +namespace trackerTFP { + + // Class to format final tfp output and to prodcue final TTTrackCollection + class TrackFindingProcessor { + public: + TrackFindingProcessor(const tt::Setup* setup_, const DataFormats* dataFormats, const TrackQuality* trackQuality); + ~TrackFindingProcessor() {} + + // produce TTTracks + void produce(const tt::StreamsTrack& inputs, + const tt::StreamsStub& stubs, + tt::TTTracks& ttTracks, + tt::StreamsTrack& outputs); + // produce StreamsTrack + void produce(const std::vector& inputs, tt::StreamsTrack& outputs) const; + + private: + // number of bits used to describe one part of a track (96 bit) + static constexpr int partial_width = 32; + // number of track parts arriving per clock tick (1 track per tick) + static constexpr int partial_in = 3; + // number of track parts leaving per clock tick (TFP sends 2/3 tracks per clock and link) + static constexpr int partial_out = 2; + // type describing one part of a track + typedef std::bitset PartialFrame; + // type describing one part of a track together with its edm ref + typedef std::pair PartialFrameTrack; + // type representing a track + struct Track { + Track(const tt::FrameTrack& frameTrack, + const tt::Frame& frameTQ, + const std::vector& ttStubRefs, + const TrackQuality* tq); + const TTTrackRef& ttTrackRef_; + const std::vector ttStubRefs_; + bool valid_; + std::vector partials_; + TTBV hitPattern_; + int channel_; + int mva_; + double inv2R_; + double phiT_; + double cot_; + double zT_; + double chi2rphi_; + double chi2rz_; + }; + // remove and return first element of deque, returns nullptr if empty + template + T* pop_front(std::deque& ts) const; + // + void consume(const tt::StreamsTrack& inputs, + const tt::StreamsStub& stubs, + std::vector>& outputs); + // emualte data format f/w + void produce(std::vector>& inputs, tt::StreamsTrack& outputs) const; + // produce TTTracks + void produce(const tt::StreamsTrack& inputs, tt::TTTracks& ouputs) const; + // provides run-time constants + const tt::Setup* setup_; + // provides data formats + const DataFormats* dataFormats_; + // provides Track Quality algo and formats + const TrackQuality* trackQuality_; + // storage of tracks + std::vector tracks_; + // b field + double bfield_; + }; + +} // namespace trackerTFP + +#endif diff --git a/L1Trigger/TrackerTFP/interface/TrackQuality.h b/L1Trigger/TrackerTFP/interface/TrackQuality.h new file mode 100644 index 0000000000000..c2906c90d8033 --- /dev/null +++ b/L1Trigger/TrackerTFP/interface/TrackQuality.h @@ -0,0 +1,177 @@ +/* +Track Quality Header file +C.Brown 28/07/20 +*/ + +#ifndef L1Trigger_TrackerTFP_TrackQuality_h +#define L1Trigger_TrackerTFP_TrackQuality_h + +#include "FWCore/Framework/interface/data_default_record_trait.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "L1Trigger/TrackerTFP/interface/DataFormats.h" + +#include +#include +#include +#include "ap_fixed.h" + +namespace trackerTFP { + + // number of mva bit + static constexpr int widthMVA_ = TTTrack_TrackWord::TrackBitWidths::kMVAQualitySize; + // number of mva bins + static constexpr int numBinsMVA_ = 1 << widthMVA_; + // number of chi2B bins + static constexpr int numBinsChi2B_ = 1 << TTTrack_TrackWord::TrackBitWidths::kBendChi2Size; + // number of chi2rphi bins + static constexpr int numBinschi2rphi_ = 1 << TTTrack_TrackWord::TrackBitWidths::kChi2RPhiSize; + // number of chi2rz bins + static constexpr int numBinschi2rz_ = 1 << TTTrack_TrackWord::TrackBitWidths::kChi2RZSize; + + // track quality variables + enum class VariableTQ { begin, m20 = begin, m21, invV0, invV1, chi2rphi, chi2rz, end, x }; + // conversion: Variable to int + inline constexpr int operator+(VariableTQ v) { return static_cast(v); } + // increment of Variable + inline constexpr VariableTQ operator+(VariableTQ v, int i) { return VariableTQ(+v + i); } + + // configuration + struct ConfigTQ { + edm::FileInPath model_; + std::vector featureNames_; + double baseShiftCot_; + double baseShiftZ0_; + double baseShiftAPfixed_; + int chi2rphiConv_; + int chi2rzConv_; + int weightBinFraction_; + int dzTruncation_; + int dphiTruncation_; + int widthM20_; + int widthM21_; + int widthInvV0_; + int widthInvV1_; + int widthchi2rphi_; + int widthchi2rz_; + int baseShiftchi2rphi_; + int baseShiftchi2rz_; + }; + + // function template for DataFormat generation + template + DataFormat makeDataFormat(const DataFormats* dataFormats, const ConfigTQ& iConfig); + + // specializations + + template <> + DataFormat makeDataFormat(const DataFormats* dataFormats, const ConfigTQ& iConfig); + template <> + DataFormat makeDataFormat(const DataFormats* dataFormats, const ConfigTQ& iConfig); + template <> + DataFormat makeDataFormat(const DataFormats* dataFormats, const ConfigTQ& iConfig); + template <> + DataFormat makeDataFormat(const DataFormats* dataFormats, const ConfigTQ& iConfig); + template <> + DataFormat makeDataFormat(const DataFormats* dataFormats, const ConfigTQ& iConfig); + template <> + DataFormat makeDataFormat(const DataFormats* dataFormats, const ConfigTQ& iConfig); + + /*! \class trackerTFP::TrackQuality + * \brief Bit accurate emulation of the track quality BDT + * \author C.Brown + * \date 28/07/20 + * \update 2024, June by Claire Savard + * \update 2024, Aug by Thomas Schuh + */ + class TrackQuality { + public: + TrackQuality() {} + TrackQuality(const ConfigTQ& iConfig, const DataFormats* dataFormats); + ~TrackQuality() {} + // object to represent tracks + struct Track { + Track(const tt::FrameTrack& frameTrack, const tt::StreamStub& streamStub, const TrackQuality* tq); + // track frame + tt::FrameTrack frameTrack_; + // additional track variables + tt::Frame frame_; + // collection of stubs forming track + tt::StreamStub streamStub_; + }; + // provides dataformats + const DataFormats* dataFormats() const { return dataFormats_; } + // Controls the conversion between TTTrack features and ML model training features + std::vector featureTransform(TTTrack& aTrack, + const std::vector& featureNames) const; + // Passed by reference a track without MVA filled, method fills the track's MVA field + void setL1TrackQuality(TTTrack& aTrack) const; + // Helper function to convert mvaPreSig to bin + int toBinMVA(double mva) const; + // Helper function to convert chi2B to bin + int toBinChi2B(double chi2B) const; + // Helper function to convert chi2rphi to bin + int toBinchi2rphi(double chi2rphi) const; + // Helper function to convert chi2rz to bin + int toBinchi2rz(double chi2rz) const; + // + double scaleCot(int cot) const { return scaleAP(scale(cot, baseShiftCot_)); } + // + double scaleZ0(int z0) const { return scaleAP(scale(z0, baseShiftZ0_)); } + // access to spedific format + const DataFormat& format(VariableTQ v) const { return dataFormatsTQ_[+v]; } + // + double base(VariableTQ v) const { return dataFormatsTQ_[+v].base(); } + // + double range(VariableTQ v) const { return dataFormatsTQ_[+v].range(); } + // + const edm::FileInPath& model() const { return model_; } + + private: + // constructs TQ data formats + template + void fillDataFormats(const ConfigTQ& iConfig); + // TQ MVA bin conversion LUT + constexpr std::array mvaPreSigBins() const; + // + static constexpr double invSigmoid(double value) { return -log(1. / value - 1.); } + // + template + int toBin(const T& bins, double d) const; + // + int scale(int i, int shift) const { return floor(i * pow(2., shift)); } + // + double scaleAP(int i) const { return i * pow(2., baseShiftAPfixed_); } + // provides dataformats + const DataFormats* dataFormats_; + // + ConfigTQ iConfig_; + // + edm::FileInPath model_; + // + std::vector featureNames_; + // + double baseShiftCot_; + // + double baseShiftZ0_; + // + double baseShiftAPfixed_; + // Conversion factor between dphi^2/weight and chi2rphi + int chi2rphiConv_; + // Conversion factor between dz^2/weight and chi2rz + int chi2rzConv_; + // Fraction of total dphi and dz ranges to calculate v0 and v1 LUT for + int weightBinFraction_; + // Constant used in FW to prevent 32-bit int overflow + int dzTruncation_; + // Constant used in FW to prevent 32-bit int overflow + int dphiTruncation_; + // collection of unique formats + std::vector dataFormatsTQ_; + }; + +} // namespace trackerTFP + +EVENTSETUP_DATA_DEFAULT_RECORD(trackerTFP::TrackQuality, trackerTFP::DataFormatsRcd); + +#endif diff --git a/L1Trigger/TrackerTFP/interface/ZHoughTransform.h b/L1Trigger/TrackerTFP/interface/ZHoughTransform.h deleted file mode 100644 index 049c905f23812..0000000000000 --- a/L1Trigger/TrackerTFP/interface/ZHoughTransform.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef L1Trigger_TrackerTFP_ZHoughTransform_h -#define L1Trigger_TrackerTFP_ZHoughTransform_h - -#include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" - -#include -#include - -namespace trackerTFP { - - // Class to refine MHT track candidates in r-z - class ZHoughTransform { - public: - ZHoughTransform(const edm::ParameterSet& iConfig, - const tt::Setup* setup, - const DataFormats* dataFormats, - int region); - ~ZHoughTransform() {} - - // read in and organize input product (fill vector input_) - void consume(const tt::StreamsStub& streams); - // fill output products - void produce(tt::StreamsStub& accepted, tt::StreamsStub& lost); - - private: - // remove and return first element of deque, returns nullptr if empty - template - T* pop_front(std::deque& ts) const; - // perform finer pattern recognition per track - void fill(int channel, const std::deque& input, std::vector>& output); - // Static load balancing of inputs: mux 4 streams to 1 stream - void slb(std::vector>& inputs, std::deque& accepted, tt::StreamStub& lost) const; - // - void merge(std::deque& stubs, tt::StreamStub& stream) const; - - // true if truncation is enbaled - bool enableTruncation_; - // provides run-time constants - const tt::Setup* setup_; - // provides dataformats - const DataFormats* dataFormats_; - // processing region (0 - 8) - int region_; - // container of in- and output stubs - std::vector stubsZHT_; - // h/w liked organized pointer to input stubs - std::vector> input_; - // - int stage_; - }; - -} // namespace trackerTFP - -#endif diff --git a/L1Trigger/TrackerTFP/plugins/ProducerCTB.cc b/L1Trigger/TrackerTFP/plugins/ProducerCTB.cc new file mode 100644 index 0000000000000..1c2678c074c58 --- /dev/null +++ b/L1Trigger/TrackerTFP/plugins/ProducerCTB.cc @@ -0,0 +1,236 @@ +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Utilities/interface/EDPutToken.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/Common/interface/OrphanHandle.h" + +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackerTFP/interface/DataFormats.h" +#include "L1Trigger/TrackerTFP/interface/CleanTrackBuilder.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace trackerTFP { + + /*! \class trackerTFP::ProducerCTB + * \brief clean HT tracks and rrestructures them + * \author Thomas Schuh + * \date 2020, July + */ + class ProducerCTB : public edm::stream::EDProducer<> { + public: + explicit ProducerCTB(const edm::ParameterSet&); + ~ProducerCTB() override {} + + private: + void beginRun(const edm::Run&, const edm::EventSetup&) override; + void produce(edm::Event&, const edm::EventSetup&) override; + // ED input token of Stubs + edm::EDGetTokenT edGetToken_; + // ED output token for TTTracks + edm::EDPutTokenT edPutTokenTTTracks_; + // ED output token for stubs + edm::EDPutTokenT edPutTokenStubs_; + // ED output token for tracks + edm::EDPutTokenT edPutTokenTracks_; + // Setup token + edm::ESGetToken esGetTokenSetup_; + // DataFormats token + edm::ESGetToken esGetTokenDataFormats_; + // LayerEncoding token + edm::ESGetToken esGetTokenLayerEncoding_; + // + DataFormat cot_; + // number of inpit channel + int numChannelIn_; + // number of output channel + int numChannelOut_; + // number of processing regions + int numRegions_; + // number of kf layers + int numLayers_; + }; + + ProducerCTB::ProducerCTB(const edm::ParameterSet& iConfig) { + const std::string& label = iConfig.getParameter("InputLabelCTB"); + const std::string& branchStubs = iConfig.getParameter("BranchStubs"); + const std::string& branchTracks = iConfig.getParameter("BranchTracks"); + // book in- and output ED products + edGetToken_ = consumes(edm::InputTag(label, branchStubs)); + edPutTokenStubs_ = produces(branchStubs); + edPutTokenTTTracks_ = produces(branchTracks); + edPutTokenTracks_ = produces(branchTracks); + // book ES products + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + esGetTokenLayerEncoding_ = esConsumes(); + } + + void ProducerCTB::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) { + const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_); + const DataFormats* dataFormats = &iSetup.getData(esGetTokenDataFormats_); + numChannelIn_ = dataFormats->numChannel(Process::ht); + numChannelOut_ = dataFormats->numChannel(Process::ctb); + numRegions_ = setup->numRegions(); + numLayers_ = setup->numLayers(); + // create data format for cot(theta) + const double baseZ = dataFormats->base(Variable::z, Process::ctb); + const double baseR = dataFormats->base(Variable::r, Process::ctb); + const double range = dataFormats->range(Variable::cot, Process::kf); + const int baseShift = std::ceil(std::log2(range / baseZ * baseR / setup->ctbNumBinsCot())); + const int width = std::ceil(std::log2(setup->ctbNumBinsCot())); + const double base = baseZ / baseR * pow(2, baseShift); + cot_ = DataFormat(true, width, base, range); + } + + void ProducerCTB::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_); + const DataFormats* dataFormats = &iSetup.getData(esGetTokenDataFormats_); + const LayerEncoding* layerEncoding = &iSetup.getData(esGetTokenLayerEncoding_); + // empty output products + tt::StreamsTrack acceptedTracks(numRegions_ * numChannelOut_); + tt::StreamsStub acceptedStubs(numRegions_ * numChannelOut_ * numLayers_); + std::vector>> streamsTracks(numRegions_, + std::vector>(numChannelOut_)); + std::vector>>> streamsStubs( + numRegions_, + std::vector>>(numChannelOut_, std::vector>(numLayers_))); + // read input Product and produce output product + const tt::StreamsStub& streamsStub = iEvent.get(edGetToken_); + // count stubs + int nStubsHT(0); + auto validFrame = [](int sum, const tt::FrameStub& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); }; + for (const tt::StreamStub& stream : streamsStub) + nStubsHT += std::accumulate(stream.begin(), stream.end(), 0, validFrame); + // create input objects and count tracks + std::vector stubsHT; + stubsHT.reserve(nStubsHT); + // count stubs + int nTracksHT(0); + for (const tt::StreamStub& stream : streamsStub) { + std::pair trackId({setup->htNumBinsPhiT(), setup->gpNumBinsZT()}); + for (const tt::FrameStub& frame : stream) { + if (frame.first.isNull()) + continue; + stubsHT.emplace_back(frame, dataFormats); + StubHT* stub = &stubsHT.back(); + if (trackId.first != stub->phiT() || trackId.second != stub->zT()) { + nTracksHT++; + trackId = {stub->phiT(), stub->zT()}; + } + } + } + // object to clean and restructure tracks + std::vector stubsCTB; + stubsCTB.reserve(nStubsHT); + std::vector tracksCTB; + tracksCTB.reserve(nTracksHT); + CleanTrackBuilder ctb(setup, dataFormats, layerEncoding, cot_, stubsCTB, tracksCTB); + int iStub(0); + for (int region = 0; region < numRegions_; region++) { + const int offsetIn = region * numChannelIn_; + const int offsetOut = region * numChannelOut_; + // read h/w liked organized pointer to input data + std::vector> streamsIn(numChannelIn_); + for (int channelIn = 0; channelIn < numChannelIn_; channelIn++) { + const tt::StreamStub& channelStubs = streamsStub[offsetIn + channelIn]; + std::vector& stream = streamsIn[channelIn]; + stream.reserve(channelStubs.size()); + for (const tt::FrameStub& frame : channelStubs) + stream.push_back(frame.first.isNull() ? nullptr : &stubsHT[iStub++]); + } + // empty h/w liked organized pointer to output data + std::vector>& regionTracks = streamsTracks[region]; + std::vector>>& regionStubs = streamsStubs[region]; + // fill output data + ctb.produce(streamsIn, regionTracks, regionStubs); + // fill ed stubs + for (int channelOut = 0; channelOut < numChannelOut_; channelOut++) { + const int offset = (offsetOut + channelOut) * numLayers_; + const std::vector>& channelStubs = regionStubs[channelOut]; + for (int layer = 0; layer < numLayers_; layer++) { + tt::StreamStub& accepted = acceptedStubs[offset + layer]; + const std::deque& layerStubs = channelStubs[layer]; + accepted.reserve(layerStubs.size()); + for (StubCTB* stub : layerStubs) + accepted.emplace_back(stub ? stub->frame() : tt::FrameStub()); + } + } + } + // store TTTracks + int nTracks(0); + auto valid = [](int sum, TrackCTB* track) { return sum + (track ? 1 : 0); }; + for (const std::vector>& region : streamsTracks) + for (const std::deque& channel : region) + nTracks += std::accumulate(channel.begin(), channel.end(), 0, valid); + tt::TTTracks ttTracks; + ttTracks.reserve(nTracks); + for (int region = 0; region < numRegions_; region++) { + const std::vector>& regionTracks = streamsTracks[region]; + const std::vector>>& regionStubs = streamsStubs[region]; + for (int channelOut = 0; channelOut < numChannelOut_; channelOut++) { + const std::deque& channelTracks = regionTracks[channelOut]; + const std::vector>& channelStubs = regionStubs[channelOut]; + for (int frame = 0; frame < static_cast(channelTracks.size()); frame++) { + TrackCTB* track = channelTracks[frame]; + if (!track) + continue; + const auto begin = std::next(channelTracks.begin(), frame); + const auto end = std::find_if(begin + 1, channelTracks.end(), [](TrackCTB* track) { return track; }); + const int size = std::distance(begin, end); + std::vector> stubs(numLayers_); + for (int layer = 0; layer < numLayers_; layer++) { + const std::deque& layerStubs = channelStubs[layer]; + std::vector& layerTrack = stubs[layer]; + layerTrack.reserve(size); + for (int s = 0; s < size; s++) { + StubCTB* stub = layerStubs[frame + s]; + if (stub) + layerTrack.push_back(stub); + } + } + ctb.put(track, stubs, region, ttTracks); + } + } + } + const edm::OrphanHandle handle = iEvent.emplace(edPutTokenTTTracks_, std::move(ttTracks)); + // add TTTrackRefs + int iTrk(0); + int iChan(0); + for (const std::vector>& region : streamsTracks) { + for (const std::deque& stream : region) { + tt::StreamTrack& streamTrack = acceptedTracks[iChan++]; + for (TrackCTB* track : stream) { + if (!track) { + streamTrack.emplace_back(tt::FrameTrack()); + continue; + } + tt::FrameTrack frame = track->frame(); + frame.first = TTTrackRef(handle, iTrk++); + streamTrack.emplace_back(frame); + } + } + } + // store tracks + iEvent.emplace(edPutTokenTracks_, std::move(acceptedTracks)); + // store stubs + iEvent.emplace(edPutTokenStubs_, std::move(acceptedStubs)); + } + +} // namespace trackerTFP + +DEFINE_FWK_MODULE(trackerTFP::ProducerCTB); diff --git a/L1Trigger/TrackerTFP/plugins/ProducerDR.cc b/L1Trigger/TrackerTFP/plugins/ProducerDR.cc new file mode 100644 index 0000000000000..dfed0aced2c2f --- /dev/null +++ b/L1Trigger/TrackerTFP/plugins/ProducerDR.cc @@ -0,0 +1,183 @@ +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Utilities/interface/EDPutToken.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "DataFormats/Common/interface/Handle.h" + +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackerTFP/interface/DataFormats.h" +#include "L1Trigger/TrackerTFP/interface/DuplicateRemoval.h" + +#include +#include + +namespace trackerTFP { + + /*! \class trackerTFP::ProducerDR + * \brief L1TrackTrigger duplicate removal emulator + * \author Thomas Schuh + * \date 2023, Feb + */ + class ProducerDR : public edm::stream::EDProducer<> { + public: + explicit ProducerDR(const edm::ParameterSet&); + ~ProducerDR() override {} + + private: + void beginRun(const edm::Run&, const edm::EventSetup&) override; + void produce(edm::Event&, const edm::EventSetup&) override; + // ED input token of sf stubs and tracks + edm::EDGetTokenT edGetTokenStubs_; + edm::EDGetTokenT edGetTokenTracks_; + // ED output token for accepted stubs and tracks + edm::EDPutTokenT edPutTokenStubs_; + edm::EDPutTokenT edPutTokenTracks_; + // Setup token + edm::ESGetToken esGetTokenSetup_; + // DataFormats token + edm::ESGetToken esGetTokenDataFormats_; + // number of input channel + int numChannelIn_; + // number of output channel + int numChannelOut_; + // number ofprocessing regions + int numRegions_; + // number of kf layers + int numLayers_; + }; + + ProducerDR::ProducerDR(const edm::ParameterSet& iConfig) { + const std::string& label = iConfig.getParameter("InputLabelDR"); + const std::string& branchStubs = iConfig.getParameter("BranchStubs"); + const std::string& branchTracks = iConfig.getParameter("BranchTracks"); + // book in- and output ED products + edGetTokenStubs_ = consumes(edm::InputTag(label, branchStubs)); + edGetTokenTracks_ = consumes(edm::InputTag(label, branchTracks)); + edPutTokenStubs_ = produces(branchStubs); + edPutTokenTracks_ = produces(branchTracks); + // book ES products + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + } + + void ProducerDR::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) { + // helper class to store configurations + const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_); + numRegions_ = setup->numRegions(); + numLayers_ = setup->numLayers(); + // helper class to extract structured data from tt::Frames + const DataFormats* dataFormats = &iSetup.getData(esGetTokenDataFormats_); + numChannelIn_ = dataFormats->numChannel(Process::kf); + numChannelOut_ = dataFormats->numChannel(Process::dr); + } + + void ProducerDR::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_); + const DataFormats* dataFormats = &iSetup.getData(esGetTokenDataFormats_); + // empty DR products + tt::StreamsStub acceptedStubs(numRegions_ * numChannelOut_ * numLayers_); + tt::StreamsTrack acceptedTracks(numRegions_ * numChannelOut_); + // read in KF Product and produce DR product + const tt::StreamsStub& allStubs = iEvent.get(edGetTokenStubs_); + const tt::StreamsTrack& allTracks = iEvent.get(edGetTokenTracks_); + // helper + auto validFrameT = [](int sum, const tt::FrameTrack& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); }; + auto validFrameS = [](int sum, const tt::FrameStub& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); }; + auto putT = [](const std::vector& objects, tt::StreamTrack& stream) { + auto toFrame = [](TrackDR* object) { return object ? object->frame() : tt::FrameTrack(); }; + stream.reserve(objects.size()); + std::transform(objects.begin(), objects.end(), std::back_inserter(stream), toFrame); + }; + auto putS = [](const std::vector& objects, tt::StreamStub& stream) { + auto toFrame = [](StubDR* object) { return object ? object->frame() : tt::FrameStub(); }; + stream.reserve(objects.size()); + std::transform(objects.begin(), objects.end(), std::back_inserter(stream), toFrame); + }; + for (int region = 0; region < numRegions_; region++) { + const int offsetIn = region * numChannelIn_; + const int offsetOut = region * numChannelOut_; + // count input objects + int nTracks(0); + int nStubs(0); + for (int channelIn = 0; channelIn < numChannelIn_; channelIn++) { + const int index = offsetIn + channelIn; + const int offset = index * numLayers_; + const tt::StreamTrack& tracks = allTracks[index]; + nTracks += std::accumulate(tracks.begin(), tracks.end(), 0, validFrameT); + for (int layer = 0; layer < numLayers_; layer++) { + const tt::StreamStub& stubs = allStubs[offset + layer]; + nStubs += std::accumulate(stubs.begin(), stubs.end(), 0, validFrameS); + } + } + // storage of input data + std::vector tracksKF; + tracksKF.reserve(nTracks); + std::vector stubsKF; + stubsKF.reserve(nStubs); + // h/w liked organized pointer to input data + std::vector> regionTracks(numChannelIn_); + std::vector> regionStubs(numChannelIn_ * numLayers_); + // read input data + for (int channelIn = 0; channelIn < numChannelIn_; channelIn++) { + const int index = offsetIn + channelIn; + const int offsetAll = index * numLayers_; + const int offsetRegion = channelIn * numLayers_; + const tt::StreamTrack& streamTrack = allTracks[index]; + std::vector& tracks = regionTracks[channelIn]; + tracks.reserve(streamTrack.size()); + for (const tt::FrameTrack& frame : streamTrack) { + TrackKF* track = nullptr; + if (frame.first.isNonnull()) { + tracksKF.emplace_back(frame, dataFormats); + track = &tracksKF.back(); + } + tracks.push_back(track); + } + for (int layer = 0; layer < numLayers_; layer++) { + for (const tt::FrameStub& frame : allStubs[offsetAll + layer]) { + StubKF* stub = nullptr; + if (frame.first.isNonnull()) { + stubsKF.emplace_back(frame, dataFormats); + stub = &stubsKF.back(); + } + regionStubs[offsetRegion + layer].push_back(stub); + } + } + } + // empty storage of output data + std::vector tracksDR; + tracksDR.reserve(nTracks); + std::vector stubsDR; + stubsDR.reserve(nStubs); + // object to remove duplicates in a processing region + DuplicateRemoval dr(setup, dataFormats, tracksDR, stubsDR); + // empty h/w liked organized pointer to output data + std::vector> streamsTrack(numChannelOut_); + std::vector> streamsStub(numChannelOut_ * numLayers_); + // fill output data + dr.produce(regionTracks, regionStubs, streamsTrack, streamsStub); + // convert data to ed products + for (int channelOut = 0; channelOut < numChannelOut_; channelOut++) { + const int index = offsetOut + channelOut; + const int offsetRegion = channelOut * numLayers_; + const int offsetAll = index * numLayers_; + putT(streamsTrack[channelOut], acceptedTracks[index]); + for (int layer = 0; layer < numLayers_; layer++) + putS(streamsStub[offsetRegion + layer], acceptedStubs[offsetAll + layer]); + } + } + // store products + iEvent.emplace(edPutTokenStubs_, std::move(acceptedStubs)); + iEvent.emplace(edPutTokenTracks_, std::move(acceptedTracks)); + } + +} // namespace trackerTFP + +DEFINE_FWK_MODULE(trackerTFP::ProducerDR); diff --git a/L1Trigger/TrackerTFP/plugins/ProducerES.cc b/L1Trigger/TrackerTFP/plugins/ProducerDataFormats.cc similarity index 50% rename from L1Trigger/TrackerTFP/plugins/ProducerES.cc rename to L1Trigger/TrackerTFP/plugins/ProducerDataFormats.cc index 4e308c80851ad..6e6a0ac46d5b1 100644 --- a/L1Trigger/TrackerTFP/plugins/ProducerES.cc +++ b/L1Trigger/TrackerTFP/plugins/ProducerDataFormats.cc @@ -8,38 +8,33 @@ #include -using namespace std; -using namespace edm; -using namespace tt; - namespace trackerTFP { - /*! \class trackerTFP::ProducerES + /*! \class trackerTFP::ProducerDataFormats * \brief Class to produce setup of Track Trigger emulator data formats * \author Thomas Schuh * \date 2020, June */ - class ProducerES : public ESProducer { + class ProducerDataFormats : public edm::ESProducer { public: - ProducerES(const ParameterSet& iConfig); - ~ProducerES() override {} - unique_ptr produce(const DataFormatsRcd& rcd); + ProducerDataFormats(const edm::ParameterSet& iConfig); + ~ProducerDataFormats() override {} + std::unique_ptr produce(const DataFormatsRcd& rcd); private: - const ParameterSet iConfig_; - ESGetToken esGetToken_; + edm::ESGetToken esGetToken_; }; - ProducerES::ProducerES(const ParameterSet& iConfig) : iConfig_(iConfig) { + ProducerDataFormats::ProducerDataFormats(const edm::ParameterSet& iConfig) { auto cc = setWhatProduced(this); esGetToken_ = cc.consumes(); } - unique_ptr ProducerES::produce(const DataFormatsRcd& rcd) { - const Setup* setup = &rcd.get(esGetToken_); - return make_unique(iConfig_, setup); + std::unique_ptr ProducerDataFormats::produce(const DataFormatsRcd& rcd) { + const tt::Setup* setup = &rcd.get(esGetToken_); + return std::make_unique(setup); } } // namespace trackerTFP -DEFINE_FWK_EVENTSETUP_MODULE(trackerTFP::ProducerES); +DEFINE_FWK_EVENTSETUP_MODULE(trackerTFP::ProducerDataFormats); diff --git a/L1Trigger/TrackerTFP/plugins/ProducerDemonstrator.cc b/L1Trigger/TrackerTFP/plugins/ProducerDemonstrator.cc index a735aa202d281..158da1446d154 100644 --- a/L1Trigger/TrackerTFP/plugins/ProducerDemonstrator.cc +++ b/L1Trigger/TrackerTFP/plugins/ProducerDemonstrator.cc @@ -4,38 +4,41 @@ #include "FWCore/Utilities/interface/ESGetToken.h" #include "L1Trigger/TrackerTFP/interface/Demonstrator.h" +#include +#include #include -using namespace std; -using namespace edm; -using namespace tt; - namespace trackerTFP { /*! \class trackerTFP::ProducerDemonstrator - * \brief Class to demontrate correctness of track trigger emulators + * \brief ESProducer providing the algorithm to run input data through modelsim + * and to compares results with expected output data * \author Thomas Schuh * \date 2020, Nov */ - class ProducerDemonstrator : public ESProducer { + class ProducerDemonstrator : public edm::ESProducer { public: - ProducerDemonstrator(const ParameterSet& iConfig); + ProducerDemonstrator(const edm::ParameterSet& iConfig); ~ProducerDemonstrator() override {} - unique_ptr produce(const DemonstratorRcd& rcd); + std::unique_ptr produce(const tt::SetupRcd& rcd); private: - const ParameterSet iConfig_; - ESGetToken esGetToken_; + Demonstrator::Config iConfig_; + edm::ESGetToken esGetToken_; }; - ProducerDemonstrator::ProducerDemonstrator(const ParameterSet& iConfig) : iConfig_(iConfig) { + ProducerDemonstrator::ProducerDemonstrator(const edm::ParameterSet& iConfig) { auto cc = setWhatProduced(this); esGetToken_ = cc.consumes(); + iConfig_.dirIPBB_ = iConfig.getParameter("DirIPBB"); + iConfig_.runTime_ = iConfig.getParameter("RunTime"); + iConfig_.linkMappingIn_ = iConfig.getParameter>("LinkMappingIn"); + iConfig_.linkMappingOut_ = iConfig.getParameter>("LinkMappingOut"); } - unique_ptr ProducerDemonstrator::produce(const DemonstratorRcd& rcd) { - const Setup* setup = &rcd.get(esGetToken_); - return make_unique(iConfig_, setup); + std::unique_ptr ProducerDemonstrator::produce(const tt::SetupRcd& rcd) { + const tt::Setup* setup = &rcd.get(esGetToken_); + return std::make_unique(iConfig_, setup); } } // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/plugins/ProducerFormatsKF.cc b/L1Trigger/TrackerTFP/plugins/ProducerFormatsKF.cc deleted file mode 100644 index 569d0516aab4d..0000000000000 --- a/L1Trigger/TrackerTFP/plugins/ProducerFormatsKF.cc +++ /dev/null @@ -1,45 +0,0 @@ -#include "FWCore/Framework/interface/ESProducer.h" -#include "FWCore/Framework/interface/ESHandle.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/Utilities/interface/ESGetToken.h" -#include "FWCore/Utilities/interface/ESInputTag.h" -#include "DataFormats/Provenance/interface/ParameterSetID.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" -#include "L1Trigger/TrackerTFP/interface/KalmanFilterFormats.h" - -#include - -using namespace std; -using namespace edm; - -namespace trackerTFP { - - /*! \class trackerTFP::ProducerFormatsKF - * \brief Class to produce setup of Kalman Filter emulator data formats - * \author Thomas Schuh - * \date 2020, July - */ - class ProducerFormatsKF : public ESProducer { - public: - ProducerFormatsKF(const ParameterSet& iConfig); - ~ProducerFormatsKF() override {} - unique_ptr produce(const KalmanFilterFormatsRcd& rcd); - - private: - const ParameterSet iConfig_; - ESGetToken esGetToken_; - }; - - ProducerFormatsKF::ProducerFormatsKF(const ParameterSet& iConfig) : iConfig_(iConfig) { - auto cc = setWhatProduced(this); - esGetToken_ = cc.consumes(); - } - - unique_ptr ProducerFormatsKF::produce(const KalmanFilterFormatsRcd& rcd) { - const DataFormats* dataFormats = &rcd.get(esGetToken_); - return make_unique(iConfig_, dataFormats); - } - -} // namespace trackerTFP - -DEFINE_FWK_EVENTSETUP_MODULE(trackerTFP::ProducerFormatsKF); diff --git a/L1Trigger/TrackerTFP/plugins/ProducerGP.cc b/L1Trigger/TrackerTFP/plugins/ProducerGP.cc index b9781b8186411..aff0657ab92a4 100644 --- a/L1Trigger/TrackerTFP/plugins/ProducerGP.cc +++ b/L1Trigger/TrackerTFP/plugins/ProducerGP.cc @@ -10,18 +10,18 @@ #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "DataFormats/Common/interface/Handle.h" -#include "DataFormats/L1TrackTrigger/interface/TTDTC.h" #include "DataFormats/L1TrackTrigger/interface/TTTypes.h" #include "L1Trigger/TrackTrigger/interface/Setup.h" #include "L1Trigger/TrackerTFP/interface/DataFormats.h" +#include "L1Trigger/TrackerTFP/interface/LayerEncoding.h" #include "L1Trigger/TrackerTFP/interface/GeometricProcessor.h" -#include #include - -using namespace std; -using namespace edm; -using namespace tt; +#include +#include +#include +#include +#include namespace trackerTFP { @@ -30,78 +30,123 @@ namespace trackerTFP { * \author Thomas Schuh * \date 2020, March */ - class ProducerGP : public stream::EDProducer<> { + class ProducerGP : public edm::stream::EDProducer<> { public: - explicit ProducerGP(const ParameterSet&); + explicit ProducerGP(const edm::ParameterSet&); ~ProducerGP() override {} private: - void beginRun(const Run&, const EventSetup&) override; - void produce(Event&, const EventSetup&) override; - virtual void endJob() {} - - // ED input token of DTC stubs - EDGetTokenT edGetToken_; - // ED output token for accepted stubs - EDPutTokenT edPutTokenAccepted_; - // ED output token for lost stubs - EDPutTokenT edPutTokenLost_; + void beginRun(const edm::Run&, const edm::EventSetup&) override; + void produce(edm::Event&, const edm::EventSetup&) override; + // ED input token of pp objects + edm::EDGetTokenT edGetToken_; + // ED output token for accepted objects + edm::EDPutTokenT edPutToken_; // Setup token - ESGetToken esGetTokenSetup_; + edm::ESGetToken esGetTokenSetup_; // DataFormats token - ESGetToken esGetTokenDataFormats_; - // configuration - ParameterSet iConfig_; - // helper classe to store configurations - const Setup* setup_ = nullptr; - // helper class to extract structured data from tt::Frames - const DataFormats* dataFormats_ = nullptr; + edm::ESGetToken esGetTokenDataFormats_; + // LayerEncoding token + edm::ESGetToken esGetTokenLayerEncoding_; + // number of input channel + int numChannelIn_; + // number of output channel + int numChannelOut_; + // number of processing regions + int numRegions_; }; - ProducerGP::ProducerGP(const ParameterSet& iConfig) : iConfig_(iConfig) { - const string& label = iConfig.getParameter("LabelDTC"); - const string& branchAccepted = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchLost = iConfig.getParameter("BranchLostStubs"); + ProducerGP::ProducerGP(const edm::ParameterSet& iConfig) { + const std::string& label = iConfig.getParameter("InputLabelGP"); + const std::string& branch = iConfig.getParameter("BranchStubs"); // book in- and output ED products - edGetToken_ = consumes(InputTag(label, branchAccepted)); - edPutTokenAccepted_ = produces(branchAccepted); - edPutTokenLost_ = produces(branchLost); + edGetToken_ = consumes(edm::InputTag(label, branch)); + edPutToken_ = produces(branch); // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + esGetTokenLayerEncoding_ = esConsumes(); } - void ProducerGP::beginRun(const Run& iRun, const EventSetup& iSetup) { - setup_ = &iSetup.getData(esGetTokenSetup_); - if (!setup_->configurationSupported()) - return; - // check process history if desired - if (iConfig_.getParameter("CheckHistory")) - setup_->checkHistory(iRun.processHistory()); - dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); + void ProducerGP::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) { + // helper classe to store configurations + const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_); + numRegions_ = setup->numRegions(); + // helper class to extract structured data from tt::Frames + const DataFormats* dataFormats = &iSetup.getData(esGetTokenDataFormats_); + numChannelIn_ = dataFormats->numChannel(Process::pp); + numChannelOut_ = dataFormats->numChannel(Process::gp); } - void ProducerGP::produce(Event& iEvent, const EventSetup& iSetup) { + void ProducerGP::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + // helper classe to store configurations + const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_); + // helper class to extract structured data from tt::Frames + const DataFormats* dataFormats = &iSetup.getData(esGetTokenDataFormats_); + // helper class to encode layer + const LayerEncoding* layerEncoding = &iSetup.getData(esGetTokenLayerEncoding_); // empty GP products - StreamsStub accepted(dataFormats_->numStreams(Process::gp)); - StreamsStub lost(dataFormats_->numStreams(Process::gp)); + tt::StreamsStub accepted(numRegions_ * numChannelOut_); // read in DTC Product and produce TFP product - if (setup_->configurationSupported()) { - Handle handle; - iEvent.getByToken(edGetToken_, handle); - const TTDTC& ttDTC = *handle.product(); - for (int region = 0; region < setup_->numRegions(); region++) { - // object to route Stubs of one region to one stream per sector - GeometricProcessor gp(iConfig_, setup_, dataFormats_, region); - // read in and organize input product - gp.consume(ttDTC); - // fill output products - gp.produce(accepted, lost); + const tt::StreamsStub& streamsStub = iEvent.get(edGetToken_); + // helper + auto validFrame = [](int sum, const tt::FrameStub& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); }; + auto nSectors = [](int sum, const StubPP& object) { + const int nPhiT = object.phiTMax() - object.phiTMin() + 1; + const int nZT = object.zTMax() - object.zTMin() + 1; + return sum + nPhiT * nZT; + }; + auto toFrame = [](StubGP* object) { return object ? object->frame() : tt::FrameStub(); }; + // produce GP product per region + for (int region = 0; region < numRegions_; region++) { + const int offsetIn = region * numChannelIn_; + const int offsetOut = region * numChannelOut_; + // count input objects + int nStubsPP(0); + for (int channelIn = 0; channelIn < numChannelIn_; channelIn++) { + const tt::StreamStub& stream = streamsStub[offsetIn + channelIn]; + nStubsPP += std::accumulate(stream.begin(), stream.end(), 0, validFrame); + } + // storage of input data + std::vector stubsPP; + stubsPP.reserve(nStubsPP); + // h/w liked organized pointer to input data + std::vector> streamsIn(numChannelIn_); + // read input data + for (int channelIn = 0; channelIn < numChannelIn_; channelIn++) { + const tt::StreamStub& streamStub = streamsStub[offsetIn + channelIn]; + std::vector& stream = streamsIn[channelIn]; + stream.reserve(streamStub.size()); + for (const tt::FrameStub& frame : streamStub) { + StubPP* stubPP = nullptr; + if (frame.first.isNonnull()) { + stubsPP.emplace_back(frame, dataFormats); + stubPP = &stubsPP.back(); + } + stream.push_back(stubPP); + } + } + // predict upper limit of GP stubs + const int nStubsGP = std::accumulate(stubsPP.begin(), stubsPP.end(), 0, nSectors); + // container of GP stubs + std::vector stubsGP; + stubsGP.reserve(nStubsGP); + // object to route Stubs of one region to one stream per sector + GeometricProcessor gp(setup, dataFormats, layerEncoding, stubsGP); + // empty h/w liked organized pointer to output data + std::vector> streamsOut(numChannelOut_); + // fill output data + gp.produce(streamsIn, streamsOut); + // convert data to ed products + for (int channelOut = 0; channelOut < numChannelOut_; channelOut++) { + const std::deque& objects = streamsOut[channelOut]; + tt::StreamStub& stream = accepted[offsetOut + channelOut]; + stream.reserve(objects.size()); + std::transform(objects.begin(), objects.end(), std::back_inserter(stream), toFrame); } } // store products - iEvent.emplace(edPutTokenAccepted_, std::move(accepted)); - iEvent.emplace(edPutTokenLost_, std::move(lost)); + iEvent.emplace(edPutToken_, std::move(accepted)); } } // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/plugins/ProducerHT.cc b/L1Trigger/TrackerTFP/plugins/ProducerHT.cc index 15a9701b7ac14..f061c6c90e64f 100644 --- a/L1Trigger/TrackerTFP/plugins/ProducerHT.cc +++ b/L1Trigger/TrackerTFP/plugins/ProducerHT.cc @@ -13,14 +13,15 @@ #include "DataFormats/L1TrackTrigger/interface/TTTypes.h" #include "L1Trigger/TrackTrigger/interface/Setup.h" #include "L1Trigger/TrackerTFP/interface/DataFormats.h" +#include "L1Trigger/TrackerTFP/interface/LayerEncoding.h" #include "L1Trigger/TrackerTFP/interface/HoughTransform.h" #include +#include +#include #include - -using namespace std; -using namespace edm; -using namespace tt; +#include +#include namespace trackerTFP { @@ -29,80 +30,112 @@ namespace trackerTFP { * \author Thomas Schuh * \date 2020, March */ - class ProducerHT : public stream::EDProducer<> { + class ProducerHT : public edm::stream::EDProducer<> { public: - explicit ProducerHT(const ParameterSet&); + explicit ProducerHT(const edm::ParameterSet&); ~ProducerHT() override {} private: - void beginRun(const Run&, const EventSetup&) override; - void produce(Event&, const EventSetup&) override; - virtual void endJob() {} - + void beginRun(const edm::Run&, const edm::EventSetup&) override; + void produce(edm::Event&, const edm::EventSetup&) override; // ED input token of gp stubs - EDGetTokenT edGetToken_; + edm::EDGetTokenT edGetToken_; // ED output token for accepted stubs - EDPutTokenT edPutTokenAccepted_; - // ED output token for lost stubs - EDPutTokenT edPutTokenLost_; + edm::EDPutTokenT edPutToken_; // Setup token - ESGetToken esGetTokenSetup_; + edm::ESGetToken esGetTokenSetup_; // DataFormats token - ESGetToken esGetTokenDataFormats_; - // configuration - ParameterSet iConfig_; - // helper class to store configurations - const Setup* setup_ = nullptr; - // helper class to extract structured data from tt::Frames - const DataFormats* dataFormats_ = nullptr; + edm::ESGetToken esGetTokenDataFormats_; + // LayerEncoding token + edm::ESGetToken esGetTokenLayerEncoding_; + // number of input channel + int numChannelIn_; + // number of output channel + int numChannelOut_; + // number of processing regions + int numRegions_; }; - ProducerHT::ProducerHT(const ParameterSet& iConfig) : iConfig_(iConfig) { - const string& label = iConfig.getParameter("LabelGP"); - const string& branchAccepted = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchLost = iConfig.getParameter("BranchLostStubs"); + ProducerHT::ProducerHT(const edm::ParameterSet& iConfig) { + const std::string& label = iConfig.getParameter("InputLabelHT"); + const std::string& branch = iConfig.getParameter("BranchStubs"); // book in- and output ED products - edGetToken_ = consumes(InputTag(label, branchAccepted)); - edPutTokenAccepted_ = produces(branchAccepted); - edPutTokenLost_ = produces(branchLost); + edGetToken_ = consumes(edm::InputTag(label, branch)); + edPutToken_ = produces(branch); // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + esGetTokenLayerEncoding_ = esConsumes(); } - void ProducerHT::beginRun(const Run& iRun, const EventSetup& iSetup) { + void ProducerHT::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) { // helper class to store configurations - setup_ = &iSetup.getData(esGetTokenSetup_); - if (!setup_->configurationSupported()) - return; - // check process history if desired - if (iConfig_.getParameter("CheckHistory")) - setup_->checkHistory(iRun.processHistory()); + const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_); + numRegions_ = setup->numRegions(); // helper class to extract structured data from tt::Frames - dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); + const DataFormats* dataFormats = &iSetup.getData(esGetTokenDataFormats_); + numChannelIn_ = dataFormats->numChannel(Process::gp); + numChannelOut_ = dataFormats->numChannel(Process::ht); } - void ProducerHT::produce(Event& iEvent, const EventSetup& iSetup) { + void ProducerHT::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_); + const DataFormats* dataFormats = &iSetup.getData(esGetTokenDataFormats_); + const LayerEncoding* layerEncoding = &iSetup.getData(esGetTokenLayerEncoding_); // empty HT products - StreamsStub accepted(dataFormats_->numStreams(Process::ht)); - StreamsStub lost(dataFormats_->numStreams(Process::ht)); + tt::StreamsStub accepted(numRegions_ * numChannelOut_); // read in DTC Product and produce TFP product - if (setup_->configurationSupported()) { - Handle handle; - iEvent.getByToken(edGetToken_, handle); - const StreamsStub& streams = *handle.product(); - for (int region = 0; region < setup_->numRegions(); region++) { - // object to find initial rough candidates in r-phi in a region - HoughTransform ht(iConfig_, setup_, dataFormats_, region); - // read in and organize input product - ht.consume(streams); - // fill output products - ht.produce(accepted, lost); + const tt::StreamsStub& streamsStub = iEvent.get(edGetToken_); + // helper + auto validFrame = [](int sum, const tt::FrameStub& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); }; + auto toFrame = [](StubHT* object) { return object ? object->frame() : tt::FrameStub(); }; + // produce HT output per region + for (int region = 0; region < numRegions_; region++) { + const int offsetIn = region * numChannelIn_; + const int offsetOut = region * numChannelOut_; + // count input objects + int nStubsGP(0); + for (int channelIn = 0; channelIn < numChannelIn_; channelIn++) { + const tt::StreamStub& stream = streamsStub[offsetIn + channelIn]; + nStubsGP += std::accumulate(stream.begin(), stream.end(), 0, validFrame); + } + // storage of input data + std::vector stubsGP; + stubsGP.reserve(nStubsGP); + // h/w liked organized pointer to input data + std::vector> streamsIn(numChannelIn_); + // read input data + for (int channelIn = 0; channelIn < numChannelIn_; channelIn++) { + const tt::StreamStub& streamStub = streamsStub[offsetIn + channelIn]; + std::vector& stream = streamsIn[channelIn]; + stream.reserve(streamStub.size()); + for (const tt::FrameStub& frame : streamStub) { + StubGP* stub = nullptr; + if (frame.first.isNonnull()) { + stubsGP.emplace_back(frame, dataFormats); + stub = &stubsGP.back(); + } + stream.push_back(stub); + } + } + // container for output stubs + std::vector stubsHT; + // object to find initial rough candidates in r-phi in a region + HoughTransform ht(setup, dataFormats, layerEncoding, stubsHT); + // empty h/w liked organized pointer to output data + std::vector> streamsOut(numChannelOut_); + // fill output data + ht.produce(streamsIn, streamsOut); + // convert data to ed products + for (int channelOut = 0; channelOut < numChannelOut_; channelOut++) { + const std::deque& objects = streamsOut[channelOut]; + tt::StreamStub& stream = accepted[offsetOut + channelOut]; + stream.reserve(objects.size()); + std::transform(objects.begin(), objects.end(), std::back_inserter(stream), toFrame); } } // store products - iEvent.emplace(edPutTokenAccepted_, std::move(accepted)); - iEvent.emplace(edPutTokenLost_, std::move(lost)); + iEvent.emplace(edPutToken_, std::move(accepted)); } } // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/plugins/ProducerKF.cc b/L1Trigger/TrackerTFP/plugins/ProducerKF.cc index ce123005215ae..7a6730fd4b445 100644 --- a/L1Trigger/TrackerTFP/plugins/ProducerKF.cc +++ b/L1Trigger/TrackerTFP/plugins/ProducerKF.cc @@ -18,10 +18,8 @@ #include "L1Trigger/TrackerTFP/interface/KalmanFilter.h" #include - -using namespace std; -using namespace edm; -using namespace tt; +#include +#include namespace trackerTFP { @@ -30,117 +28,236 @@ namespace trackerTFP { * \author Thomas Schuh * \date 2020, July */ - class ProducerKF : public stream::EDProducer<> { + class ProducerKF : public edm::stream::EDProducer<> { public: - explicit ProducerKF(const ParameterSet&); + explicit ProducerKF(const edm::ParameterSet&); ~ProducerKF() override {} private: - void beginRun(const Run&, const EventSetup&) override; - void produce(Event&, const EventSetup&) override; + typedef State::Stub Stub; + void beginRun(const edm::Run&, const edm::EventSetup&) override; + void produce(edm::Event&, const edm::EventSetup&) override; void endStream() override { + std::stringstream ss; if (printDebug_) - kalmanFilterFormats_->endJob(); + kalmanFilterFormats_.endJob(ss); + edm::LogPrint(moduleDescription().moduleName()) << ss.str(); } - // ED input token of sf stubs and tracks - EDGetTokenT edGetTokenStubs_; - EDGetTokenT edGetTokenTracks_; + edm::EDGetTokenT edGetTokenStubs_; + edm::EDGetTokenT edGetTokenTracks_; // ED output token for accepted stubs and tracks - EDPutTokenT edPutTokenAcceptedStubs_; - EDPutTokenT edPutTokenAcceptedTracks_; - // ED output token for lost stubs and tracks - EDPutTokenT edPutTokenLostStubs_; - EDPutTokenT edPutTokenLostTracks_; + edm::EDPutTokenT edPutTokenStubs_; + edm::EDPutTokenT edPutTokenTracks_; // ED output token for number of accepted and lost States - EDPutTokenT edPutTokenNumAcceptedStates_; - EDPutTokenT edPutTokenNumLostStates_; + edm::EDPutTokenT edPutTokenNumStatesAccepted_; + edm::EDPutTokenT edPutTokenNumStatesTruncated_; + // ED output token for chi2s in r-phi and r-z plane + edm::EDPutTokenT>> edPutTokenChi2s_; // Setup token - ESGetToken esGetTokenSetup_; + edm::ESGetToken esGetTokenSetup_; // DataFormats token - ESGetToken esGetTokenDataFormats_; - // KalmanFilterFormats token - ESGetToken esGetTokenKalmanFilterFormats_; - // configuration - ParameterSet iConfig_; - // helper class to store configurations - const Setup* setup_ = nullptr; - // helper class to extract structured data from tt::Frames - const DataFormats* dataFormats_ = nullptr; - // helper class to - KalmanFilterFormats* kalmanFilterFormats_ = nullptr; + edm::ESGetToken esGetTokenDataFormats_; + // LayerEncoding token + edm::ESGetToken esGetTokenLayerEncoding_; + // helper class to tune internal kf variables + KalmanFilterFormats kalmanFilterFormats_; + // KalmanFilterFormats configuraation + ConfigKF iConfig_; // print end job internal unused MSB bool printDebug_; + // number of channels + int numChannel_; + // number of processing regions + int numRegions_; + // number of kf layers + int numLayers_; }; - ProducerKF::ProducerKF(const ParameterSet& iConfig) : iConfig_(iConfig) { + ProducerKF::ProducerKF(const edm::ParameterSet& iConfig) { + // KalmanFilterFormats configuraation + iConfig_.enableIntegerEmulation_ = iConfig.getParameter("EnableIntegerEmulation"); + iConfig_.widthR00_ = iConfig.getParameter("WidthR00"); + iConfig_.widthR11_ = iConfig.getParameter("WidthR11"); + iConfig_.widthC00_ = iConfig.getParameter("WidthC00"); + iConfig_.widthC01_ = iConfig.getParameter("WidthC01"); + iConfig_.widthC11_ = iConfig.getParameter("WidthC11"); + iConfig_.widthC22_ = iConfig.getParameter("WidthC22"); + iConfig_.widthC23_ = iConfig.getParameter("WidthC23"); + iConfig_.widthC33_ = iConfig.getParameter("WidthC33"); + iConfig_.baseShiftx0_ = iConfig.getParameter("BaseShiftx0"); + iConfig_.baseShiftx1_ = iConfig.getParameter("BaseShiftx1"); + iConfig_.baseShiftx2_ = iConfig.getParameter("BaseShiftx2"); + iConfig_.baseShiftx3_ = iConfig.getParameter("BaseShiftx3"); + iConfig_.baseShiftr0_ = iConfig.getParameter("BaseShiftr0"); + iConfig_.baseShiftr1_ = iConfig.getParameter("BaseShiftr1"); + iConfig_.baseShiftS00_ = iConfig.getParameter("BaseShiftS00"); + iConfig_.baseShiftS01_ = iConfig.getParameter("BaseShiftS01"); + iConfig_.baseShiftS12_ = iConfig.getParameter("BaseShiftS12"); + iConfig_.baseShiftS13_ = iConfig.getParameter("BaseShiftS13"); + iConfig_.baseShiftR00_ = iConfig.getParameter("BaseShiftR00"); + iConfig_.baseShiftR11_ = iConfig.getParameter("BaseShiftR11"); + iConfig_.baseShiftInvR00Approx_ = iConfig.getParameter("BaseShiftInvR00Approx"); + iConfig_.baseShiftInvR11Approx_ = iConfig.getParameter("BaseShiftInvR11Approx"); + iConfig_.baseShiftInvR00Cor_ = iConfig.getParameter("BaseShiftInvR00Cor"); + iConfig_.baseShiftInvR11Cor_ = iConfig.getParameter("BaseShiftInvR11Cor"); + iConfig_.baseShiftInvR00_ = iConfig.getParameter("BaseShiftInvR00"); + iConfig_.baseShiftInvR11_ = iConfig.getParameter("BaseShiftInvR11"); + iConfig_.baseShiftS00Shifted_ = iConfig.getParameter("BaseShiftS00Shifted"); + iConfig_.baseShiftS01Shifted_ = iConfig.getParameter("BaseShiftS01Shifted"); + iConfig_.baseShiftS12Shifted_ = iConfig.getParameter("BaseShiftS12Shifted"); + iConfig_.baseShiftS13Shifted_ = iConfig.getParameter("BaseShiftS13Shifted"); + iConfig_.baseShiftK00_ = iConfig.getParameter("BaseShiftK00"); + iConfig_.baseShiftK10_ = iConfig.getParameter("BaseShiftK10"); + iConfig_.baseShiftK21_ = iConfig.getParameter("BaseShiftK21"); + iConfig_.baseShiftK31_ = iConfig.getParameter("BaseShiftK31"); + iConfig_.baseShiftC00_ = iConfig.getParameter("BaseShiftC00"); + iConfig_.baseShiftC01_ = iConfig.getParameter("BaseShiftC01"); + iConfig_.baseShiftC11_ = iConfig.getParameter("BaseShiftC11"); + iConfig_.baseShiftC22_ = iConfig.getParameter("BaseShiftC22"); + iConfig_.baseShiftC23_ = iConfig.getParameter("BaseShiftC23"); + iConfig_.baseShiftC33_ = iConfig.getParameter("BaseShiftC33"); + iConfig_.baseShiftr0Shifted_ = iConfig.getParameter("BaseShiftr0Shifted"); + iConfig_.baseShiftr1Shifted_ = iConfig.getParameter("BaseShiftr1Shifted"); + iConfig_.baseShiftr02_ = iConfig.getParameter("BaseShiftr02"); + iConfig_.baseShiftr12_ = iConfig.getParameter("BaseShiftr12"); + iConfig_.baseShiftchi20_ = iConfig.getParameter("BaseShiftchi20"); + iConfig_.baseShiftchi21_ = iConfig.getParameter("BaseShiftchi21"); printDebug_ = iConfig.getParameter("PrintKFDebug"); - const string& label = iConfig.getParameter("LabelKFin"); - const string& branchAcceptedStubs = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchAcceptedTracks = iConfig.getParameter("BranchAcceptedTracks"); - const string& branchLostStubs = iConfig.getParameter("BranchLostStubs"); - const string& branchLostTracks = iConfig.getParameter("BranchLostTracks"); + const std::string& label = iConfig.getParameter("InputLabelKF"); + const std::string& branchStubs = iConfig.getParameter("BranchStubs"); + const std::string& branchTracks = iConfig.getParameter("BranchTracks"); + const std::string& branchTruncated = iConfig.getParameter("BranchTruncated"); // book in- and output ED products - edGetTokenStubs_ = consumes(InputTag(label, branchAcceptedStubs)); - edGetTokenTracks_ = consumes(InputTag(label, branchAcceptedTracks)); - edPutTokenAcceptedStubs_ = produces(branchAcceptedStubs); - edPutTokenAcceptedTracks_ = produces(branchAcceptedTracks); - edPutTokenLostStubs_ = produces(branchLostStubs); - edPutTokenLostTracks_ = produces(branchLostTracks); - edPutTokenNumAcceptedStates_ = produces(branchAcceptedTracks); - edPutTokenNumLostStates_ = produces(branchLostTracks); + edGetTokenStubs_ = consumes(edm::InputTag(label, branchStubs)); + edGetTokenTracks_ = consumes(edm::InputTag(label, branchTracks)); + edPutTokenStubs_ = produces(branchStubs); + edPutTokenTracks_ = produces(branchTracks); + edPutTokenNumStatesAccepted_ = produces(branchTracks); + edPutTokenNumStatesTruncated_ = produces(branchTruncated); + edPutTokenChi2s_ = produces>>(branchTracks); // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); - esGetTokenKalmanFilterFormats_ = esConsumes(); + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + esGetTokenLayerEncoding_ = esConsumes(); } - void ProducerKF::beginRun(const Run& iRun, const EventSetup& iSetup) { - // helper class to store configurations - setup_ = &iSetup.getData(esGetTokenSetup_); - if (!setup_->configurationSupported()) - return; - // check process history if desired - if (iConfig_.getParameter("CheckHistory")) - setup_->checkHistory(iRun.processHistory()); - // helper class to extract structured data from tt::Frames - dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); - // helper class to - kalmanFilterFormats_ = const_cast(&iSetup.getData(esGetTokenKalmanFilterFormats_)); + void ProducerKF::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) { + const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_); + numRegions_ = setup->numRegions(); + numLayers_ = setup->numLayers(); + const DataFormats* dataFormats = &iSetup.getData(esGetTokenDataFormats_); + numChannel_ = dataFormats->numChannel(Process::kf); + kalmanFilterFormats_.beginRun(dataFormats, iConfig_); } - void ProducerKF::produce(Event& iEvent, const EventSetup& iSetup) { + void ProducerKF::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + // helper class to store configurations + const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_); + // helper class to extract structured data from tt::Frames + const DataFormats* dataFormats = &iSetup.getData(esGetTokenDataFormats_); + // helper class to encode layer + const LayerEncoding* layerEncoding = &iSetup.getData(esGetTokenLayerEncoding_); // empty KF products - StreamsStub acceptedStubs(dataFormats_->numStreamsStubs(Process::kf)); - StreamsTrack acceptedTracks(dataFormats_->numStreamsTracks(Process::kf)); - StreamsStub lostStubs(dataFormats_->numStreamsStubs(Process::kf)); - StreamsTrack lostTracks(dataFormats_->numStreamsTracks(Process::kf)); - int numAcceptedStates(0); - int numLostStates(0); + tt::StreamsStub acceptedStubs(numRegions_ * numChannel_ * numLayers_); + tt::StreamsTrack acceptedTracks(numRegions_ * numChannel_); + int numStatesAccepted(0); + int numStatesTruncated(0); + std::deque> chi2s; // read in SF Product and produce KF product - if (setup_->configurationSupported()) { - Handle handleStubs; - iEvent.getByToken(edGetTokenStubs_, handleStubs); - const StreamsStub& stubs = *handleStubs; - Handle handleTracks; - iEvent.getByToken(edGetTokenTracks_, handleTracks); - const StreamsTrack& tracks = *handleTracks; - for (int region = 0; region < setup_->numRegions(); region++) { - // object to fit tracks in a processing region - KalmanFilter kf(iConfig_, setup_, dataFormats_, kalmanFilterFormats_, region); - // read in and organize input tracks and stubs - kf.consume(tracks, stubs); - // fill output products - kf.produce(acceptedStubs, acceptedTracks, lostStubs, lostTracks, numAcceptedStates, numLostStates); + const tt::StreamsStub& allStubs = iEvent.get(edGetTokenStubs_); + const tt::StreamsTrack& allTracks = iEvent.get(edGetTokenTracks_); + // helper + auto validFrameT = [](int sum, const tt::FrameTrack& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); }; + auto validFrameS = [](int sum, const tt::FrameStub& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); }; + auto putT = [](const std::vector& objects, tt::StreamTrack& stream) { + auto toFrame = [](TrackKF* object) { return object ? object->frame() : tt::FrameTrack(); }; + stream.reserve(objects.size()); + std::transform(objects.begin(), objects.end(), std::back_inserter(stream), toFrame); + }; + auto putS = [](const std::vector& objects, tt::StreamStub& stream) { + auto toFrame = [](StubKF* object) { return object ? object->frame() : tt::FrameStub(); }; + stream.reserve(objects.size()); + std::transform(objects.begin(), objects.end(), std::back_inserter(stream), toFrame); + }; + for (int region = 0; region < numRegions_; region++) { + const int offset = region * numChannel_; + // count input objects + int nTracks(0); + int nStubs(0); + for (int channel = 0; channel < numChannel_; channel++) { + const int index = offset + channel; + const int offsetStubs = index * numLayers_; + const tt::StreamTrack& tracks = allTracks[index]; + nTracks += std::accumulate(tracks.begin(), tracks.end(), 0, validFrameT); + for (int layer = 0; layer < numLayers_; layer++) { + const tt::StreamStub& stubs = allStubs[offsetStubs + layer]; + nStubs += std::accumulate(stubs.begin(), stubs.end(), 0, validFrameS); + } + } + // storage of input data + std::vector tracksCTB; + tracksCTB.reserve(nTracks); + std::vector stubs; + stubs.reserve(nStubs); + // h/w liked organized pointer to input data + std::vector> regionTracks(numChannel_); + std::vector> regionStubs(numChannel_ * numLayers_); + // read input data + for (int channel = 0; channel < numChannel_; channel++) { + const int index = offset + channel; + const int offsetAll = index * numLayers_; + const int offsetRegion = channel * numLayers_; + const tt::StreamTrack& streamTrack = allTracks[index]; + std::vector& tracks = regionTracks[channel]; + tracks.reserve(streamTrack.size()); + for (const tt::FrameTrack& frame : streamTrack) { + TrackCTB* track = nullptr; + if (frame.first.isNonnull()) { + tracksCTB.emplace_back(frame, dataFormats); + track = &tracksCTB.back(); + } + tracks.push_back(track); + } + for (int layer = 0; layer < numLayers_; layer++) { + for (const tt::FrameStub& frame : allStubs[offsetAll + layer]) { + Stub* stub = nullptr; + if (frame.first.isNonnull()) { + stubs.emplace_back(&kalmanFilterFormats_, frame); + stub = &stubs.back(); + } + regionStubs[offsetRegion + layer].push_back(stub); + } + } + } + // empty storage of output data + std::vector tracksKF; + tracksKF.reserve(nTracks); + std::vector stubsKF; + stubsKF.reserve(nStubs); + // object to fit tracks in a processing region + KalmanFilter kf(setup, dataFormats, layerEncoding, &kalmanFilterFormats_, tracksKF, stubsKF); + // empty h/w liked organized pointer to output data + std::vector> streamsTrack(numChannel_); + std::vector>> streamsStub(numChannel_, + std::vector>(numLayers_)); + // fill output products + kf.produce(regionTracks, regionStubs, streamsTrack, streamsStub, numStatesAccepted, numStatesTruncated, chi2s); + // convert data to ed products + for (int channel = 0; channel < numChannel_; channel++) { + const int index = offset + channel; + const int offsetStubs = index * numLayers_; + putT(streamsTrack[channel], acceptedTracks[index]); + for (int layer = 0; layer < numLayers_; layer++) + putS(streamsStub[channel][layer], acceptedStubs[offsetStubs + layer]); } } // store products - iEvent.emplace(edPutTokenAcceptedStubs_, std::move(acceptedStubs)); - iEvent.emplace(edPutTokenAcceptedTracks_, std::move(acceptedTracks)); - iEvent.emplace(edPutTokenLostStubs_, std::move(lostStubs)); - iEvent.emplace(edPutTokenLostTracks_, std::move(lostTracks)); - iEvent.emplace(edPutTokenNumAcceptedStates_, numAcceptedStates); - iEvent.emplace(edPutTokenNumLostStates_, numLostStates); + iEvent.emplace(edPutTokenStubs_, std::move(acceptedStubs)); + iEvent.emplace(edPutTokenTracks_, std::move(acceptedTracks)); + iEvent.emplace(edPutTokenNumStatesAccepted_, numStatesAccepted); + iEvent.emplace(edPutTokenNumStatesTruncated_, numStatesTruncated); + iEvent.emplace(edPutTokenChi2s_, chi2s.begin(), chi2s.end()); } } // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/plugins/ProducerKFin.cc b/L1Trigger/TrackerTFP/plugins/ProducerKFin.cc deleted file mode 100644 index a3e539b3270b8..0000000000000 --- a/L1Trigger/TrackerTFP/plugins/ProducerKFin.cc +++ /dev/null @@ -1,225 +0,0 @@ -#include "FWCore/Framework/interface/stream/EDProducer.h" -#include "FWCore/Framework/interface/Run.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Utilities/interface/EDGetToken.h" -#include "FWCore/Utilities/interface/EDPutToken.h" -#include "FWCore/Utilities/interface/ESGetToken.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "DataFormats/Common/interface/Handle.h" - -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" -#include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" -#include "L1Trigger/TrackerTFP/interface/LayerEncoding.h" - -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace edm; -using namespace tt; - -namespace trackerTFP { - - /*! \class trackerTFP::ProducerKFin - * \brief transforms TTTracks into KF input - * \author Thomas Schuh - * \date 2020, July - */ - class ProducerKFin : public stream::EDProducer<> { - public: - explicit ProducerKFin(const ParameterSet&); - ~ProducerKFin() override {} - - private: - void beginRun(const Run&, const EventSetup&) override; - void produce(Event&, const EventSetup&) override; - virtual void endJob() {} - - // ED input token of TTTracks - EDGetTokenT>> edGetTokenTTTracks_; - // ED input token of Stubs - EDGetTokenT edGetTokenStubs_; - // ED output token for stubs - EDPutTokenT edPutTokenAcceptedStubs_; - EDPutTokenT edPutTokenLostStubs_; - // ED output token for tracks - EDPutTokenT edPutTokenAcceptedTracks_; - EDPutTokenT edPutTokenLostTracks_; - // Setup token - ESGetToken esGetTokenSetup_; - // DataFormats token - ESGetToken esGetTokenDataFormats_; - // LayerEncoding token - ESGetToken esGetTokenLayerEncoding_; - // configuration - ParameterSet iConfig_; - // helper class to store configurations - const Setup* setup_ = nullptr; - // helper class to extract structured data from tt::Frames - const DataFormats* dataFormats_ = nullptr; - // helper class to encode layer - const LayerEncoding* layerEncoding_ = nullptr; - // - bool enableTruncation_; - }; - - ProducerKFin::ProducerKFin(const ParameterSet& iConfig) : iConfig_(iConfig) { - const string& labelTTTracks = iConfig.getParameter("LabelZHTout"); - const string& labelStubs = iConfig.getParameter("LabelZHT"); - const string& branchAcceptedStubs = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchAcceptedTracks = iConfig.getParameter("BranchAcceptedTracks"); - const string& branchLostStubs = iConfig.getParameter("BranchLostStubs"); - const string& branchLostTracks = iConfig.getParameter("BranchLostTracks"); - // book in- and output ED products - edGetTokenTTTracks_ = - consumes>>(InputTag(labelTTTracks, branchAcceptedTracks)); - edGetTokenStubs_ = consumes(InputTag(labelStubs, branchAcceptedStubs)); - edPutTokenAcceptedStubs_ = produces(branchAcceptedStubs); - edPutTokenAcceptedTracks_ = produces(branchAcceptedTracks); - edPutTokenLostStubs_ = produces(branchLostStubs); - edPutTokenLostTracks_ = produces(branchLostTracks); - // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); - esGetTokenLayerEncoding_ = esConsumes(); - // - enableTruncation_ = iConfig.getParameter("EnableTruncation"); - } - - void ProducerKFin::beginRun(const Run& iRun, const EventSetup& iSetup) { - // helper class to store configurations - setup_ = &iSetup.getData(esGetTokenSetup_); - if (!setup_->configurationSupported()) - return; - // check process history if desired - if (iConfig_.getParameter("CheckHistory")) - setup_->checkHistory(iRun.processHistory()); - // helper class to extract structured data from tt::Frames - dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); - // helper class to encode layer - layerEncoding_ = &iSetup.getData(esGetTokenLayerEncoding_); - } - - void ProducerKFin::produce(Event& iEvent, const EventSetup& iSetup) { - const DataFormat& dfcot = dataFormats_->format(Variable::cot, Process::kfin); - const DataFormat& dfzT = dataFormats_->format(Variable::zT, Process::kfin); - const DataFormat& dfinv2R = dataFormats_->format(Variable::inv2R, Process::kfin); - const DataFormat& dfdPhi = dataFormats_->format(Variable::dPhi, Process::kfin); - const DataFormat& dfdZ = dataFormats_->format(Variable::dZ, Process::kfin); - // empty KFin products - StreamsStub streamAcceptedStubs(dataFormats_->numStreamsStubs(Process::kf)); - StreamsTrack streamAcceptedTracks(dataFormats_->numStreamsTracks(Process::kf)); - StreamsStub streamLostStubs(dataFormats_->numStreamsStubs(Process::kf)); - StreamsTrack streamLostTracks(dataFormats_->numStreamsTracks(Process::kf)); - // read in SFout Product and produce KFin product - if (setup_->configurationSupported()) { - Handle handleStubs; - iEvent.getByToken(edGetTokenStubs_, handleStubs); - const StreamsStub& streams = *handleStubs.product(); - Handle>> handleTTTracks; - iEvent.getByToken>>(edGetTokenTTTracks_, handleTTTracks); - const vector>& ttTracks = *handleTTTracks.product(); - for (int region = 0; region < setup_->numRegions(); region++) { - // Unpack input SF data into vector - int nStubsZHR(0); - for (int channel = 0; channel < dataFormats_->numChannel(Process::zht); channel++) { - const int index = region * dataFormats_->numChannel(Process::zht) + channel; - const StreamStub& stream = streams[index]; - nStubsZHR += accumulate(stream.begin(), stream.end(), 0, [](int sum, const FrameStub& frame) { - return sum + (frame.first.isNonnull() ? 1 : 0); - }); - } - vector stubsZHT; - stubsZHT.reserve(nStubsZHR); - for (int channel = 0; channel < dataFormats_->numChannel(Process::zht); channel++) { - const int index = region * dataFormats_->numChannel(Process::zht) + channel; - for (const FrameStub& frame : streams[index]) - if (frame.first.isNonnull()) - stubsZHT.emplace_back(frame, dataFormats_); - } - vector> dequesStubs(dataFormats_->numChannel(Process::kf) * setup_->numLayers()); - vector> dequesTracks(dataFormats_->numChannel(Process::kf)); - int i(0); - for (const TTTrack& ttTrack : ttTracks) { - if ((int)ttTrack.phiSector() / setup_->numSectorsPhi() != region) { - i++; - continue; - } - const int sectorPhi = ttTrack.phiSector() % setup_->numSectorsPhi(); - deque& tracks = dequesTracks[sectorPhi]; - const int binEta = ttTrack.etaSector(); - const int binZT = dfzT.toUnsigned(dfzT.integer(ttTrack.z0())); - const int binCot = dfcot.toUnsigned(dfcot.integer(ttTrack.tanL())); - StubZHT* stubZHT = nullptr; - vector layerCounts(setup_->numLayers(), 0); - for (const TTStubRef& ttStubRef : ttTrack.getStubRefs()) { - const int layerId = setup_->layerId(ttStubRef); - const int layerIdKF = layerEncoding_->layerIdKF(binEta, binZT, binCot, layerId); - if (layerIdKF == -1) - continue; - if (layerCounts[layerIdKF] == setup_->zhtMaxStubsPerLayer()) - continue; - layerCounts[layerIdKF]++; - deque& stubs = dequesStubs[sectorPhi * setup_->numLayers() + layerIdKF]; - auto identical = [ttStubRef, ttTrack](const StubZHT& stub) { - return (int)ttTrack.trackSeedType() == stub.trackId() && ttStubRef == stub.ttStubRef(); - }; - stubZHT = &*find_if(stubsZHT.begin(), stubsZHT.end(), identical); - const double inv2R = dfinv2R.floating(stubZHT->inv2R()); - const double cot = dfcot.floating(stubZHT->cot()) + setup_->sectorCot(binEta); - const double dPhi = dfdPhi.digi(setup_->dPhi(ttStubRef, inv2R)); - const double dZ = dfdZ.digi(setup_->dZ(ttStubRef, cot)); - stubs.emplace_back(StubKFin(*stubZHT, dPhi, dZ, layerIdKF).frame()); - } - const int size = *max_element(layerCounts.begin(), layerCounts.end()); - int layerIdKF(0); - for (int layerCount : layerCounts) { - deque& stubs = dequesStubs[sectorPhi * setup_->numLayers() + layerIdKF++]; - const int nGaps = size - layerCount; - stubs.insert(stubs.end(), nGaps, FrameStub()); - } - const TTBV& maybePattern = layerEncoding_->maybePattern(binEta, binZT, binCot); - const TrackKFin track(*stubZHT, TTTrackRef(handleTTTracks, i++), maybePattern); - tracks.emplace_back(track.frame()); - const int nGaps = size - 1; - tracks.insert(tracks.end(), nGaps, FrameTrack()); - } - // transform deques to vectors & emulate truncation - for (int channel = 0; channel < dataFormats_->numChannel(Process::kf); channel++) { - const int index = region * dataFormats_->numChannel(Process::kf) + channel; - deque& tracks = dequesTracks[channel]; - auto limitTracks = next(tracks.begin(), min(setup_->numFrames(), (int)tracks.size())); - if (!enableTruncation_) - limitTracks = tracks.end(); - streamAcceptedTracks[index] = StreamTrack(tracks.begin(), limitTracks); - streamLostTracks[index] = StreamTrack(limitTracks, tracks.end()); - for (int l = 0; l < setup_->numLayers(); l++) { - deque& stubs = dequesStubs[channel * setup_->numLayers() + l]; - auto limitStubs = next(stubs.begin(), min(setup_->numFrames(), (int)stubs.size())); - if (!enableTruncation_) - limitStubs = stubs.end(); - streamAcceptedStubs[index * setup_->numLayers() + l] = StreamStub(stubs.begin(), limitStubs); - streamLostStubs[index * setup_->numLayers() + l] = StreamStub(limitStubs, stubs.end()); - } - } - } - } - // store products - iEvent.emplace(edPutTokenAcceptedStubs_, std::move(streamAcceptedStubs)); - iEvent.emplace(edPutTokenAcceptedTracks_, std::move(streamAcceptedTracks)); - iEvent.emplace(edPutTokenLostStubs_, std::move(streamLostStubs)); - iEvent.emplace(edPutTokenLostTracks_, std::move(streamLostTracks)); - } - -} // namespace trackerTFP - -DEFINE_FWK_MODULE(trackerTFP::ProducerKFin); diff --git a/L1Trigger/TrackerTFP/plugins/ProducerLayerEncoding.cc b/L1Trigger/TrackerTFP/plugins/ProducerLayerEncoding.cc index e8858d144c4db..13178c7b68cfb 100644 --- a/L1Trigger/TrackerTFP/plugins/ProducerLayerEncoding.cc +++ b/L1Trigger/TrackerTFP/plugins/ProducerLayerEncoding.cc @@ -3,14 +3,10 @@ #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/Utilities/interface/ESGetToken.h" #include "FWCore/Utilities/interface/ESInputTag.h" -#include "DataFormats/Provenance/interface/ParameterSetID.h" #include "L1Trigger/TrackerTFP/interface/LayerEncoding.h" #include -using namespace std; -using namespace edm; - namespace trackerTFP { /*! \class trackerTFP::ProducerLayerEncoding @@ -18,25 +14,24 @@ namespace trackerTFP { * \author Thomas Schuh * \date 2020, July */ - class ProducerLayerEncoding : public ESProducer { + class ProducerLayerEncoding : public edm::ESProducer { public: - ProducerLayerEncoding(const ParameterSet& iConfig); + ProducerLayerEncoding(const edm::ParameterSet& iConfig); ~ProducerLayerEncoding() override {} - unique_ptr produce(const LayerEncodingRcd& rcd); + std::unique_ptr produce(const DataFormatsRcd& rcd); private: - const ParameterSet iConfig_; - ESGetToken esGetToken_; + edm::ESGetToken esGetToken_; }; - ProducerLayerEncoding::ProducerLayerEncoding(const ParameterSet& iConfig) : iConfig_(iConfig) { + ProducerLayerEncoding::ProducerLayerEncoding(const edm::ParameterSet& iConfig) { auto cc = setWhatProduced(this); esGetToken_ = cc.consumes(); } - unique_ptr ProducerLayerEncoding::produce(const LayerEncodingRcd& rcd) { + std::unique_ptr ProducerLayerEncoding::produce(const DataFormatsRcd& rcd) { const DataFormats* dataFormats = &rcd.get(esGetToken_); - return make_unique(dataFormats); + return std::make_unique(dataFormats); } } // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/plugins/ProducerMHT.cc b/L1Trigger/TrackerTFP/plugins/ProducerMHT.cc deleted file mode 100644 index 7ca6a74f8d108..0000000000000 --- a/L1Trigger/TrackerTFP/plugins/ProducerMHT.cc +++ /dev/null @@ -1,110 +0,0 @@ -#include "FWCore/Framework/interface/stream/EDProducer.h" -#include "FWCore/Framework/interface/Run.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Utilities/interface/EDGetToken.h" -#include "FWCore/Utilities/interface/EDPutToken.h" -#include "FWCore/Utilities/interface/ESGetToken.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "DataFormats/Common/interface/Handle.h" - -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" -#include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" -#include "L1Trigger/TrackerTFP/interface/MiniHoughTransform.h" - -#include -#include - -using namespace std; -using namespace edm; -using namespace tt; - -namespace trackerTFP { - - /*! \class trackerTFP::ProducerMHT - * \brief L1TrackTrigger Mini Hough Transform emulator - * \author Thomas Schuh - * \date 2020, May - */ - class ProducerMHT : public stream::EDProducer<> { - public: - explicit ProducerMHT(const ParameterSet&); - ~ProducerMHT() override {} - - private: - void beginRun(const Run&, const EventSetup&) override; - void produce(Event&, const EventSetup&) override; - virtual void endJob() {} - - // ED input token of gp stubs - EDGetTokenT edGetToken_; - // ED output token for accepted stubs - EDPutTokenT edPutTokenAccepted_; - // ED output token for lost stubs - EDPutTokenT edPutTokenLost_; - // Setup token - ESGetToken esGetTokenSetup_; - // DataFormats token - ESGetToken esGetTokenDataFormats_; - // configuration - ParameterSet iConfig_; - // helper class to store configurations - const Setup* setup_ = nullptr; - // helper class to extract structured data from tt::Frames - const DataFormats* dataFormats_ = nullptr; - }; - - ProducerMHT::ProducerMHT(const ParameterSet& iConfig) : iConfig_(iConfig) { - const string& label = iConfig.getParameter("LabelHT"); - const string& branchAccepted = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchLost = iConfig.getParameter("BranchLostStubs"); - // book in- and output ED products - edGetToken_ = consumes(InputTag(label, branchAccepted)); - edPutTokenAccepted_ = produces(branchAccepted); - edPutTokenLost_ = produces(branchLost); - // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); - } - - void ProducerMHT::beginRun(const Run& iRun, const EventSetup& iSetup) { - // helper class to store configurations - setup_ = &iSetup.getData(esGetTokenSetup_); - if (!setup_->configurationSupported()) - return; - // check process history if desired - if (iConfig_.getParameter("CheckHistory")) - setup_->checkHistory(iRun.processHistory()); - // helper class to extract structured data from tt::Frames - dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); - } - - void ProducerMHT::produce(Event& iEvent, const EventSetup& iSetup) { - // empty MHT products - StreamsStub accepted(dataFormats_->numStreams(Process::mht)); - StreamsStub lost(dataFormats_->numStreams(Process::mht)); - // read in HT Product and produce MHT product - if (setup_->configurationSupported()) { - Handle handle; - iEvent.getByToken(edGetToken_, handle); - const StreamsStub& streams = *handle.product(); - for (int region = 0; region < setup_->numRegions(); region++) { - // object to find in a region finer rough candidates in r-phi - MiniHoughTransform mht(iConfig_, setup_, dataFormats_, region); - // read in and organize input product - mht.consume(streams); - // fill output products - mht.produce(accepted, lost); - } - } - // store products - iEvent.emplace(edPutTokenAccepted_, std::move(accepted)); - iEvent.emplace(edPutTokenLost_, std::move(lost)); - } - -} // namespace trackerTFP - -DEFINE_FWK_MODULE(trackerTFP::ProducerMHT); diff --git a/L1Trigger/TrackerTFP/plugins/ProducerPP.cc b/L1Trigger/TrackerTFP/plugins/ProducerPP.cc new file mode 100644 index 0000000000000..240857247df8f --- /dev/null +++ b/L1Trigger/TrackerTFP/plugins/ProducerPP.cc @@ -0,0 +1,69 @@ +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Utilities/interface/EDPutToken.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "DataFormats/Common/interface/Handle.h" + +#include "DataFormats/L1TrackTrigger/interface/TTDTC.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "L1Trigger/TrackTrigger/interface/Setup.h" + +#include + +namespace trackerTFP { + + /*! \class trackerTFP::ProducerPP + * \brief L1TrackTrigger PatchPanel between DTC and TFP emulator + * \author Thomas Schuh + * \date 2023, April + */ + class ProducerPP : public edm::stream::EDProducer<> { + public: + explicit ProducerPP(const edm::ParameterSet&); + ~ProducerPP() override {} + + private: + void produce(edm::Event&, const edm::EventSetup&) override; + // ED input token of DTC stubs + edm::EDGetTokenT edGetToken_; + // ED output token for accepted stubs + edm::EDPutTokenT edPutToken_; + // Setup token + edm::ESGetToken esGetTokenSetup_; + }; + + ProducerPP::ProducerPP(const edm::ParameterSet& iConfig) { + const std::string& label = iConfig.getParameter("InputLabelPP"); + const std::string& branch = iConfig.getParameter("BranchStubs"); + // book in- and output ED products + edGetToken_ = consumes(edm::InputTag(label, branch)); + edPutToken_ = produces(branch); + // book ES products + esGetTokenSetup_ = esConsumes(); + } + + void ProducerPP::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + // helper classe to store configurations + const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_); + // empty GP products + tt::StreamsStub stubs(setup->numRegions() * setup->numDTCsPerTFP()); + // read in DTC Product and produce TFP product + const TTDTC& ttDTC = iEvent.get(edGetToken_); + for (int region = 0; region < setup->numRegions(); region++) { + const int offset = region * setup->numDTCsPerTFP(); + for (int channel = 0; channel < setup->numDTCsPerTFP(); channel++) + stubs[offset + channel] = ttDTC.stream(region, channel); + } + // store products + iEvent.emplace(edPutToken_, std::move(stubs)); + } + +} // namespace trackerTFP + +DEFINE_FWK_MODULE(trackerTFP::ProducerPP); diff --git a/L1Trigger/TrackerTFP/plugins/ProducerTFP.cc b/L1Trigger/TrackerTFP/plugins/ProducerTFP.cc new file mode 100644 index 0000000000000..b3923bed9d5a2 --- /dev/null +++ b/L1Trigger/TrackerTFP/plugins/ProducerTFP.cc @@ -0,0 +1,107 @@ +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Utilities/interface/EDPutToken.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/Common/interface/OrphanHandle.h" + +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackerTFP/interface/DataFormats.h" +#include "L1Trigger/TrackerTFP/interface/TrackQuality.h" +#include "L1Trigger/TrackerTFP/interface/TrackFindingProcessor.h" + +#include +#include +#include +#include + +namespace trackerTFP { + + /*! \class trackerTFP::ProducerTFP + * \brief L1TrackTrigger final TFP output formatter + * \author Thomas Schuh + * \date 2023, June + */ + class ProducerTFP : public edm::stream::EDProducer<> { + public: + explicit ProducerTFP(const edm::ParameterSet&); + ~ProducerTFP() override {} + + private: + void produce(edm::Event&, const edm::EventSetup&) override; + // ED input token of stubs and tracks + edm::EDGetTokenT edGetTokenTracks_; + edm::EDGetTokenT edGetTokenStubs_; + // ED output token for accepted stubs and tracks + edm::EDPutTokenT edPutTokenTTTracks_; + edm::EDPutTokenT edPutTokenTracks_; + // Setup token + edm::ESGetToken esGetTokenSetup_; + // DataFormats token + edm::ESGetToken esGetTokenDataFormats_; + // TrackQuality token + edm::ESGetToken esGetTokenTrackQuality_; + // helper class to store configurations + const tt::Setup* setup_ = nullptr; + // helper class to extract structured data from tt::Frames + const DataFormats* dataFormats_ = nullptr; + // helper class to determine track quality + const TrackQuality* trackQuality_ = nullptr; + }; + + ProducerTFP::ProducerTFP(const edm::ParameterSet& iConfig) { + const std::string& labelTracks = iConfig.getParameter("InputLabelTFP"); + const std::string& labelStubs = iConfig.getParameter("InputLabelTQ"); + const std::string& branchTracks = iConfig.getParameter("BranchTracks"); + const std::string& branchTTTracks = iConfig.getParameter("BranchTTTracks"); + const std::string& branchStubs = iConfig.getParameter("BranchStubs"); + // book in- and output ED products + edGetTokenTracks_ = consumes(edm::InputTag(labelTracks, branchTracks)); + edGetTokenStubs_ = consumes(edm::InputTag(labelStubs, branchStubs)); + edPutTokenTTTracks_ = produces(branchTTTracks); + edPutTokenTracks_ = produces(branchTracks); + // book ES products + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + esGetTokenTrackQuality_ = esConsumes(); + } + + void ProducerTFP::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + // helper class to store configurations + const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_); + // helper class to extract structured data from tt::Frames + const DataFormats* dataFormats = &iSetup.getData(esGetTokenDataFormats_); + // helper class to determine track quality + const TrackQuality* trackQuality = &iSetup.getData(esGetTokenTrackQuality_); + // empty TFP products + tt::TTTracks ttTracks; + tt::StreamsTrack streamsTrack(setup->numRegions() * setup->tfpNumChannel()); + // read in TQ Products + const tt::StreamsTrack& tracks = iEvent.get(edGetTokenTracks_); + const tt::StreamsStub& stubs = iEvent.get(edGetTokenStubs_); + // produce TTTracks + TrackFindingProcessor tfp(setup, dataFormats, trackQuality); + tfp.produce(tracks, stubs, ttTracks, streamsTrack); + // put TTTRacks and produce TTTRackRefs + const int nTrks = ttTracks.size(); + const edm::OrphanHandle oh = iEvent.emplace(edPutTokenTTTracks_, std::move(ttTracks)); + std::vector ttTrackRefs; + ttTrackRefs.reserve(nTrks); + for (int iTrk = 0; iTrk < nTrks; iTrk++) + ttTrackRefs.emplace_back(oh, iTrk); + // replace old TTTrackRefs in streamsTrack with new TTTrackRefs + tfp.produce(ttTrackRefs, streamsTrack); + // put StreamsTrack + iEvent.emplace(edPutTokenTracks_, std::move(streamsTrack)); + } + +} // namespace trackerTFP + +DEFINE_FWK_MODULE(trackerTFP::ProducerTFP); diff --git a/L1Trigger/TrackerTFP/plugins/ProducerTQ.cc b/L1Trigger/TrackerTFP/plugins/ProducerTQ.cc new file mode 100644 index 0000000000000..b86755c1c9a41 --- /dev/null +++ b/L1Trigger/TrackerTFP/plugins/ProducerTQ.cc @@ -0,0 +1,129 @@ +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Utilities/interface/EDPutToken.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "DataFormats/Common/interface/Handle.h" + +#include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackerTFP/interface/DataFormats.h" +#include "L1Trigger/TrackerTFP/interface/TrackQuality.h" + +#include +#include + +namespace trackerTFP { + + /*! \class trackerTFP::ProducerTQ + * \brief Bit accurate emulation of the track quality BDT + * \author Thomas Schuh + * \date 2024, Aug + */ + class ProducerTQ : public edm::stream::EDProducer<> { + public: + explicit ProducerTQ(const edm::ParameterSet&); + ~ProducerTQ() override {} + void produce(edm::Event&, const edm::EventSetup&) override; + + private: + typedef TrackQuality::Track Track; + // ED input token of kf stubs + edm::EDGetTokenT edGetTokenStubs_; + // ED input token of kf tracks + edm::EDGetTokenT edGetTokenTracks_; + // ED output token for tracks + edm::EDPutTokenT edPutTokenTracks_; + // ED output token for additional track variables + edm::EDPutTokenT edPutTokenTracksAdd_; + // ED output token for stubs + edm::EDPutTokenT edPutTokenStubs_; + // Setup token + edm::ESGetToken esGetTokenSetup_; + // DataFormats token + edm::ESGetToken esGetTokenDataFormats_; + // TrackQuality token + edm::ESGetToken esGetTokenTrackQuality_; + }; + + ProducerTQ::ProducerTQ(const edm::ParameterSet& iConfig) { + const std::string& label = iConfig.getParameter("InputLabelTQ"); + const std::string& branchStubs = iConfig.getParameter("BranchStubs"); + const std::string& branchTracks = iConfig.getParameter("BranchTracks"); + // book in- and output ED products + edGetTokenStubs_ = consumes(edm::InputTag(label, branchStubs)); + edGetTokenTracks_ = consumes(edm::InputTag(label, branchTracks)); + edPutTokenTracks_ = produces(branchTracks); + edPutTokenTracksAdd_ = produces(branchTracks); + edPutTokenStubs_ = produces(branchStubs); + // book ES products + esGetTokenSetup_ = esConsumes(); + esGetTokenTrackQuality_ = esConsumes(); + } + + void ProducerTQ::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + // helper class to store configurations + const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_); + // helper class to determine Track Quality + const TrackQuality* trackQuality = &iSetup.getData(esGetTokenTrackQuality_); + auto valid = [](int sum, const tt::FrameTrack& frame) { return sum + (frame.first.isNull() ? 0 : 1); }; + // empty TQ product + tt::StreamsTrack outputTracks(setup->numRegions()); + tt::Streams outputTracksAdd(setup->numRegions()); + tt::StreamsStub outputStubs(setup->numRegions() * setup->numLayers()); + // read in KF Product and produce TQ product + const tt::StreamsStub& streamsStubs = iEvent.get(edGetTokenStubs_); + const tt::StreamsTrack& streamsTracks = iEvent.get(edGetTokenTracks_); + for (int region = 0; region < setup->numRegions(); region++) { + // calculate track quality + const int offsetLayer = region * setup->numLayers(); + const tt::StreamTrack& streamTrack = streamsTracks[region]; + const int nTracks = std::accumulate(streamTrack.begin(), streamTrack.end(), 0, valid); + std::vector tracks; + tracks.reserve(nTracks); + std::vector stream; + stream.reserve(streamTrack.size()); + for (int frame = 0; frame < static_cast(streamTrack.size()); frame++) { + const tt::FrameTrack& frameTrack = streamTrack[frame]; + if (frameTrack.first.isNull()) { + stream.push_back(nullptr); + continue; + } + tt::StreamStub streamStub; + streamStub.reserve(setup->numLayers()); + for (int layer = 0; layer < setup->numLayers(); layer++) + streamStub.push_back(streamsStubs[offsetLayer + layer][frame]); + tracks.emplace_back(frameTrack, streamStub, trackQuality); + stream.push_back(&tracks.back()); + } + // fill TQ product + outputTracks[region].reserve(stream.size()); + outputTracksAdd[region].reserve(stream.size()); + for (int layer = 0; layer < setup->numLayers(); layer++) + outputStubs[offsetLayer + layer].reserve(stream.size()); + for (Track* track : stream) { + if (!track) { + outputTracks[region].emplace_back(tt::FrameTrack()); + outputTracksAdd[region].emplace_back(tt::Frame()); + for (int layer = 0; layer < setup->numLayers(); layer++) + outputStubs[offsetLayer + layer].emplace_back(tt::FrameStub()); + continue; + } + outputTracks[region].emplace_back(track->frameTrack_); + outputTracksAdd[region].emplace_back(track->frame_); + for (int layer = 0; layer < setup->numLayers(); layer++) + outputStubs[offsetLayer + layer].emplace_back(track->streamStub_[layer]); + } + } + // store TQ product + iEvent.emplace(edPutTokenTracks_, std::move(outputTracks)); + iEvent.emplace(edPutTokenTracksAdd_, std::move(outputTracksAdd)); + iEvent.emplace(edPutTokenStubs_, streamsStubs); + } +} // namespace trackerTFP + +DEFINE_FWK_MODULE(trackerTFP::ProducerTQ); diff --git a/L1Trigger/TrackerTFP/plugins/ProducerTT.cc b/L1Trigger/TrackerTFP/plugins/ProducerTT.cc deleted file mode 100644 index dbb278cf9b068..0000000000000 --- a/L1Trigger/TrackerTFP/plugins/ProducerTT.cc +++ /dev/null @@ -1,124 +0,0 @@ -#include "FWCore/Framework/interface/stream/EDProducer.h" -#include "FWCore/Framework/interface/Run.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Utilities/interface/EDGetToken.h" -#include "FWCore/Utilities/interface/EDPutToken.h" -#include "FWCore/Utilities/interface/ESGetToken.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "DataFormats/Common/interface/Handle.h" - -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" -#include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" - -#include -#include - -using namespace std; -using namespace edm; -using namespace tt; - -namespace trackerTFP { - - /*! \class trackerTFP::ProducerTT - * \brief Converts KF output into TTTracks - * \author Thomas Schuh - * \date 2020, Oct - */ - class ProducerTT : public stream::EDProducer<> { - public: - explicit ProducerTT(const ParameterSet&); - ~ProducerTT() override {} - - private: - void beginRun(const Run&, const EventSetup&) override; - void produce(Event&, const EventSetup&) override; - void endJob() {} - - // ED input token of kf stubs - EDGetTokenT edGetTokenStubs_; - // ED input token of kf tracks - EDGetTokenT edGetTokenTracks_; - // ED output token for TTTracks - EDPutTokenT edPutToken_; - // Setup token - ESGetToken esGetTokenSetup_; - // DataFormats token - ESGetToken esGetTokenDataFormats_; - // configuration - ParameterSet iConfig_; - // helper class to store configurations - const Setup* setup_ = nullptr; - // helper class to extract structured data from tt::Frames - const DataFormats* dataFormats_ = nullptr; - }; - - ProducerTT::ProducerTT(const ParameterSet& iConfig) : iConfig_(iConfig) { - const string& label = iConfig.getParameter("LabelKF"); - const string& branchStubs = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchTracks = iConfig.getParameter("BranchAcceptedTracks"); - // book in- and output ED products - edGetTokenStubs_ = consumes(InputTag(label, branchStubs)); - edGetTokenTracks_ = consumes(InputTag(label, branchTracks)); - edPutToken_ = produces(branchTracks); - // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); - } - - void ProducerTT::beginRun(const Run& iRun, const EventSetup& iSetup) { - // helper class to store configurations - setup_ = &iSetup.getData(esGetTokenSetup_); - if (!setup_->configurationSupported()) - return; - // check process history if desired - if (iConfig_.getParameter("CheckHistory")) - setup_->checkHistory(iRun.processHistory()); - // helper class to extract structured data from tt::Frames - dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); - } - - void ProducerTT::produce(Event& iEvent, const EventSetup& iSetup) { - // empty KFTTTrack product - TTTracks ttTracks; - // read in KF Product and produce KFTTTrack product - if (setup_->configurationSupported()) { - Handle handleTracks; - iEvent.getByToken(edGetTokenTracks_, handleTracks); - const StreamsTrack& streamsTracks = *handleTracks.product(); - Handle handleStubs; - iEvent.getByToken(edGetTokenTracks_, handleStubs); - const StreamsStub& streamsStubs = *handleStubs.product(); - int nTracks(0); - for (const StreamTrack& stream : streamsTracks) - nTracks += accumulate(stream.begin(), stream.end(), 0, [](int sum, const FrameTrack& frame) { - return sum + (frame.first.isNonnull() ? 1 : 0); - }); - ttTracks.reserve(nTracks); - for (int channel = 0; channel < dataFormats_->numStreamsTracks(Process::kf); channel++) { - int iTrk(0); - const int offset = channel * setup_->numLayers(); - for (const FrameTrack& frameTrack : streamsTracks[channel]) { - vector stubs; - stubs.reserve(setup_->numLayers()); - for (int layer = 0; layer < setup_->numLayers(); layer++) { - const FrameStub& frameStub = streamsStubs[offset + layer][iTrk]; - if (frameStub.first.isNonnull()) - stubs.emplace_back(frameStub, dataFormats_, layer); - } - TrackKF track(frameTrack, dataFormats_); - ttTracks.emplace_back(track.ttTrack(stubs)); - iTrk++; - } - } - } - // store products - iEvent.emplace(edPutToken_, std::move(ttTracks)); - } - -} // namespace trackerTFP - -DEFINE_FWK_MODULE(trackerTFP::ProducerTT); diff --git a/L1Trigger/TrackerTFP/plugins/ProducerTrackQuality.cc b/L1Trigger/TrackerTFP/plugins/ProducerTrackQuality.cc new file mode 100644 index 0000000000000..d494c5d87c5f6 --- /dev/null +++ b/L1Trigger/TrackerTFP/plugins/ProducerTrackQuality.cc @@ -0,0 +1,54 @@ +#include "FWCore/Framework/interface/ESProducer.h" +#include "FWCore/Framework/interface/ModuleFactory.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "L1Trigger/TrackerTFP/interface/TrackQuality.h" + +#include + +namespace trackerTFP { + + /*! \class trackerTFP::ProducerTrackQuality + * \brief Class to produce TrackQuality of Track Trigger emulators + * \author Thomas Schuh + * \date 2024, July + */ + class ProducerTrackQuality : public edm::ESProducer { + public: + ProducerTrackQuality(const edm::ParameterSet& iConfig) { + auto cc = setWhatProduced(this); + esGetToken_ = cc.consumes(); + iConfig_.model_ = iConfig.getParameter("Model"); + iConfig_.featureNames_ = iConfig.getParameter>("FeatureNames"); + iConfig_.baseShiftCot_ = iConfig.getParameter("BaseShiftCot"); + iConfig_.baseShiftZ0_ = iConfig.getParameter("BaseShiftZ0"); + iConfig_.baseShiftAPfixed_ = iConfig.getParameter("BaseShiftAPfixed"); + iConfig_.chi2rphiConv_ = iConfig.getParameter("Chi2rphiConv"); + iConfig_.chi2rzConv_ = iConfig.getParameter("Chi2rzConv"); + iConfig_.weightBinFraction_ = iConfig.getParameter("WeightBinFraction"); + iConfig_.dzTruncation_ = iConfig.getParameter("DzTruncation"); + iConfig_.dphiTruncation_ = iConfig.getParameter("DphiTruncation"); + iConfig_.widthM20_ = iConfig.getParameter("WidthM20"); + iConfig_.widthM21_ = iConfig.getParameter("WidthM21"); + iConfig_.widthInvV0_ = iConfig.getParameter("WidthInvV0"); + iConfig_.widthInvV1_ = iConfig.getParameter("WidthInvV1"); + iConfig_.widthchi2rphi_ = iConfig.getParameter("Widthchi2rphi"); + iConfig_.widthchi2rz_ = iConfig.getParameter("Widthchi2rz"); + iConfig_.baseShiftchi2rphi_ = iConfig.getParameter("BaseShiftchi2rphi"); + iConfig_.baseShiftchi2rz_ = iConfig.getParameter("BaseShiftchi2rz"); + } + ~ProducerTrackQuality() override {} + std::unique_ptr produce(const DataFormatsRcd& rcd) { + const DataFormats* dataFormats = &rcd.get(esGetToken_); + return std::make_unique(iConfig_, dataFormats); + } + + private: + ConfigTQ iConfig_; + edm::ESGetToken esGetToken_; + }; + +} // namespace trackerTFP + +DEFINE_FWK_EVENTSETUP_MODULE(trackerTFP::ProducerTrackQuality); diff --git a/L1Trigger/TrackerTFP/plugins/ProducerZHT.cc b/L1Trigger/TrackerTFP/plugins/ProducerZHT.cc deleted file mode 100644 index 4a07b157ea3a0..0000000000000 --- a/L1Trigger/TrackerTFP/plugins/ProducerZHT.cc +++ /dev/null @@ -1,110 +0,0 @@ -#include "FWCore/Framework/interface/stream/EDProducer.h" -#include "FWCore/Framework/interface/Run.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Utilities/interface/EDGetToken.h" -#include "FWCore/Utilities/interface/EDPutToken.h" -#include "FWCore/Utilities/interface/ESGetToken.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "DataFormats/Common/interface/Handle.h" - -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" -#include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" -#include "L1Trigger/TrackerTFP/interface/ZHoughTransform.h" - -#include -#include - -using namespace std; -using namespace edm; -using namespace tt; - -namespace trackerTFP { - - /*! \class trackerTFP::ProducerZHT - * \brief L1TrackTrigger r-z Hough Transform emulator - * \author Thomas Schuh - * \date 2021, May - */ - class ProducerZHT : public stream::EDProducer<> { - public: - explicit ProducerZHT(const ParameterSet&); - ~ProducerZHT() override {} - - private: - void beginRun(const Run&, const EventSetup&) override; - void produce(Event&, const EventSetup&) override; - virtual void endJob() {} - - // ED input token of gp stubs - EDGetTokenT edGetToken_; - // ED output token for accepted stubs - EDPutTokenT edPutTokenAccepted_; - // ED output token for lost stubs - EDPutTokenT edPutTokenLost_; - // Setup token - ESGetToken esGetTokenSetup_; - // DataFormats token - ESGetToken esGetTokenDataFormats_; - // configuration - ParameterSet iConfig_; - // helper class to store configurations - const Setup* setup_ = nullptr; - // helper class to extract structured data from tt::Frames - const DataFormats* dataFormats_ = nullptr; - }; - - ProducerZHT::ProducerZHT(const ParameterSet& iConfig) : iConfig_(iConfig) { - const string& label = iConfig.getParameter("LabelMHT"); - const string& branchAccepted = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchLost = iConfig.getParameter("BranchLostStubs"); - // book in- and output ED products - edGetToken_ = consumes(InputTag(label, branchAccepted)); - edPutTokenAccepted_ = produces(branchAccepted); - edPutTokenLost_ = produces(branchLost); - // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); - } - - void ProducerZHT::beginRun(const Run& iRun, const EventSetup& iSetup) { - // helper class to store configurations - setup_ = &iSetup.getData(esGetTokenSetup_); - if (!setup_->configurationSupported()) - return; - // check process history if desired - if (iConfig_.getParameter("CheckHistory")) - setup_->checkHistory(iRun.processHistory()); - // helper class to extract structured data from tt::Frames - dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); - } - - void ProducerZHT::produce(Event& iEvent, const EventSetup& iSetup) { - // empty MHT products - StreamsStub accepted(dataFormats_->numStreams(Process::mht)); - StreamsStub lost(dataFormats_->numStreams(Process::mht)); - // read in HT Product and produce MHT product - if (setup_->configurationSupported()) { - Handle handle; - iEvent.getByToken(edGetToken_, handle); - const StreamsStub& streams = *handle.product(); - for (int region = 0; region < setup_->numRegions(); region++) { - // object to find in a region finer rough candidates in r-phi - ZHoughTransform zht(iConfig_, setup_, dataFormats_, region); - // read in and organize input product - zht.consume(streams); - // fill output products - zht.produce(accepted, lost); - } - } - // store products - iEvent.emplace(edPutTokenAccepted_, std::move(accepted)); - iEvent.emplace(edPutTokenLost_, std::move(lost)); - } - -} // namespace trackerTFP - -DEFINE_FWK_MODULE(trackerTFP::ProducerZHT); diff --git a/L1Trigger/TrackerTFP/plugins/ProducerZHTout.cc b/L1Trigger/TrackerTFP/plugins/ProducerZHTout.cc deleted file mode 100644 index 6abbba845d7fd..0000000000000 --- a/L1Trigger/TrackerTFP/plugins/ProducerZHTout.cc +++ /dev/null @@ -1,135 +0,0 @@ -#include "FWCore/Framework/interface/stream/EDProducer.h" -#include "FWCore/Framework/interface/Run.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Utilities/interface/EDGetToken.h" -#include "FWCore/Utilities/interface/EDPutToken.h" -#include "FWCore/Utilities/interface/ESGetToken.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "DataFormats/Common/interface/Handle.h" - -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" -#include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" - -#include -#include -#include - -using namespace std; -using namespace edm; -using namespace tt; - -namespace trackerTFP { - - /*! \class trackerTFP::ProducerZHTout - * \brief transforms SF output into TTTracks - * \author Thomas Schuh - * \date 2020, July - */ - class ProducerZHTout : public stream::EDProducer<> { - public: - explicit ProducerZHTout(const ParameterSet&); - ~ProducerZHTout() override {} - - private: - void beginRun(const Run&, const EventSetup&) override; - void produce(Event&, const EventSetup&) override; - virtual void endJob() {} - - // ED input token of sf stubs - EDGetTokenT edGetToken_; - // ED output token of TTTracks - EDPutTokenT>> edPutToken_; - // Setup token - ESGetToken esGetTokenSetup_; - // DataFormats token - ESGetToken esGetTokenDataFormats_; - // configuration - ParameterSet iConfig_; - // helper class to store configurations - const Setup* setup_ = nullptr; - // helper class to extract structured data from tt::Frames - const DataFormats* dataFormats_ = nullptr; - }; - - ProducerZHTout::ProducerZHTout(const ParameterSet& iConfig) : iConfig_(iConfig) { - const string& label = iConfig.getParameter("LabelZHT"); - const string& branchAcceptedStubs = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchAcceptedTracks = iConfig.getParameter("BranchAcceptedTracks"); - // book in- and output ED products - edGetToken_ = consumes(InputTag(label, branchAcceptedStubs)); - edPutToken_ = produces>>(branchAcceptedTracks); - // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); - } - - void ProducerZHTout::beginRun(const Run& iRun, const EventSetup& iSetup) { - // helper class to store configurations - setup_ = &iSetup.getData(esGetTokenSetup_); - if (!setup_->configurationSupported()) - return; - // check process history if desired - if (iConfig_.getParameter("CheckHistory")) - setup_->checkHistory(iRun.processHistory()); - // helper class to extract structured data from tt::Frames - dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); - } - - void ProducerZHTout::produce(Event& iEvent, const EventSetup& iSetup) { - const DataFormat& dfCot = dataFormats_->format(Variable::cot, Process::zht); - const DataFormat& dfZT = dataFormats_->format(Variable::zT, Process::zht); - const DataFormat& dfPhiT = dataFormats_->format(Variable::phiT, Process::zht); - const DataFormat& dfinv2R = dataFormats_->format(Variable::inv2R, Process::zht); - // empty SFout product - deque> ttTracks; - // read in SF Product and produce SFout product - if (setup_->configurationSupported()) { - Handle handle; - iEvent.getByToken(edGetToken_, handle); - const StreamsStub& streams = *handle.product(); - for (int region = 0; region < setup_->numRegions(); region++) { - for (int channel = 0; channel < dataFormats_->numChannel(Process::zht); channel++) { - const int index = region * dataFormats_->numChannel(Process::zht) + channel; - // convert stream to stubs - const StreamStub& stream = streams[index]; - vector stubs; - stubs.reserve(stream.size()); - for (const FrameStub& frame : stream) - if (frame.first.isNonnull()) - stubs.emplace_back(frame, dataFormats_); - // form tracks - int i(0); - for (auto it = stubs.begin(); it != stubs.end();) { - const auto start = it; - const int id = it->trackId(); - auto different = [id](const StubZHT& stub) { return id != stub.trackId(); }; - it = find_if(it, stubs.end(), different); - vector ttStubRefs; - ttStubRefs.reserve(distance(start, it)); - transform(start, it, back_inserter(ttStubRefs), [](const StubZHT& stub) { return stub.ttStubRef(); }); - const double zT = dfZT.floating(start->zT()); - const double cot = dfCot.floating(start->cot()); - const double phiT = dfPhiT.floating(start->phiT()); - const double inv2R = dfinv2R.floating(start->inv2R()); - ttTracks.emplace_back(inv2R, phiT, cot, zT, 0., 0., 0., 0., 0., 0, 0, 0.); - ttTracks.back().setStubRefs(ttStubRefs); - ttTracks.back().setPhiSector(start->sectorPhi() + region * setup_->numSectorsPhi()); - ttTracks.back().setEtaSector(start->sectorEta()); - ttTracks.back().setTrackSeedType(start->trackId()); - if (i++ == setup_->zhtMaxTracks()) - break; - } - } - } - } - // store product - iEvent.emplace(edPutToken_, ttTracks.begin(), ttTracks.end()); - } - -} // namespace trackerTFP - -DEFINE_FWK_MODULE(trackerTFP::ProducerZHTout); diff --git a/L1Trigger/TrackerTFP/python/Analyzer_cff.py b/L1Trigger/TrackerTFP/python/Analyzer_cff.py index 8ecacab35aede..fbc9959e108d9 100644 --- a/L1Trigger/TrackerTFP/python/Analyzer_cff.py +++ b/L1Trigger/TrackerTFP/python/Analyzer_cff.py @@ -1,12 +1,14 @@ +# EDAnalyzer for Track Trigger emulation steps + import FWCore.ParameterSet.Config as cms from L1Trigger.TrackerTFP.Analyzer_cfi import TrackerTFPAnalyzer_params from L1Trigger.TrackerTFP.Producer_cfi import TrackerTFPProducer_params -TrackerTFPAnalyzerGP = cms.EDAnalyzer( 'trackerTFP::AnalyzerGP', TrackerTFPAnalyzer_params, TrackerTFPProducer_params ) -TrackerTFPAnalyzerHT = cms.EDAnalyzer( 'trackerTFP::AnalyzerHT', TrackerTFPAnalyzer_params, TrackerTFPProducer_params ) -TrackerTFPAnalyzerMHT = cms.EDAnalyzer( 'trackerTFP::AnalyzerMHT', TrackerTFPAnalyzer_params, TrackerTFPProducer_params ) -TrackerTFPAnalyzerZHT = cms.EDAnalyzer( 'trackerTFP::AnalyzerZHT', TrackerTFPAnalyzer_params, TrackerTFPProducer_params ) -TrackerTFPAnalyzerKFin = cms.EDAnalyzer( 'trackerTFP::AnalyzerKFin', TrackerTFPAnalyzer_params, TrackerTFPProducer_params ) -TrackerTFPAnalyzerKF = cms.EDAnalyzer( 'trackerTFP::AnalyzerKF', TrackerTFPAnalyzer_params, TrackerTFPProducer_params ) -TrackerTFPAnalyzerTT = cms.EDAnalyzer( 'trackerTFP::AnalyzerTT', TrackerTFPAnalyzer_params, TrackerTFPProducer_params ) +AnalyzerGP = cms.EDAnalyzer( 'trackerTFP::AnalyzerGP' , TrackerTFPAnalyzer_params, TrackerTFPProducer_params ) +AnalyzerHT = cms.EDAnalyzer( 'trackerTFP::AnalyzerHT' , TrackerTFPAnalyzer_params, TrackerTFPProducer_params ) +AnalyzerCTB = cms.EDAnalyzer( 'trackerTFP::AnalyzerCTB', TrackerTFPAnalyzer_params, TrackerTFPProducer_params ) +AnalyzerKF = cms.EDAnalyzer( 'trackerTFP::AnalyzerKF' , TrackerTFPAnalyzer_params, TrackerTFPProducer_params ) +AnalyzerDR = cms.EDAnalyzer( 'trackerTFP::AnalyzerDR' , TrackerTFPAnalyzer_params, TrackerTFPProducer_params ) +AnalyzerTQ = cms.EDAnalyzer( 'trackerTFP::AnalyzerTQ', TrackerTFPAnalyzer_params, TrackerTFPProducer_params ) +AnalyzerTFP = cms.EDAnalyzer( 'trackerTFP::AnalyzerTFP', TrackerTFPAnalyzer_params, TrackerTFPProducer_params ) diff --git a/L1Trigger/TrackerTFP/python/Analyzer_cfi.py b/L1Trigger/TrackerTFP/python/Analyzer_cfi.py index cbcc20fd7b0e8..2c1fe9b588dec 100644 --- a/L1Trigger/TrackerTFP/python/Analyzer_cfi.py +++ b/L1Trigger/TrackerTFP/python/Analyzer_cfi.py @@ -1,3 +1,5 @@ +# configuration for Track Trigger emulation EDAnalyzer + import FWCore.ParameterSet.Config as cms TrackerTFPAnalyzer_params = cms.PSet ( @@ -5,6 +7,12 @@ UseMCTruth = cms.bool( True ), # enables analyze of TPs InputTagReconstructable = cms.InputTag("StubAssociator", "Reconstructable"), # InputTagSelection = cms.InputTag("StubAssociator", "UseForAlgEff"), # - + OutputLabelGP = cms.string( "ProducerGP" ), # + OutputLabelHT = cms.string( "ProducerHT" ), # + OutputLabelCTB = cms.string( "ProducerCTB" ), # + OutputLabelKF = cms.string( "ProducerKF" ), # + OutputLabelDR = cms.string( "ProducerDR" ), # + OutputLabelTQ = cms.string( "ProducerTQ" ), # + OutputLabelTFP = cms.string( "ProducerTFP" ), # ) diff --git a/L1Trigger/TrackerTFP/python/Customize_cff.py b/L1Trigger/TrackerTFP/python/Customize_cff.py index 9baa4073771f7..ece45fd65e045 100644 --- a/L1Trigger/TrackerTFP/python/Customize_cff.py +++ b/L1Trigger/TrackerTFP/python/Customize_cff.py @@ -1,7 +1,27 @@ +# function to alter TrackTriggerSetup to provide TMTT configuration + import FWCore.ParameterSet.Config as cms def setupUseTMTT(process): - process.TrackTriggerDataFormats.UseHybrid = False - process.TrackTriggerSetup.TrackingParticle.MinPt = 3.0 - process.TrackTriggerSetup.Firmware.MaxdPhi = 0.01 - return process + process.TrackTriggerSetup.TMTT.WidthR = 11 # number of bits used for stub r - ChosenRofPhi + process.TrackTriggerSetup.TMTT.WidthPhi = 14 # number of bits used for stub phi w.r.t. phi region centre + process.TrackTriggerSetup.TMTT.WidthZ = 13 # number of bits used for stub z + process.TrackTriggerSetup.TrackFinding.MinPt = 3.0 # min track pt in GeV, also defines region overlap shape + process.TrackTriggerSetup.TrackFinding.MaxEta = 2.4 # cut on stub eta + process.TrackTriggerSetup.TrackFinding.ChosenRofPhi = 67.24 # critical radius defining region overlap shape in cm + process.TrackTriggerSetup.TrackFinding.NumLayers = 8 # TMTT: number of detector layers a reconstructbale particle may cross, reduced to 7, 8th layer almost never corssed + process.TrackTriggerSetup.GeometricProcessor.ChosenRofZ = 57.76 # critical radius defining r-z sector shape in cm + process.TrackTriggerSetup.HoughTransform.MinLayers = 5 # required number of stub layers to form a candidate + process.TrackTriggerSetup.CleanTrackBuilder.MaxStubs = 4 # cut on number of stub per layer for input candidates + process.TrackTriggerSetup.KalmanFilter.NumWorker = 4 # number of kf worker + process.TrackTriggerSetup.KalmanFilter.MaxLayers = 8 # maximum number of layers added to a track + process.TrackTriggerSetup.KalmanFilter.MaxSeedingLayer = 3 # perform seeding in layers 0 to this + process.TrackTriggerSetup.KalmanFilter.MaxGaps = 2 # maximum number of layer gaps allowed during cominatorical track building + process.TrackTriggerSetup.KalmanFilter.ShiftChi20 = 0 # shiting chi2 in r-phi plane by power of two when caliclating chi2 + process.TrackTriggerSetup.KalmanFilter.ShiftChi21 = 0 # shiting chi2 in r-z plane by power of two when caliclating chi2 + process.TrackTriggerSetup.KalmanFilter.CutChi2 = 2.0 # cut on chi2 over degree of freedom + +def simUseTMTT(process): + process.StubAssociator.MinPt = 3.0 # pt cut in GeV + + return process diff --git a/L1Trigger/TrackerTFP/python/DataFormats_cff.py b/L1Trigger/TrackerTFP/python/DataFormats_cff.py new file mode 100644 index 0000000000000..fc8250a827f30 --- /dev/null +++ b/L1Trigger/TrackerTFP/python/DataFormats_cff.py @@ -0,0 +1,5 @@ +# ESProducer to provide and calculate and provide dataformats used by Track Trigger emulator + +import FWCore.ParameterSet.Config as cms + +TrackTriggerDataFormats = cms.ESProducer("trackerTFP::ProducerDataFormats") diff --git a/L1Trigger/TrackerTFP/python/Demonstrator_cff.py b/L1Trigger/TrackerTFP/python/Demonstrator_cff.py index dd963873dad1d..f70ac8eab4dae 100644 --- a/L1Trigger/TrackerTFP/python/Demonstrator_cff.py +++ b/L1Trigger/TrackerTFP/python/Demonstrator_cff.py @@ -1,3 +1,6 @@ +# ESProducer providing the algorithm to run input data through modelsim and to compares results with expected output data +# and EDAnalyzer running the ESProduct produced by above ESProducer + import FWCore.ParameterSet.Config as cms from L1Trigger.TrackerTFP.Demonstrator_cfi import TrackTriggerDemonstrator_params diff --git a/L1Trigger/TrackerTFP/python/Demonstrator_cfi.py b/L1Trigger/TrackerTFP/python/Demonstrator_cfi.py index 720d2bbe1a640..7fc458b9cd7f9 100644 --- a/L1Trigger/TrackerTFP/python/Demonstrator_cfi.py +++ b/L1Trigger/TrackerTFP/python/Demonstrator_cfi.py @@ -1,11 +1,17 @@ -# configuration of Demonstrator. +# configuration of TrackTriggerDemonstrator. import FWCore.ParameterSet.Config as cms +# these parameters a for ModelSim runs of FW TrackTriggerDemonstrator_params = cms.PSet ( - LabelIn = cms.string( "TrackerTFPProducerKFin" ), # - LabelOut = cms.string( "TrackerTFPProducerKF" ), # - DirIPBB = cms.string( "/heplnw039/tschuh/work/proj/kf/" ), # path to ipbb proj area - RunTime = cms.double( 6.0 ) # runtime in us + LabelIn = cms.string( "ProducerCTB" ), # + LabelOut = cms.string( "ProducerKF" ), # + DirIPBB = cms.string( "/heplnw039/tschuh/work/proj/ctbkf/" ), # path to ipbb proj area + RunTime = cms.double( 6.50 ), # runtime in us + + #LinkMappingIn = cms.vint32( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 ), + #LinkMappingOut = cms.vint32( 52, 53, 54, 55, 56, 57, 58, 59, 60 ) + LinkMappingIn = cms.vint32(), + LinkMappingOut = cms.vint32() ) diff --git a/L1Trigger/TrackerTFP/python/KalmanFilterFormats_cff.py b/L1Trigger/TrackerTFP/python/KalmanFilterFormats_cff.py deleted file mode 100644 index 3e0ac34332a90..0000000000000 --- a/L1Trigger/TrackerTFP/python/KalmanFilterFormats_cff.py +++ /dev/null @@ -1,5 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -from L1Trigger.TrackerTFP.KalmanFilterFormats_cfi import TrackTriggerKalmanFilterFormats_params - -TrackTriggerKalmanFilterFormats = cms.ESProducer("trackerTFP::ProducerFormatsKF", TrackTriggerKalmanFilterFormats_params) diff --git a/L1Trigger/TrackerTFP/python/KalmanFilterFormats_cfi.py b/L1Trigger/TrackerTFP/python/KalmanFilterFormats_cfi.py index 4927e9605122c..832eb5d37d317 100644 --- a/L1Trigger/TrackerTFP/python/KalmanFilterFormats_cfi.py +++ b/L1Trigger/TrackerTFP/python/KalmanFilterFormats_cfi.py @@ -1,75 +1,69 @@ +import FWCore.ParameterSet.Config as cms + +TrackTriggerKalmanFilterFormats_params = cms.PSet ( + + EnableIntegerEmulation = cms.bool( True ), # enables emulation of integer calculations + + WidthR00 = cms.int32( 20 ), # number of bits used to represent R00 + WidthR11 = cms.int32( 20 ), # number of bits used to represent R11 + + WidthC00 = cms.int32( 20 ), # number of bits used to represent C00 + WidthC01 = cms.int32( 20 ), # number of bits used to represent C01 + WidthC11 = cms.int32( 20 ), # number of bits used to represent C11 + WidthC22 = cms.int32( 20 ), # number of bits used to represent C22 + WidthC23 = cms.int32( 20 ), # number of bits used to represent C23 + WidthC33 = cms.int32( 20 ), # number of bits used to represent C33 + # configuration of internal KF variable bases which can be shifted by powers of 2 w.r.t. KF output track parameter # TrackerTFPProducer_params.PrintKFDebug printouts unused MSB for each variable, so that one could consider decreasing the basseshift by that amount # numerical instabillity (negative C00, C11, C22, C33) requires smaller baseshifts of related variables (rx, Sxx, Kxx, Rxx, invRxx) # if a variable overflows an Exception will be thrown and the corresponding baseshift needs to be increased. -import FWCore.ParameterSet.Config as cms -TrackTriggerKalmanFilterFormats_params = cms.PSet ( + BaseShiftx0 = cms.int32( 0 ), + BaseShiftx1 = cms.int32( -7 ), + BaseShiftx2 = cms.int32( -1 ), + BaseShiftx3 = cms.int32( -1 ), + + BaseShiftr0 = cms.int32( -8 ), + BaseShiftr1 = cms.int32( 0 ), + + BaseShiftS00 = cms.int32( -4 ), + BaseShiftS01 = cms.int32( -12 ), + BaseShiftS12 = cms.int32( 0 ), + BaseShiftS13 = cms.int32( -1 ), + + BaseShiftR00 = cms.int32( -5 ), + BaseShiftR11 = cms.int32( 6 ), + + BaseShiftInvR00Approx = cms.int32( -30 ), + BaseShiftInvR11Approx = cms.int32( -41 ), + BaseShiftInvR00Cor = cms.int32( -24 ), + BaseShiftInvR11Cor = cms.int32( -24 ), + BaseShiftInvR00 = cms.int32( -30 ), + BaseShiftInvR11 = cms.int32( -41 ), + + BaseShiftS00Shifted = cms.int32( -1 ), + BaseShiftS01Shifted = cms.int32( -7 ), + BaseShiftS12Shifted = cms.int32( 4 ), + BaseShiftS13Shifted = cms.int32( 4 ), - tmtt = cms.PSet ( - BaseShiftx0 = cms.int32( -3 ), - BaseShiftx1 = cms.int32( -9 ), - BaseShiftx2 = cms.int32( 0 ), - BaseShiftx3 = cms.int32( -2 ), - BaseShiftv0 = cms.int32( -6 ), - BaseShiftv1 = cms.int32( 8 ), - BaseShiftr0 = cms.int32( -8 ), - BaseShiftr1 = cms.int32( 0 ), - BaseShiftS00 = cms.int32( -2 ), - BaseShiftS01 = cms.int32( -7 ), - BaseShiftS12 = cms.int32( 3 ), - BaseShiftS13 = cms.int32( 1 ), - BaseShiftK00 = cms.int32( -16 ), - BaseShiftK10 = cms.int32( -22 ), - BaseShiftK21 = cms.int32( -22 ), - BaseShiftK31 = cms.int32( -23 ), - BaseShiftR00 = cms.int32( -5 ), - BaseShiftR11 = cms.int32( 7 ), - BaseShiftInvR00Approx = cms.int32( -26 ), - BaseShiftInvR11Approx = cms.int32( -38 ), - BaseShiftInvR00Cor = cms.int32( -15 ), - BaseShiftInvR11Cor = cms.int32( -15 ), - BaseShiftInvR00 = cms.int32( -24 ), - BaseShiftInvR11 = cms.int32( -33 ), - BaseShiftC00 = cms.int32( 5 ), - BaseShiftC01 = cms.int32( -3 ), - BaseShiftC11 = cms.int32( -7 ), - BaseShiftC22 = cms.int32( 3 ), - BaseShiftC23 = cms.int32( 0 ), - BaseShiftC33 = cms.int32( 1 ) - ), + BaseShiftK00 = cms.int32( -7 ), + BaseShiftK10 = cms.int32( -13 ), + BaseShiftK21 = cms.int32( -13 ), + BaseShiftK31 = cms.int32( -13 ), + + BaseShiftC00 = cms.int32( 6 ), + BaseShiftC01 = cms.int32( 1 ), + BaseShiftC11 = cms.int32( -6 ), + BaseShiftC22 = cms.int32( 5 ), + BaseShiftC23 = cms.int32( 6 ), + BaseShiftC33 = cms.int32( 5 ), - hybrid = cms.PSet ( - BaseShiftx0 = cms.int32( -4 ), - BaseShiftx1 = cms.int32( -10 ), - BaseShiftx2 = cms.int32( -2 ), - BaseShiftx3 = cms.int32( -3 ), - BaseShiftv0 = cms.int32( -4 ), - BaseShiftv1 = cms.int32( 8 ), - BaseShiftr0 = cms.int32( -9 ), - BaseShiftr1 = cms.int32( -1 ), - BaseShiftS00 = cms.int32( 0 ), - BaseShiftS01 = cms.int32( -7 ), - BaseShiftS12 = cms.int32( 3 ), - BaseShiftS13 = cms.int32( 1 ), - BaseShiftK00 = cms.int32( -16 ), - BaseShiftK10 = cms.int32( -22 ), - BaseShiftK21 = cms.int32( -22 ), - BaseShiftK31 = cms.int32( -23 ), - BaseShiftR00 = cms.int32( -4 ), - BaseShiftR11 = cms.int32( 7 ), - BaseShiftInvR00Approx = cms.int32( -27 ), - BaseShiftInvR11Approx = cms.int32( -38 ), - BaseShiftInvR00Cor = cms.int32( -15 ), - BaseShiftInvR11Cor = cms.int32( -15 ), - BaseShiftInvR00 = cms.int32( -23 ), - BaseShiftInvR11 = cms.int32( -33 ), - BaseShiftC00 = cms.int32( 5 ), - BaseShiftC01 = cms.int32( -3 ), - BaseShiftC11 = cms.int32( -7 ), - BaseShiftC22 = cms.int32( 3 ), - BaseShiftC23 = cms.int32( 0 ), - BaseShiftC33 = cms.int32( 1 ) - ), + BaseShiftr0Shifted = cms.int32( 4 ), + BaseShiftr1Shifted = cms.int32( 7 ), + BaseShiftr02 = cms.int32( -1 ), + BaseShiftr12 = cms.int32( 10 ), + BaseShiftchi20 = cms.int32( -10 ), + BaseShiftchi21 = cms.int32( -10 ) ) diff --git a/L1Trigger/TrackerTFP/python/LayerEncoding_cff.py b/L1Trigger/TrackerTFP/python/LayerEncoding_cff.py new file mode 100644 index 0000000000000..9e22ca4651a3a --- /dev/null +++ b/L1Trigger/TrackerTFP/python/LayerEncoding_cff.py @@ -0,0 +1,5 @@ +# ESProducer providing layer id encoding (Layers consitent with rough r-z track parameters are counted from 0 onwards) used by Kalman Filter + +import FWCore.ParameterSet.Config as cms + +TrackTriggerLayerEncoding = cms.ESProducer("trackerTFP::ProducerLayerEncoding") diff --git a/L1Trigger/TrackerTFP/python/ProducerES_cff.py b/L1Trigger/TrackerTFP/python/ProducerES_cff.py deleted file mode 100644 index a10a837ed809f..0000000000000 --- a/L1Trigger/TrackerTFP/python/ProducerES_cff.py +++ /dev/null @@ -1,5 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -from L1Trigger.TrackerTFP.ProducerES_cfi import TrackTriggerDataFormats_params - -TrackTriggerDataFormats = cms.ESProducer("trackerTFP::ProducerES", TrackTriggerDataFormats_params) diff --git a/L1Trigger/TrackerTFP/python/ProducerES_cfi.py b/L1Trigger/TrackerTFP/python/ProducerES_cfi.py deleted file mode 100644 index 069a37dbeb5bc..0000000000000 --- a/L1Trigger/TrackerTFP/python/ProducerES_cfi.py +++ /dev/null @@ -1,28 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -TrackTriggerDataFormats_params = cms.PSet ( - - UseHybrid = cms.bool( True ), - - ZHoughTransform = cms.PSet ( - - NumBinsZT = cms.int32( 2 ), - NumBinsCot = cms.int32( 2 ), - NumStages = cms.int32( 5 ) - - ), - - KalmanFilter = cms.PSet ( - - RangeFactor = cms.double( 2.0 ) # search window of each track parameter in initial uncertainties - - ), - - DuplicateRemoval = cms.PSet ( - WidthPhi0 = cms.int32( 12 ), # number of bist used for phi0 - WidthQoverPt = cms.int32( 15 ), # number of bist used for qOverPt - WidthCot = cms.int32( 16 ), # number of bist used for cot(theta) - WidthZ0 = cms.int32( 12 ) # number of bist used for z0 - ), - -) diff --git a/L1Trigger/TrackerTFP/python/ProducerLayerEncoding_cff.py b/L1Trigger/TrackerTFP/python/ProducerLayerEncoding_cff.py deleted file mode 100644 index 9fbd580d8b4af..0000000000000 --- a/L1Trigger/TrackerTFP/python/ProducerLayerEncoding_cff.py +++ /dev/null @@ -1,5 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -from L1Trigger.TrackerTFP.ProducerLayerEncoding_cfi import TrackTriggerLayerEncoding_params - -TrackTriggerLayerEncoding = cms.ESProducer("trackerTFP::ProducerLayerEncoding", TrackTriggerLayerEncoding_params) diff --git a/L1Trigger/TrackerTFP/python/ProducerLayerEncoding_cfi.py b/L1Trigger/TrackerTFP/python/ProducerLayerEncoding_cfi.py deleted file mode 100644 index 3b098a398a863..0000000000000 --- a/L1Trigger/TrackerTFP/python/ProducerLayerEncoding_cfi.py +++ /dev/null @@ -1,7 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -TrackTriggerLayerEncoding_params = cms.PSet ( - - - -) diff --git a/L1Trigger/TrackerTFP/python/Producer_cff.py b/L1Trigger/TrackerTFP/python/Producer_cff.py index 4276962e6d5f6..2aeaac76fe8e6 100644 --- a/L1Trigger/TrackerTFP/python/Producer_cff.py +++ b/L1Trigger/TrackerTFP/python/Producer_cff.py @@ -1,18 +1,18 @@ # Produce L1 tracks with TMTT C++ emulation import FWCore.ParameterSet.Config as cms -from L1Trigger.TrackTrigger.ProducerSetup_cff import TrackTriggerSetup +from L1Trigger.TrackTrigger.Setup_cff import TrackTriggerSetup from L1Trigger.TrackerTFP.Producer_cfi import TrackerTFPProducer_params -from L1Trigger.TrackerTFP.ProducerES_cff import TrackTriggerDataFormats -from L1Trigger.TrackerTFP.ProducerLayerEncoding_cff import TrackTriggerLayerEncoding -from L1Trigger.TrackerTFP.KalmanFilterFormats_cff import TrackTriggerKalmanFilterFormats +from L1Trigger.TrackerTFP.DataFormats_cff import TrackTriggerDataFormats +from L1Trigger.TrackerTFP.TrackQuality_cff import * +from L1Trigger.TrackerTFP.LayerEncoding_cff import TrackTriggerLayerEncoding +from L1Trigger.TrackerTFP.KalmanFilterFormats_cfi import TrackTriggerKalmanFilterFormats_params -TrackerTFPProducerGP = cms.EDProducer( 'trackerTFP::ProducerGP', TrackerTFPProducer_params ) -TrackerTFPProducerHT = cms.EDProducer( 'trackerTFP::ProducerHT', TrackerTFPProducer_params ) -TrackerTFPProducerMHT = cms.EDProducer( 'trackerTFP::ProducerMHT', TrackerTFPProducer_params ) -TrackerTFPProducerZHT = cms.EDProducer( 'trackerTFP::ProducerZHT', TrackerTFPProducer_params ) -TrackerTFPProducerZHTout = cms.EDProducer( 'trackerTFP::ProducerZHTout', TrackerTFPProducer_params ) -TrackerTFPProducerKFin = cms.EDProducer( 'trackerTFP::ProducerKFin', TrackerTFPProducer_params ) -TrackerTFPProducerKF = cms.EDProducer( 'trackerTFP::ProducerKF', TrackerTFPProducer_params ) -TrackerTFPProducerTT = cms.EDProducer( 'trackerTFP::ProducerTT', TrackerTFPProducer_params ) -TrackerTFPProducerAS = cms.EDProducer( 'trackerTFP::ProducerAS', TrackerTFPProducer_params ) +ProducerPP = cms.EDProducer( 'trackerTFP::ProducerPP' , TrackerTFPProducer_params ) +ProducerGP = cms.EDProducer( 'trackerTFP::ProducerGP' , TrackerTFPProducer_params ) +ProducerHT = cms.EDProducer( 'trackerTFP::ProducerHT' , TrackerTFPProducer_params ) +ProducerCTB = cms.EDProducer( 'trackerTFP::ProducerCTB', TrackerTFPProducer_params ) +ProducerKF = cms.EDProducer( 'trackerTFP::ProducerKF' , TrackerTFPProducer_params, TrackTriggerKalmanFilterFormats_params ) +ProducerDR = cms.EDProducer( 'trackerTFP::ProducerDR' , TrackerTFPProducer_params ) +ProducerTQ = cms.EDProducer( 'trackerTFP::ProducerTQ' , TrackerTFPProducer_params ) +ProducerTFP = cms.EDProducer( 'trackerTFP::ProducerTFP', TrackerTFPProducer_params ) diff --git a/L1Trigger/TrackerTFP/python/Producer_cfi.py b/L1Trigger/TrackerTFP/python/Producer_cfi.py index 351cab0337c78..2177c5205a98f 100644 --- a/L1Trigger/TrackerTFP/python/Producer_cfi.py +++ b/L1Trigger/TrackerTFP/python/Producer_cfi.py @@ -1,24 +1,21 @@ +# configuartion for L1 track Producer + import FWCore.ParameterSet.Config as cms TrackerTFPProducer_params = cms.PSet ( - LabelDTC = cms.string( "TrackerDTCProducer" ), # - LabelGP = cms.string( "TrackerTFPProducerGP" ), # - LabelHT = cms.string( "TrackerTFPProducerHT" ), # - LabelMHT = cms.string( "TrackerTFPProducerMHT" ), # - LabelZHT = cms.string( "TrackerTFPProducerZHT" ), # - LabelZHTout = cms.string( "TrackerTFPProducerZHTout" ), # - LabelKFin = cms.string( "TrackerTFPProducerKFin" ), # - LabelKF = cms.string( "TrackerTFPProducerKF" ), # - LabelDR = cms.string( "TrackerTFPProducerDR" ), # - LabelTT = cms.string( "TrackerTFPProducerTT" ), # - LabelAS = cms.string( "TrackerTFPProducerAS" ), # - BranchAcceptedStubs = cms.string( "StubAccepted" ), # branch for prodcut with passed stubs - BranchAcceptedTracks = cms.string( "TrackAccepted" ), # branch for prodcut with passed tracks - BranchLostStubs = cms.string( "StubLost" ), # branch for prodcut with lost stubs - BranchLostTracks = cms.string( "TracksLost" ), # branch for prodcut with lost tracks - CheckHistory = cms.bool ( False ), # checks if input sample production is configured as current process - EnableTruncation = cms.bool ( True ), # enable emulation of truncation, lost stubs are filled in BranchLost - PrintKFDebug = cms.bool ( False ) # print end job internal unused MSB + InputLabelPP = cms.string( "ProducerDTC" ), # + InputLabelGP = cms.string( "ProducerPP" ), # + InputLabelHT = cms.string( "ProducerGP" ), # + InputLabelCTB = cms.string( "ProducerHT" ), # + InputLabelKF = cms.string( "ProducerCTB" ), # + InputLabelDR = cms.string( "ProducerKF" ), # + InputLabelTQ = cms.string( "ProducerDR" ), # + InputLabelTFP = cms.string( "ProducerTQ" ), # + BranchStubs = cms.string( "StubAccepted" ), # branch for prodcut with passed stubs + BranchTracks = cms.string( "TrackAccepted" ), # branch for prodcut with passed tracks + BranchTTTracks = cms.string( "TrackAccepted" ), # branch for prodcut with passed TTTracks + BranchTruncated = cms.string( "Truncated" ), # branch for truncated prodcuts + PrintKFDebug = cms.bool ( True ) # print end job internal unused MSB ) diff --git a/L1Trigger/TrackerTFP/python/TrackQuality_cff.py b/L1Trigger/TrackerTFP/python/TrackQuality_cff.py new file mode 100644 index 0000000000000..ba3f8d3a9bd2c --- /dev/null +++ b/L1Trigger/TrackerTFP/python/TrackQuality_cff.py @@ -0,0 +1,6 @@ +# ESProducer providing Bit accurate emulation of the track quality BDT + +import FWCore.ParameterSet.Config as cms +from L1Trigger.TrackerTFP.TrackQuality_cfi import TrackQuality_params + +TrackTriggerTrackQuality = cms.ESProducer("trackerTFP::ProducerTrackQuality", TrackQuality_params) diff --git a/L1Trigger/TrackerTFP/python/TrackQuality_cfi.py b/L1Trigger/TrackerTFP/python/TrackQuality_cfi.py new file mode 100644 index 0000000000000..f4b0210124c2d --- /dev/null +++ b/L1Trigger/TrackerTFP/python/TrackQuality_cfi.py @@ -0,0 +1,35 @@ +# configuration of TrackTriggerTrackQuality + +import FWCore.ParameterSet.Config as cms + +TrackQuality_params = cms.PSet( + # This emulation GBDT is optimised for the HYBRID_NEWKF emulation and works with the emulation of the KF out module + # It is compatible with the HYBRID simulation and will give equivilant performance with this workflow + Model = cms.FileInPath( "L1Trigger/TrackTrigger/data/L1_TrackQuality_GBDT_emulation_digitized.json" ), + #Vector of strings of training features, in the order that the model was trained with + FeatureNames = cms.vstring( ["tanl", + "z0_scaled", + "bendchi2_bin", + "nstub", + "nlaymiss_interior", + "chi2rphi_bin", + "chi2rz_bin" + ] ), + BaseShiftCot = cms.int32( -7 ), # + BaseShiftZ0 = cms.int32( -6 ), # + BaseShiftAPfixed = cms.int32( -5 ), # + Chi2rphiConv = cms.int32( 3 ), # Conversion factor between dphi^2/weight and chi2rphi + Chi2rzConv = cms.int32( 13 ), # Conversion factor between dz^2/weight and chi2rz + WeightBinFraction = cms.int32( 0 ), # Number of bits dropped from dphi and dz for v0 and v1 LUTs + DzTruncation = cms.int32( 262144 ), # Constant used in FW to prevent 32-bit int overflow + DphiTruncation = cms.int32( 16 ), # Constant used in FW to prevent 32-bit int overflow + WidthM20 = cms.int32( 16 ), # + WidthM21 = cms.int32( 16 ), # + WidthInvV0 = cms.int32( 16 ), # + WidthInvV1 = cms.int32( 16 ), # + Widthchi2rphi = cms.int32( 20 ), # + Widthchi2rz = cms.int32( 20 ), # + BaseShiftchi2rphi = cms.int32( -6 ), # + BaseShiftchi2rz = cms.int32( -6 ) # + +) diff --git a/L1Trigger/TrackerTFP/src/CleanTrackBuilder.cc b/L1Trigger/TrackerTFP/src/CleanTrackBuilder.cc new file mode 100644 index 0000000000000..850994e068fb0 --- /dev/null +++ b/L1Trigger/TrackerTFP/src/CleanTrackBuilder.cc @@ -0,0 +1,486 @@ +#include "L1Trigger/TrackerTFP/interface/CleanTrackBuilder.h" + +#include +#include +#include +#include +#include +#include + +namespace trackerTFP { + + CleanTrackBuilder::CleanTrackBuilder(const tt::Setup* setup, + const DataFormats* dataFormats, + const LayerEncoding* layerEncoding, + const DataFormat& cot, + std::vector& stubs, + std::vector& tracks) + : setup_(setup), + dataFormats_(dataFormats), + layerEncoding_(layerEncoding), + cot_(cot), + stubsCTB_(stubs), + tracksCTB_(tracks), + r_(dataFormats_->format(Variable::r, Process::ctb)), + phi_(dataFormats_->format(Variable::phi, Process::ctb)), + z_(dataFormats_->format(Variable::z, Process::ctb)), + phiT_(dataFormats_->format(Variable::phiT, Process::ctb)), + zT_(dataFormats_->format(Variable::zT, Process::ctb)) { + stubs_.reserve(stubs.capacity()); + tracks_.reserve(tracks.capacity()); + numChannelOut_ = dataFormats_->numChannel(Process::ctb); + numChannel_ = dataFormats_->numChannel(Process::ht) / numChannelOut_; + numLayers_ = setup_->numLayers(); + wlayer_ = dataFormats_->width(Variable::layer, Process::ctb); + numBinsInv2R_ = setup_->ctbNumBinsInv2R(); + numBinsPhiT_ = setup_->ctbNumBinsPhiT(); + numBinsCot_ = setup_->ctbNumBinsCot(); + numBinsZT_ = setup_->ctbNumBinsZT(); + baseInv2R_ = dataFormats_->base(Variable::inv2R, Process::ctb) / numBinsInv2R_; + basePhiT_ = phiT_.base() / numBinsPhiT_; + baseCot_ = cot_.base(); + baseZT_ = zT_.base() / numBinsZT_; + } + + // fill output products + void CleanTrackBuilder::produce(const std::vector>& streamsIn, + std::vector>& regionTracks, + std::vector>>& regionStubs) { + // loop over worker + for (int channelOut = 0; channelOut < numChannelOut_; channelOut++) { + // clean input tracks + std::vector> streamsT(numChannel_); + std::vector> streamsS(numChannel_); + for (int cin = 0; cin < numChannel_; cin++) { + const int index = numChannel_ * cin + channelOut; + cleanStream(streamsIn[index], streamsT[cin], streamsS[cin], index); + } + // route + std::deque tracks; + std::vector> stubs(numLayers_); + route(streamsT, tracks); + route(streamsS, stubs); + // sort + sort(tracks, stubs); + // convert + std::deque& channelTracks = regionTracks[channelOut]; + std::vector>& channelStubs = regionStubs[channelOut]; + convert(tracks, stubs, channelTracks, channelStubs); + } + } + + // + void CleanTrackBuilder::cleanStream(const std::vector& input, + std::deque& tracks, + std::deque& stubs, + int channelId) { + const DataFormat& dfInv2R = dataFormats_->format(Variable::inv2R, Process::ht); + const double inv2R = dfInv2R.floating(dfInv2R.toSigned(channelId)); + const int offset = channelId * setup_->ctbMaxTracks(); + int trackId = offset; + // identify tracks in input container + int id; + auto toTrkId = [this](StubHT* stub) { + const DataFormat& phiT = dataFormats_->format(Variable::phiT, Process::ht); + const DataFormat& zT = dataFormats_->format(Variable::zT, Process::ht); + return (phiT.ttBV(stub->phiT()) + zT.ttBV(stub->zT())).val(); + }; + auto different = [&id, toTrkId](StubHT* stub) { return id != toTrkId(stub); }; + int delta = -setup_->htMinLayers() + 1; + int old = 0; + for (auto it = input.begin(); it != input.end();) { + id = toTrkId(*it); + const auto start = it; + const auto end = std::find_if(start, input.end(), different); + const std::vector track(start, end); + // restore clock accurancy + delta += track.size() - old; + old = track.size(); + if (delta > 0) { + stubs.insert(stubs.end(), delta, nullptr); + tracks.insert(tracks.end(), delta, nullptr); + delta = 0; + } + // run single track through r-phi and r-z hough transform + cleanTrack(track, tracks, stubs, inv2R, (*start)->zT(), trackId++); + if (trackId - offset == setup_->ctbMaxTracks()) + break; + // set begin of next track + it = end; + } + } + + // run single track through r-phi and r-z hough transform + void CleanTrackBuilder::cleanTrack(const std::vector& track, + std::deque& tracks, + std::deque& stubs, + double inv2R, + int zT, + int trackId) { + const TTBV& maybePattern = layerEncoding_->maybePattern(zT); + auto noTrack = [this, &maybePattern](const TTBV& pattern) { + // not enough seeding layer + if (pattern.count(0, setup_->kfMaxSeedingLayer()) < 2) + return true; + int nHits(0); + int nGaps(0); + bool doubleGap = false; + for (int layer = 0; layer < numLayers_; layer++) { + if (pattern.test(layer)) { + doubleGap = false; + if (++nHits == setup_->ctbMinLayers()) + return false; + } else if (!maybePattern.test(layer)) { + if (++nGaps == setup_->kfMaxGaps() || doubleGap) + break; + doubleGap = true; + } + } + return true; + }; + auto toLayerId = [this](StubHT* stub) { return stub->layer().val(wlayer_); }; + auto toDPhi = [this, inv2R](StubHT* stub) { + const bool barrel = stub->layer()[5]; + const bool ps = stub->layer()[4]; + const bool tilt = stub->layer()[3]; + const double pitchRow = ps ? setup_->pitchRowPS() : setup_->pitchRow2S(); + const double pitchCol = ps ? setup_->pitchColPS() : setup_->pitchCol2S(); + const double pitchColR = barrel ? (tilt ? setup_->tiltUncertaintyR() : 0.0) : pitchCol; + const double r = stub->r() + setup_->chosenRofPhi(); + const double dPhi = pitchRow / r + (setup_->scattering() + pitchColR) * std::abs(inv2R); + return phi_.digi(dPhi / 2.); + }; + auto toDZ = [this](StubHT* stub) { + const double m = setup_->tiltApproxSlope(); + const double c = setup_->tiltApproxIntercept(); + const bool barrel = stub->layer()[5]; + const bool ps = stub->layer()[4]; + const bool tilt = stub->layer()[3]; + const double pitchCol = ps ? setup_->pitchColPS() : setup_->pitchCol2S(); + const double zT = zT_.floating(stub->zT()); + const double cot = std::abs(zT) / setup_->chosenRofZ(); + const double dZ = (barrel ? (tilt ? m * cot + c : 1.) : cot) * pitchCol; + return z_.digi(dZ / 2.); + }; + std::vector tStubs; + tStubs.reserve(track.size()); + std::vector hitPatternPhi(numBinsInv2R_ * numBinsPhiT_, TTBV(0, numLayers_)); + std::vector hitPatternZ(numBinsCot_ * numBinsZT_, TTBV(0, numLayers_)); + TTBV tracksPhi(0, numBinsInv2R_ * numBinsPhiT_); + TTBV tracksZ(0, numBinsCot_ * numBinsZT_); + // identify finer tracks each stub is consistent with + for (StubHT* stub : track) { + const int layerId = toLayerId(stub); + const double dPhi = toDPhi(stub); + const double dZ = toDZ(stub); + // r - phi HT + auto phiT = [stub](double inv2R, double dPhi) { return inv2R * stub->r() + stub->phi() + dPhi; }; + TTBV hitsPhi(0, numBinsInv2R_ * numBinsPhiT_); + for (int binInv2R = 0; binInv2R < numBinsInv2R_; binInv2R++) { + const int offset = binInv2R * numBinsPhiT_; + const double inv2RMin = (binInv2R - numBinsInv2R_ / 2.) * baseInv2R_; + const double inv2RMax = inv2RMin + baseInv2R_; + const auto phiTs = {phiT(inv2RMin, -dPhi), phiT(inv2RMax, -dPhi), phiT(inv2RMin, dPhi), phiT(inv2RMax, dPhi)}; + const int binPhiTMin = + std::floor(*std::min_element(phiTs.begin(), phiTs.end()) / basePhiT_ + 1.e-11) + numBinsPhiT_ / 2; + const int binPhiTMax = + std::floor(*std::max_element(phiTs.begin(), phiTs.end()) / basePhiT_ + 1.e-11) + numBinsPhiT_ / 2; + for (int binPhiT = 0; binPhiT < numBinsPhiT_; binPhiT++) + if (binPhiT >= binPhiTMin && binPhiT <= binPhiTMax) + hitsPhi.set(offset + binPhiT); + } + // check for tracks on the fly + for (int phi : hitsPhi.ids()) { + hitPatternPhi[phi].set(layerId); + if (!noTrack(hitPatternPhi[phi])) + tracksPhi.set(phi); + } + // r - z HT + auto zT = [this, stub](double cot, double dZ) { + const double r = r_.digi(stub->r() + r_.digi(setup_->chosenRofPhi() - setup_->chosenRofZ())); + return cot * r + stub->z() + dZ; + }; + TTBV hitsZ(0, numBinsCot_ * numBinsZT_); + for (int binCot = 0; binCot < numBinsCot_; binCot++) { + const int offset = binCot * numBinsZT_; + const double cotMin = (binCot - numBinsCot_ / 2.) * baseCot_; + const double cotMax = cotMin + baseCot_; + const auto zTs = {zT(cotMin, -dZ), zT(cotMax, -dZ), zT(cotMin, dZ), zT(cotMax, dZ)}; + const int binZTMin = std::floor(*std::min_element(zTs.begin(), zTs.end()) / baseZT_ + 1.e-11) + numBinsZT_ / 2; + const int binZTMax = std::floor(*std::max_element(zTs.begin(), zTs.end()) / baseZT_ + 1.e-11) + numBinsZT_ / 2; + for (int binZT = 0; binZT < numBinsZT_; binZT++) + if (binZT >= binZTMin && binZT <= binZTMax) + hitsZ.set(offset + binZT); + } + // check for tracks on the fly + for (int z : hitsZ.ids()) { + hitPatternZ[z].set(layerId); + if (!noTrack(hitPatternZ[z])) + tracksZ.set(z); + } + // store stubs consistent finer tracks + stubs_.emplace_back(stub, trackId, hitsPhi, hitsZ, layerId, dPhi, dZ); + tStubs.push_back(&stubs_.back()); + } + // clean + tracks.insert(tracks.end(), tStubs.size() - 1, nullptr); + tracks_.emplace_back(setup_, trackId, tracksPhi, tracksZ, tStubs, inv2R); + tracks.push_back(&tracks_.back()); + stubs.insert(stubs.end(), tStubs.begin(), tStubs.end()); + } + + // + void CleanTrackBuilder::Stub::update(const TTBV& phi, const TTBV& z, std::vector& ids, int max) { + auto consistent = [](const TTBV& stub, const TTBV& track) { + for (int id : track.ids()) + if (stub[id]) + return true; + return false; + }; + if (consistent(hitsPhi_, phi) && consistent(hitsZ_, z) && ids[layerId_] < max) + stubId_ = ids[layerId_]++; + else + valid_ = false; + } + + // construct Track from Stubs + CleanTrackBuilder::Track::Track(const tt::Setup* setup, + int trackId, + const TTBV& hitsPhi, + const TTBV& hitsZ, + const std::vector& stubs, + double inv2R) + : valid_(true), stubs_(stubs), trackId_(trackId), hitsPhi_(hitsPhi), hitsZ_(hitsZ), inv2R_(inv2R) { + std::vector stubIds(setup->numLayers(), 0); + for (Stub* stub : stubs_) + stub->update(hitsPhi_, hitsZ_, stubIds, setup->ctbMaxStubs()); + const int nLayer = + std::accumulate(stubIds.begin(), stubIds.end(), 0, [](int sum, int i) { return sum + (i > 0 ? 1 : 0); }); + if (nLayer < setup->ctbMinLayers()) + valid_ = false; + size_ = *std::max_element(stubIds.begin(), stubIds.end()); + } + + // + void CleanTrackBuilder::route(std::vector>& input, std::vector>& outputs) const { + for (int channelOut = 0; channelOut < (int)outputs.size(); channelOut++) { + std::deque& output = outputs[channelOut]; + std::vector> inputs(input); + for (std::deque& stream : inputs) { + for (Stub*& stub : stream) + if (stub && (!stub->valid_ || stub->layerId_ != channelOut)) + stub = nullptr; + for (auto it = stream.end(); it != stream.begin();) + it = (*--it) ? stream.begin() : stream.erase(it); + } + std::vector> stacks(input.size()); + // clock accurate firmware emulation, each while trip describes one clock tick, one stub in and one stub out per tick + while (!std::all_of(inputs.begin(), inputs.end(), [](const std::deque& stubs) { return stubs.empty(); }) || + !std::all_of(stacks.begin(), stacks.end(), [](const std::deque& stubs) { return stubs.empty(); })) { + // fill input fifos + for (int channel = 0; channel < static_cast(input.size()); channel++) { + std::deque& stack = stacks[channel]; + Stub* stub = pop_front(inputs[channel]); + if (stub) { + if (setup_->enableTruncation() && (int)stack.size() == setup_->ctbDepthMemory() - 1) + pop_front(stack); + stack.push_back(stub); + } + } + // merge input fifos to one stream, prioritizing lower input channel over higher channel + bool nothingToRoute(true); + for (int channel = 0; channel < static_cast(input.size()); channel++) { + Stub* stub = pop_front(stacks[channel]); + if (stub) { + nothingToRoute = false; + output.push_back(stub); + break; + } + } + if (nothingToRoute) + output.push_back(nullptr); + } + } + } + + // + void CleanTrackBuilder::route(std::vector>& inputs, std::deque& output) const { + std::vector> stacks(inputs.size()); + // clock accurate firmware emulation, each while trip describes one clock tick, one stub in and one stub out per tick + while (!std::all_of(inputs.begin(), inputs.end(), [](const std::deque& tracks) { + return tracks.empty(); + }) || !std::all_of(stacks.begin(), stacks.end(), [](const std::deque& tracks) { return tracks.empty(); })) { + // fill input fifos + for (int channel = 0; channel < static_cast(inputs.size()); channel++) { + std::deque& stack = stacks[channel]; + Track* track = pop_front(inputs[channel]); + if (track && track->valid_) { + if (setup_->enableTruncation() && static_cast(stack.size()) == setup_->ctbDepthMemory() - 1) + pop_front(stack); + stack.push_back(track); + } + } + // merge input fifos to one stream, prioritizing lower input channel over higher channel + bool nothingToRoute(true); + for (int channel = 0; channel < static_cast(inputs.size()); channel++) { + Track* track = pop_front(stacks[channel]); + if (track) { + nothingToRoute = false; + output.push_back(track); + break; + } + } + if (nothingToRoute) + output.push_back(nullptr); + } + } + + // sort + void CleanTrackBuilder::sort(std::deque& tracks, std::vector>& stubs) const { + // aplly truncation + if (setup_->enableTruncation()) { + if (static_cast(tracks.size()) > setup_->numFramesHigh()) + tracks.resize(setup_->numFramesHigh()); + for (std::deque& stream : stubs) + if (static_cast(stream.size()) > setup_->numFramesHigh()) + stream.resize(setup_->numFramesHigh()); + } + // cycle event, remove all gaps + tracks.erase(std::remove(tracks.begin(), tracks.end(), nullptr), tracks.end()); + for (std::deque& stream : stubs) + stream.erase(std::remove(stream.begin(), stream.end(), nullptr), stream.end()); + // prepare sort according to track id arrival order + std::vector trackIds; + trackIds.reserve(tracks.size()); + std::transform( + tracks.begin(), tracks.end(), std::back_inserter(trackIds), [](Track* track) { return track->trackId_; }); + auto cleaned = [&trackIds](Stub* stub) { + return std::find(trackIds.begin(), trackIds.end(), stub->trackId_) == trackIds.end(); + }; + auto order = [&trackIds](auto lhs, auto rhs) { + const auto l = std::find(trackIds.begin(), trackIds.end(), lhs->trackId_); + const auto r = std::find(trackIds.begin(), trackIds.end(), rhs->trackId_); + return std::distance(r, l) < 0; + }; + for (std::deque& stream : stubs) { + // remove stubs from removed tracks + stream.erase(std::remove_if(stream.begin(), stream.end(), cleaned), stream.end()); + // sort according to stub id on layer + std::stable_sort(stream.begin(), stream.end(), [](Stub* lhs, Stub* rhs) { return lhs->stubId_ < rhs->stubId_; }); + // sort according to track id arrival order + std::stable_sort(stream.begin(), stream.end(), order); + } + // add all gaps + const int size = + std::accumulate(tracks.begin(), tracks.end(), 0, [](int sum, Track* track) { return sum + track->size_; }); + for (int frame = 0; frame < size;) { + const int trackId = tracks[frame]->trackId_; + const int length = tracks[frame]->size_; + tracks.insert(std::next(tracks.begin(), frame + 1), length - 1, nullptr); + for (int layer = 0; layer < numLayers_; layer++) { + std::deque& stream = stubs[layer]; + if (frame >= static_cast(stream.size())) { + stream.insert(stream.end(), length, nullptr); + continue; + } + const auto begin = std::next(stream.begin(), frame); + const auto end = std::find_if(begin, stream.end(), [trackId](Stub* stub) { return stub->trackId_ != trackId; }); + stream.insert(end, length - std::distance(begin, end), nullptr); + } + frame += length; + } + } + + // + void CleanTrackBuilder::convert(const std::deque& iTracks, + const std::vector>& iStubs, + std::deque& oTracks, + std::vector>& oStubs) { + for (int iFrame = 0; iFrame < static_cast(iTracks.size());) { + Track* track = iTracks[iFrame]; + if (!track) { + oTracks.push_back(nullptr); + for (std::deque& stubs : oStubs) + stubs.push_back(nullptr); + iFrame++; + continue; + } + StubHT* s = nullptr; + for (int layer = 0; layer < numLayers_; layer++) { + for (int n = 0; n < track->size_; n++) { + Stub* stub = iStubs[layer][iFrame + n]; + if (!stub) { + oStubs[layer].push_back(nullptr); + continue; + } + s = stub->stubHT_; + const double r = s->r(); + const double phi = s->phi(); + const double z = s->z(); + const double dPhi = stub->dPhi_; + const double dZ = stub->dZ_; + stubsCTB_.emplace_back(*s, r, phi, z, dPhi, dZ); + oStubs[layer].push_back(&stubsCTB_.back()); + } + } + const double inv2R = track->inv2R_; + const double phiT = dataFormats_->format(Variable::phiT, Process::ctb).floating(s->phiT()); + const double zT = dataFormats_->format(Variable::zT, Process::ctb).floating(s->zT()); + tracksCTB_.emplace_back(TTTrackRef(), dataFormats_, inv2R, phiT, zT); + oTracks.push_back(&tracksCTB_.back()); + oTracks.insert(oTracks.end(), track->size_ - 1, nullptr); + iFrame += track->size_; + } + } + + // remove and return first element of deque, returns nullptr if empty + template + T* CleanTrackBuilder::pop_front(std::deque& ts) const { + T* t = nullptr; + if (!ts.empty()) { + t = ts.front(); + ts.pop_front(); + } + return t; + } + + void CleanTrackBuilder::put(TrackCTB* track, + const std::vector>& stubs, + int region, + tt::TTTracks& ttTracks) const { + const double dPhi = dataFormats_->format(Variable::phiT, Process::ctb).range(); + const double invR = -track->inv2R() * 2.; + const double phi0 = tt::deltaPhi(track->phiT() - track->inv2R() * setup_->chosenRofPhi() + region * dPhi); + const double zT = track->zT(); + const double cot = zT / setup_->chosenRofZ(); + TTBV hits(0, numLayers_); + double chi2phi(0.); + double chi2z(0.); + const int nStubs = accumulate( + stubs.begin(), stubs.end(), 0, [](int sum, const std::vector& layer) { return sum += layer.size(); }); + std::vector ttStubRefs; + ttStubRefs.reserve(nStubs); + for (int layer = 0; layer < numLayers_; layer++) { + for (StubCTB* stub : stubs[layer]) { + hits.set(layer); + chi2phi += std::pow(stub->phi(), 2) / pow(stub->dPhi(), 2); + chi2z += std::pow(stub->z(), 2) / pow(stub->dZ(), 2); + ttStubRefs.push_back(stub->frame().first); + } + } + static constexpr int nPar = 4; + static constexpr double d0 = 0.; + static constexpr double z0 = 0; + static constexpr double trkMVA1 = 0.; + static constexpr double trkMVA2 = 0.; + static constexpr double trkMVA3 = 0.; + const int hitPattern = hits.val(); + const double bField = setup_->bField(); + TTTrack ttTrack( + invR, phi0, cot, z0, d0, chi2phi, chi2z, trkMVA1, trkMVA2, trkMVA3, hitPattern, nPar, bField); + ttTrack.setStubRefs(ttStubRefs); + ttTrack.setPhiSector(region); + ttTracks.emplace_back(ttTrack); + } + +} // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/src/DataFormats.cc b/L1Trigger/TrackerTFP/src/DataFormats.cc index d58ba3d15b50b..67261e009ad93 100644 --- a/L1Trigger/TrackerTFP/src/DataFormats.cc +++ b/L1Trigger/TrackerTFP/src/DataFormats.cc @@ -1,5 +1,5 @@ #include "L1Trigger/TrackerTFP/interface/DataFormats.h" -#include "L1Trigger/TrackTrigger/interface/StubPtConsistency.h" +#include "DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h" #include #include @@ -9,24 +9,20 @@ #include #include #include - -using namespace std; -using namespace edm; -using namespace tt; +#include namespace trackerTFP { - // default constructor, trying to needs space as proper constructed object + // default constructor, trying to need space as proper constructed object DataFormats::DataFormats() : numDataFormats_(0), formats_(+Variable::end, std::vector(+Process::end, nullptr)), - numUnusedBitsStubs_(+Process::end, TTBV::S_), - numUnusedBitsTracks_(+Process::end, TTBV::S_), + numUnusedBitsStubs_(+Process::end, TTBV::S_ - 1), + numUnusedBitsTracks_(+Process::end, TTBV::S_ - 1), numChannel_(+Process::end, 0) { setup_ = nullptr; countFormats(); dataFormats_.reserve(numDataFormats_); - numStreams_.reserve(+Process::end); numStreamsStubs_.reserve(+Process::end); numStreamsTracks_.reserve(+Process::end); } @@ -36,15 +32,18 @@ namespace trackerTFP { void DataFormats::countFormats() { if constexpr (config_[+v][+p] == p) numDataFormats_++; - if constexpr (++p != Process::end) - countFormats(); - else if constexpr (++v != Variable::end) - countFormats<++v>(); + constexpr Process nextP = p + 1; + if constexpr (nextP != Process::end) + countFormats(); + else { + constexpr Variable nextV = v + 1; + if constexpr (nextV != Variable::end) + countFormats(); + } } // proper constructor - DataFormats::DataFormats(const ParameterSet& iConfig, const Setup* setup) : DataFormats() { - iConfig_ = iConfig; + DataFormats::DataFormats(const tt::Setup* setup) : DataFormats() { setup_ = setup; fillDataFormats(); for (const Process p : Processes) @@ -57,37 +56,34 @@ namespace trackerTFP { numChannel_[+Process::pp] = setup_->numDTCsPerTFP(); numChannel_[+Process::gp] = setup_->numSectors(); numChannel_[+Process::ht] = setup_->htNumBinsInv2R(); - numChannel_[+Process::mht] = setup_->htNumBinsInv2R(); - numChannel_[+Process::zht] = setup_->htNumBinsInv2R(); - numChannel_[+Process::kfin] = setup_->kfNumWorker() * setup_->numLayers(); + numChannel_[+Process::ctb] = setup_->kfNumWorker(); numChannel_[+Process::kf] = setup_->kfNumWorker(); - transform(numChannel_.begin(), numChannel_.end(), back_inserter(numStreams_), [this](int channel) { - return channel * setup_->numRegions(); - }); - numStreamsStubs_ = numStreams_; - numStreamsStubs_[+Process::kf] = numStreams_[+Process::kfin]; - numStreamsTracks_ = vector(+Process::end, 0); - numStreamsTracks_[+Process::kfin] = numStreams_[+Process::kf]; - numStreamsTracks_[+Process::kf] = numStreams_[+Process::kf]; - // Print digi data format of all variables of any specified algo step - // (Look at DataFormat.h::tracks_ to see variable names). - //for (const Variable v : tracks_[+Process::kf]) { - // const DataFormat& f = format(v, Process::kf); - // cout <<" KF "<< f.base() << " " << f.range() << " " << f.width() << endl; - //} + numChannel_[+Process::dr] = 1; + for (const Process& p : {Process::dtc, Process::pp, Process::gp, Process::ht}) { + numStreamsStubs_.push_back(numChannel_[+p] * setup_->numRegions()); + numStreamsTracks_.push_back(0); + } + for (const Process& p : {Process::ctb, Process::kf, Process::dr}) { + numStreamsTracks_.emplace_back(numChannel_[+p] * setup_->numRegions()); + numStreamsStubs_.emplace_back(numStreamsTracks_.back() * setup_->numLayers()); + } } // constructs data formats of all unique used variables and flavours template void DataFormats::fillDataFormats() { if constexpr (config_[+v][+p] == p) { - dataFormats_.emplace_back(Format(iConfig_, setup_)); + dataFormats_.emplace_back(makeDataFormat(setup_)); fillFormats(); } - if constexpr (++p != Process::end) - fillDataFormats(); - else if constexpr (++v != Variable::end) - fillDataFormats<++v>(); + constexpr Process nextP = p + 1; + if constexpr (nextP != Process::end) + fillDataFormats(); + else { + constexpr Variable nextV = v + 1; + if constexpr (nextV != Variable::end) + fillDataFormats(); + } } // helper (loop) data formats of all unique used variables and flavours @@ -96,807 +92,240 @@ namespace trackerTFP { if (config_[+v][+it] == p) { formats_[+v][+it] = &dataFormats_.back(); } - if constexpr (++it != Process::end) - fillFormats(); - } - - // converts bits to ntuple of variables - template - void DataFormats::convertStub(Process p, const Frame& bv, tuple& data) const { - TTBV ttBV(bv); - extractStub(p, ttBV, data); - } - - // helper (loop) to convert bits to ntuple of variables - template - void DataFormats::extractStub(Process p, TTBV& ttBV, std::tuple& data) const { - Variable v = *next(stubs_[+p].begin(), sizeof...(Ts) - 1 - it); - formats_[+v][+p]->extract(ttBV, get(data)); - if constexpr (it + 1 != sizeof...(Ts)) - extractStub(p, ttBV, data); - } - - // converts ntuple of variables to bits - template - void DataFormats::convertStub(Process p, const std::tuple& data, Frame& bv) const { - TTBV ttBV(1, numUnusedBitsStubs_[+p]); - attachStub(p, data, ttBV); - bv = ttBV.bs(); - } - - // helper (loop) to convert ntuple of variables to bits - template - void DataFormats::attachStub(Process p, const tuple& data, TTBV& ttBV) const { - Variable v = *next(stubs_[+p].begin(), it); - formats_[+v][+p]->attach(get(data), ttBV); - if constexpr (it + 1 != sizeof...(Ts)) - attachStub(p, data, ttBV); - } - - // converts bits to ntuple of variables - template - void DataFormats::convertTrack(Process p, const Frame& bv, tuple& data) const { - TTBV ttBV(bv); - extractTrack(p, ttBV, data); - } - - // helper (loop) to convert bits to ntuple of variables - template - void DataFormats::extractTrack(Process p, TTBV& ttBV, std::tuple& data) const { - Variable v = *next(tracks_[+p].begin(), sizeof...(Ts) - 1 - it); - formats_[+v][+p]->extract(ttBV, get(data)); - if constexpr (it + 1 != sizeof...(Ts)) - extractTrack(p, ttBV, data); - } - - // converts ntuple of variables to bits - template - void DataFormats::convertTrack(Process p, const std::tuple& data, Frame& bv) const { - TTBV ttBV(1, numUnusedBitsTracks_[+p]); - attachTrack(p, data, ttBV); - bv = ttBV.bs(); - } - - // helper (loop) to convert ntuple of variables to bits - template - void DataFormats::attachTrack(Process p, const tuple& data, TTBV& ttBV) const { - Variable v = *next(tracks_[+p].begin(), it); - formats_[+v][+p]->attach(get(data), ttBV); - if constexpr (it + 1 != sizeof...(Ts)) - attachTrack(p, data, ttBV); - } - - // construct Stub from Frame - template - Stub::Stub(const FrameStub& frame, const DataFormats* dataFormats, Process p) - : dataFormats_(dataFormats), p_(p), frame_(frame), trackId_(0) { - dataFormats_->convertStub(p, frame.second, data_); - } - - // construct Stub from other Stub - template - template - Stub::Stub(const Stub& stub, Ts... data) - : dataFormats_(stub.dataFormats()), - p_(++stub.p()), - frame_(stub.frame().first, Frame()), - data_(data...), - trackId_(0) {} - - // construct Stub from TTStubRef - template - Stub::Stub(const TTStubRef& ttStubRef, const DataFormats* dataFormats, Process p, Ts... data) - : dataFormats_(dataFormats), p_(p), frame_(ttStubRef, Frame()), data_(data...), trackId_(0) {} - - // construct StubPP from Frame - StubPP::StubPP(const FrameStub& frame, const DataFormats* formats) : Stub(frame, formats, Process::pp) { - for (int sectorEta = sectorEtaMin(); sectorEta <= sectorEtaMax(); sectorEta++) - for (int sectorPhi = 0; sectorPhi < width(Variable::sectorsPhi); sectorPhi++) - sectors_[sectorEta * width(Variable::sectorsPhi) + sectorPhi] = sectorsPhi()[sectorPhi]; - } - - // construct StubGP from Frame - StubGP::StubGP(const FrameStub& frame, const DataFormats* formats, int sectorPhi, int sectorEta) - : Stub(frame, formats, Process::gp), sectorPhi_(sectorPhi), sectorEta_(sectorEta) { - const Setup* setup = dataFormats_->setup(); - inv2RBins_ = TTBV(0, setup->htNumBinsInv2R()); - for (int inv2R = inv2RMin(); inv2R <= inv2RMax(); inv2R++) - inv2RBins_.set(inv2R + inv2RBins_.size() / 2); - } - - // construct StubGP from StubPP - StubGP::StubGP(const StubPP& stub, int sectorPhi, int sectorEta) - : Stub(stub, stub.r(), stub.phi(), stub.z(), stub.layer(), stub.inv2RMin(), stub.inv2RMax()), - sectorPhi_(sectorPhi), - sectorEta_(sectorEta) { - const Setup* setup = dataFormats_->setup(); - get<1>(data_) -= (sectorPhi_ - .5) * setup->baseSector(); - get<2>(data_) -= (r() + dataFormats_->chosenRofPhi()) * setup->sectorCot(sectorEta_); - dataFormats_->convertStub(p_, data_, frame_.second); - } - - // construct StubHT from Frame - StubHT::StubHT(const FrameStub& frame, const DataFormats* formats, int inv2R) - : Stub(frame, formats, Process::ht), inv2R_(inv2R) { - fillTrackId(); - } - - // construct StubHT from StubGP and HT cell assignment - StubHT::StubHT(const StubGP& stub, int phiT, int inv2R) - : Stub(stub, stub.r(), stub.phi(), stub.z(), stub.layer(), stub.sectorPhi(), stub.sectorEta(), phiT), - inv2R_(inv2R) { - get<1>(data_) -= - format(Variable::inv2R).floating(this->inv2R()) * r() + format(Variable::phiT).floating(this->phiT()); - fillTrackId(); - dataFormats_->convertStub(p_, data_, frame_.second); - } - - void StubHT::fillTrackId() { - TTBV ttBV(bv()); - trackId_ = ttBV.extract(width(Variable::sectorPhi) + width(Variable::sectorEta) + width(Variable::phiT)); - } - - // construct StubMHT from Frame - StubMHT::StubMHT(const FrameStub& frame, const DataFormats* formats) : Stub(frame, formats, Process::mht) { - fillTrackId(); - } - - // construct StubMHT from StubHT and MHT cell assignment - StubMHT::StubMHT(const StubHT& stub, int phiT, int inv2R) - : Stub(stub, - stub.r(), - stub.phi(), - stub.z(), - stub.layer(), - stub.sectorPhi(), - stub.sectorEta(), - stub.phiT(), - stub.inv2R()) { - const Setup* setup = dataFormats_->setup(); - // update track (phIT, inv2R), and phi residuals w.r.t. track, to reflect MHT cell assignment. - get<6>(data_) = this->phiT() * setup->mhtNumBinsPhiT() + phiT; - get<7>(data_) = this->inv2R() * setup->mhtNumBinsInv2R() + inv2R; - get<1>(data_) -= base(Variable::inv2R) * (inv2R - .5) * r() + base(Variable::phiT) * (phiT - .5); - dataFormats_->convertStub(p_, data_, frame_.second); - fillTrackId(); - } - - // fills track id - void StubMHT::fillTrackId() { - TTBV ttBV(bv()); - trackId_ = ttBV.extract(width(Variable::sectorPhi) + width(Variable::sectorEta) + width(Variable::phiT) + - width(Variable::inv2R)); - } - - // construct StubZHT from Frame - StubZHT::StubZHT(const FrameStub& frame, const DataFormats* formats) : Stub(frame, formats, Process::zht) { - cot_ = 0.; - zT_ = 0.; - fillTrackId(); - } - - // construct StubZHT from StubMHT - StubZHT::StubZHT(const StubMHT& stub) - : Stub(stub, - stub.r(), - stub.phi(), - stub.z(), - stub.layer(), - stub.sectorPhi(), - stub.sectorEta(), - stub.phiT(), - stub.inv2R(), - 0, - 0) { - cot_ = 0.; - zT_ = 0.; - r_ = format(Variable::r).digi(this->r() + dataFormats_->chosenRofPhi() - dataFormats_->setup()->chosenRofZ()); - chi_ = stub.z(); - trackId_ = stub.trackId(); - } - - // - StubZHT::StubZHT(const StubZHT& stub, double zT, double cot, int id) - : Stub(stub.frame().first, - stub.dataFormats(), - Process::zht, - stub.r(), - stub.phi(), - stub.z(), - stub.layer(), - stub.sectorPhi(), - stub.sectorEta(), - stub.phiT(), - stub.inv2R(), - stub.zT(), - stub.cot()) { - // update track (zT, cot), and phi residuals w.r.t. track, to reflect ZHT cell assignment. - r_ = stub.r_; - cot_ = stub.cotf() + cot; - zT_ = stub.ztf() + zT; - chi_ = stub.z() - zT_ + r_ * cot_; - get<8>(data_) = format(Variable::zT).integer(zT_); - get<9>(data_) = format(Variable::cot).integer(cot_); - dataFormats_->convertStub(p_, data_, frame_.second); - trackId_ = stub.trackId() * 4 + id; - } - - // - StubZHT::StubZHT(const StubZHT& stub, int cot, int zT) - : Stub(stub.frame().first, - stub.dataFormats(), - Process::zht, - stub.r(), - stub.phi(), - 0., - stub.layer(), - stub.sectorPhi(), - stub.sectorEta(), - stub.phiT(), - stub.inv2R(), - zT, - cot) { - get<2>(data_) = - format(Variable::z) - .digi(stub.z() - (format(Variable::zT).floating(zT) - stub.r_ * format(Variable::cot).floating(cot))); - dataFormats_->convertStub(p_, data_, frame_.second); - fillTrackId(); - } - - // fills track id - void StubZHT::fillTrackId() { - TTBV ttBV(bv()); - trackId_ = ttBV.extract(width(Variable::sectorPhi) + width(Variable::sectorEta) + width(Variable::phiT) + - width(Variable::inv2R) + width(Variable::zT) + width(Variable::cot)); - } - - // construct StubKFin from Frame - StubKFin::StubKFin(const FrameStub& frame, const DataFormats* formats, int layer) - : Stub(frame, formats, Process::kfin), layer_(layer) {} - - // construct StubKFin from StubZHT - StubKFin::StubKFin(const StubZHT& stub, double dPhi, double dZ, int layer) - : Stub(stub, stub.r(), stub.phi(), stub.z(), dPhi, dZ), layer_(layer) { - dataFormats_->convertStub(p_, data_, frame_.second); - } - - // construct StubKFin from TTStubRef - StubKFin::StubKFin(const TTStubRef& ttStubRef, - const DataFormats* dataFormats, - double r, - double phi, - double z, - double dPhi, - double dZ, - int layer) - : Stub(ttStubRef, dataFormats, Process::kfin, r, phi, z, dPhi, dZ), layer_(layer) { - dataFormats_->convertStub(p_, data_, frame_.second); - } - - // construct StubKF from Frame - StubKF::StubKF(const FrameStub& frame, const DataFormats* formats, int layer) - : Stub(frame, formats, Process::kf), layer_(layer) {} - - // construct StubKF from StubKFin - StubKF::StubKF(const StubKFin& stub, double inv2R, double phiT, double cot, double zT) - : Stub(stub, stub.r(), 0., 0., stub.dPhi(), stub.dZ()), layer_(stub.layer()) { - const Setup* setup = dataFormats_->setup(); - get<1>(data_) = format(Variable::phi).digi(stub.phi() - (phiT + this->r() * inv2R)); - const double d = - (dataFormats_->hybrid() ? setup->hybridChosenRofPhi() : setup->chosenRofPhi()) - setup->chosenRofZ(); - const double rz = format(Variable::r).digi(this->r() + d); - get<2>(data_) = format(Variable::z).digi(stub.z() - (zT + rz * cot)); - dataFormats_->convertStub(p_, data_, frame_.second); - } - - // construct Track from Frame - template - Track::Track(const FrameTrack& frame, const DataFormats* dataFormats, Process p) - : dataFormats_(dataFormats), p_(p), frame_(frame) { - dataFormats_->convertTrack(p_, frame.second, data_); - } - - // construct Track from other Track - template - template - Track::Track(const Track& track, Ts... data) - : dataFormats_(track.dataFormats()), p_(++track.p()), frame_(track.frame().first, Frame()), data_(data...) {} - - // construct Track from Stub - template - template - Track::Track(const Stub& stub, const TTTrackRef& ttTrackRef, Ts... data) - : dataFormats_(stub.dataFormats()), p_(++stub.p()), frame_(ttTrackRef, Frame()), data_(data...) {} - - // construct Track from TTTrackRef - template - Track::Track(const TTTrackRef& ttTrackRef, const DataFormats* dataFormats, Process p, Ts... data) - : dataFormats_(dataFormats), p_(p), frame_(ttTrackRef, Frame()), data_(data...) {} - - // construct TrackKFin from Frame - TrackKFin::TrackKFin(const FrameTrack& frame, const DataFormats* dataFormats, const vector& stubs) - : Track(frame, dataFormats, Process::kfin), stubs_(setup()->numLayers()), hitPattern_(0, setup()->numLayers()) { - vector nStubs(stubs_.size(), 0); - for (StubKFin* stub : stubs) - nStubs[stub->layer()]++; - for (int layer = 0; layer < dataFormats->setup()->numLayers(); layer++) - stubs_[layer].reserve(nStubs[layer]); - for (StubKFin* stub : stubs) { - const int layer = stub->layer(); - stubs_[layer].push_back(stub); - hitPattern_.set(layer); - } - } - - // construct TrackKFin from StubZHT - TrackKFin::TrackKFin(const StubZHT& stub, const TTTrackRef& ttTrackRef, const TTBV& maybePattern) - : Track(stub, ttTrackRef, maybePattern, stub.sectorPhi(), stub.sectorEta(), 0., 0., 0., 0.), - stubs_(setup()->numLayers()), - hitPattern_(0, setup()->numLayers()) { - get<3>(data_) = format(Variable::phiT, Process::mht).floating(stub.phiT()); - get<4>(data_) = format(Variable::inv2R, Process::mht).floating(stub.inv2R()); - get<5>(data_) = format(Variable::zT, Process::zht).floating(stub.zT()); - get<6>(data_) = format(Variable::cot, Process::zht).floating(stub.cot()); - dataFormats_->convertTrack(p_, data_, frame_.second); - } - - // construct TrackKFin from TTTrackRef - TrackKFin::TrackKFin(const TTTrackRef& ttTrackRef, - const DataFormats* dataFormats, - const TTBV& maybePattern, - double phiT, - double inv2R, - double zT, - double cot, - int sectorPhi, - int sectorEta) - : Track(ttTrackRef, dataFormats, Process::kfin, maybePattern, sectorPhi, sectorEta, phiT, inv2R, zT, cot), - stubs_(setup()->numLayers()), - hitPattern_(0, setup()->numLayers()) { - dataFormats_->convertTrack(p_, data_, frame_.second); - } - - vector TrackKFin::ttStubRefs(const TTBV& hitPattern, const vector& layerMap) const { - vector stubs; - stubs.reserve(hitPattern.count()); - for (int layer = 0; layer < setup()->numLayers(); layer++) - if (hitPattern[layer]) - stubs.push_back(stubs_[layer][layerMap[layer]]->ttStubRef()); - return stubs; - } - - // construct TrackKF from Frame - TrackKF::TrackKF(const FrameTrack& frame, const DataFormats* dataFormats) : Track(frame, dataFormats, Process::kf) {} - - // construct TrackKF from TrackKfin - TrackKF::TrackKF(const TrackKFin& track, double phiT, double inv2R, double zT, double cot) - : Track( - track, false, track.sectorPhi(), track.sectorEta(), track.phiT(), track.inv2R(), track.cot(), track.zT()) { - get<0>(data_) = abs(inv2R) < dataFormats_->format(Variable::inv2R, Process::zht).base() / 2. && - abs(phiT) < dataFormats_->format(Variable::phiT, Process::zht).base() / 2.; - get<3>(data_) += phiT; - get<4>(data_) += inv2R; - get<5>(data_) += cot; - get<6>(data_) += zT; - dataFormats_->convertTrack(p_, data_, frame_.second); - } - - // conversion to TTTrack with given stubs - TTTrack TrackKF::ttTrack(const vector& stubs) const { - const double invR = -this->inv2R() * 2.; - const double phi0 = - deltaPhi(this->phiT() - this->inv2R() * dataFormats_->chosenRofPhi() + - setup()->baseSector() * (this->sectorPhi() - .5) + setup()->baseRegion() * frame_.first->phiSector()); - const double cot = this->cot() + setup()->sectorCot(this->sectorEta()); - const double z0 = this->zT() - this->cot() * setup()->chosenRofZ(); - TTBV hitVector(0, setup()->numLayers()); - double chi2phi(0.); - double chi2z(0.); - vector ttStubRefs; - const int nLayer = stubs.size(); - ttStubRefs.reserve(nLayer); - for (const StubKF& stub : stubs) { - hitVector.set(stub.layer()); - const TTStubRef& ttStubRef = stub.ttStubRef(); - chi2phi += pow(stub.phi(), 2) / setup()->v0(ttStubRef, this->inv2R()); - chi2z += pow(stub.z(), 2) / setup()->v1(ttStubRef, cot); - ttStubRefs.push_back(ttStubRef); - } - static constexpr int nPar = 4; - static constexpr double d0 = 0.; - static constexpr double trkMVA1 = 0.; - static constexpr double trkMVA2 = 0.; - static constexpr double trkMVA3 = 0.; - const int hitPattern = hitVector.val(); - const double bField = setup()->bField(); - TTTrack ttTrack( - invR, phi0, cot, z0, d0, chi2phi, chi2z, trkMVA1, trkMVA2, trkMVA3, hitPattern, nPar, bField); - ttTrack.setStubRefs(ttStubRefs); - ttTrack.setPhiSector(frame_.first->phiSector()); - ttTrack.setEtaSector(this->sectorEta()); - ttTrack.setTrackSeedType(frame_.first->trackSeedType()); - ttTrack.setStubPtConsistency(StubPtConsistency::getConsistency( - ttTrack, setup()->trackerGeometry(), setup()->trackerTopology(), bField, nPar)); - return ttTrack; - } - - // construct TrackDR from Frame - TrackDR::TrackDR(const FrameTrack& frame, const DataFormats* dataFormats) : Track(frame, dataFormats, Process::dr) {} - - // construct TrackDR from TrackKF - TrackDR::TrackDR(const TrackKF& track) : Track(track, 0., 0., 0., 0.) { - get<0>(data_) = track.phiT() + track.inv2R() * dataFormats_->chosenRofPhi() + - dataFormats_->format(Variable::phi, Process::gp).range() * (track.sectorPhi() - .5); - get<1>(data_) = track.inv2R(); - get<2>(data_) = track.zT() - track.cot() * setup()->chosenRofZ(); - get<3>(data_) = track.cot() + setup()->sectorCot(track.sectorEta()); - dataFormats_->convertTrack(p_, data_, frame_.second); - } - - // conversion to TTTrack - TTTrack TrackDR::ttTrack() const { - const double inv2R = this->inv2R(); - const double phi0 = this->phi0(); - const double cot = this->cot(); - const double z0 = this->z0(); - static constexpr double d0 = 0.; - static constexpr double chi2phi = 0.; - static constexpr double chi2z = 0; - static constexpr double trkMVA1 = 0.; - static constexpr double trkMVA2 = 0.; - static constexpr double trkMVA3 = 0.; - static constexpr int hitPattern = 0.; - static constexpr int nPar = 4; - static constexpr double bField = 0.; - const int sectorPhi = frame_.first->phiSector(); - const int sectorEta = frame_.first->etaSector(); - TTTrack ttTrack( - inv2R, phi0, cot, z0, d0, chi2phi, chi2z, trkMVA1, trkMVA2, trkMVA3, hitPattern, nPar, bField); - ttTrack.setPhiSector(sectorPhi); - ttTrack.setEtaSector(sectorEta); - return ttTrack; + constexpr Process nextIt = it + 1; + if constexpr (nextIt != Process::end) + fillFormats(); } template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - range_ = 2. * M_PI / (double)(setup->numRegions() * setup->numSectorsPhi()); - base_ = range_ / (double)setup->htNumBinsPhiT(); - width_ = ceil(log2(setup->htNumBinsPhiT())); + DataFormat makeDataFormat(const tt::Setup* setup) { + const int width = TTTrack_TrackWord::TrackBitWidths::kRinvSize; + const double range = -2. * TTTrack_TrackWord::minRinv; + const double base = range * std::pow(2, -width); + return DataFormat(true, width, base, range); } - template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - const Format ht(iConfig, setup); - range_ = ht.range(); - base_ = ht.base() / setup->mhtNumBinsPhiT(); - width_ = ceil(log2(setup->htNumBinsPhiT() * setup->mhtNumBinsPhiT())); + DataFormat makeDataFormat(const tt::Setup* setup) { + const int width = TTTrack_TrackWord::TrackBitWidths::kPhiSize; + const double range = -2. * TTTrack_TrackWord::minPhi0; + const double base = range * std::pow(2, -width); + return DataFormat(true, width, base, range); } - template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - const double mintPt = iConfig.getParameter("UseHybrid") ? setup->hybridMinPtCand() : setup->minPt(); - range_ = 2. * setup->invPtToDphi() / mintPt; - base_ = range_ / (double)setup->htNumBinsInv2R(); - width_ = ceil(log2(setup->htNumBinsInv2R())); + DataFormat makeDataFormat(const tt::Setup* setup) { + const int width = TTTrack_TrackWord::TrackBitWidths::kTanlSize; + const double range = -2. * TTTrack_TrackWord::minTanl; + const double base = range * std::pow(2, -width); + return DataFormat(true, width, base, range); } - template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - const Format ht(iConfig, setup); - range_ = ht.range(); - base_ = ht.base() / setup->mhtNumBinsInv2R(); - width_ = ceil(log2(setup->htNumBinsInv2R() * setup->mhtNumBinsInv2R())); + DataFormat makeDataFormat(const tt::Setup* setup) { + const int width = TTTrack_TrackWord::TrackBitWidths::kZ0Size; + const double range = -2. * TTTrack_TrackWord::minZ0; + const double base = range * std::pow(2, -width); + return DataFormat(true, width, base, range); } template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - const double chosenRofPhi = - iConfig.getParameter("UseHybrid") ? setup->hybridChosenRofPhi() : setup->chosenRofPhi(); - width_ = setup->tmttWidthR(); - range_ = 2. * max(abs(setup->outerRadius() - chosenRofPhi), abs(setup->innerRadius() - chosenRofPhi)); - const Format phiT(iConfig, setup); - const Format inv2R(iConfig, setup); - base_ = phiT.base() / inv2R.base(); - const int shift = ceil(log2(range_ / base_ / pow(2., width_))); - base_ *= pow(2., shift); + DataFormat makeDataFormat(const tt::Setup* setup) { + const DataFormat phiT = makeDataFormat(setup); + const DataFormat inv2R = makeDataFormat(setup); + const int width = setup->tmttWidthR(); + const double range = 2. * setup->maxRphi(); + const double baseShifted = phiT.base() / inv2R.base(); + const int shift = std::ceil(std::log2(range / baseShifted)) - width; + const double base = baseShifted * std::pow(2., shift); + return DataFormat(true, width, base, range); } - template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - const Format phiT(iConfig, setup); - const Format inv2R(iConfig, setup); - const Format r(iConfig, setup); - range_ = phiT.range() + inv2R.range() * r.base() * pow(2., r.width()) / 4.; - const Format dtc(iConfig, setup); - base_ = dtc.base(); - width_ = ceil(log2(range_ / base_)); + DataFormat makeDataFormat(const tt::Setup* setup) { + const DataFormat phiT = makeDataFormat(setup); + const DataFormat inv2R = makeDataFormat(setup); + const int width = setup->tmttWidthPhi(); + const double range = phiT.range() + inv2R.range() * setup->maxRphi(); + const int shift = std::ceil(std::log2(range / phiT.base())) - width; + const double base = phiT.base() * std::pow(2., shift); + return DataFormat(true, width, base, range); } - template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - width_ = setup->tmttWidthPhi(); - const Format phiT(iConfig, setup); - const Format inv2R(iConfig, setup); - const Format r(iConfig, setup); - range_ = 2. * M_PI / (double)setup->numRegions() + inv2R.range() * r.base() * pow(2., r.width()) / 4.; - const int shift = ceil(log2(range_ / phiT.base() / pow(2., width_))); - base_ = phiT.base() * pow(2., shift); + DataFormat makeDataFormat(const tt::Setup* setup) { + const DataFormat zT = makeDataFormat(setup); + const int width = setup->tmttWidthZ(); + const double range = 2. * setup->halfLength(); + const int shift = std::ceil(std::log2(range / zT.base())) - width; + const double base = zT.base() * std::pow(2., shift); + return DataFormat(true, width, base, range); } - template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - const Format phiT(iConfig, setup); - range_ = 2. * phiT.base(); - const Format gp(iConfig, setup); - base_ = gp.base(); - width_ = ceil(log2(range_ / base_)); + DataFormat makeDataFormat(const tt::Setup* setup) { + const int width = 5; + return DataFormat(false, width, 1., width); } template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - const Format phiT(iConfig, setup); - range_ = 2. * phiT.base(); - const Format ht(iConfig, setup); - base_ = ht.base(); - width_ = ceil(log2(range_ / base_)); + DataFormat makeDataFormat(const tt::Setup* setup) { + const DataFormat phi = makeDataFormat(setup); + const DataFormat inv2R = makeDataFormat(setup); + const DataFormat phiT = makeDataFormat(setup); + const double base = phi.base(); + const double range = phiT.base() + inv2R.range() * setup->maxRphi(); + const int width = std::ceil(std::log2(range / base)); + return DataFormat(true, width, base, range); } - template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - const Format phi(iConfig, setup); - const double rangeFactor = iConfig.getParameter("KalmanFilter").getParameter("RangeFactor"); - range_ = rangeFactor * phi.range(); - base_ = phi.base(); - width_ = ceil(log2(range_ / base_)); + DataFormat makeDataFormat(const tt::Setup* setup) { + const DataFormat z = makeDataFormat(setup); + const DataFormat zT = makeDataFormat(setup); + const double rangeCot = (zT.base() + 2. * setup->beamWindowZ()) / setup->chosenRofZ(); + const double base = z.base(); + const double range = zT.base() + rangeCot * setup->maxRz(); + const int width = std::ceil(std::log2(range / base)); + return DataFormat(true, width, base, range); } - template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - width_ = setup->tmttWidthZ(); - range_ = 2. * setup->halfLength(); - const Format r(iConfig, setup); - const int shift = ceil(log2(range_ / r.base())) - width_; - base_ = r.base() * pow(2., shift); + DataFormat makeDataFormat(const tt::Setup* setup) { + const double range = 2. * M_PI / setup->numRegions(); + const int width = std::ceil(std::log2(setup->gpNumBinsPhiT())); + const double base = range / std::pow(2., width); + return DataFormat(true, width, base, range); } - template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - range_ = setup->neededRangeChiZ(); - const Format dtc(iConfig, setup); - base_ = dtc.base(); - width_ = ceil(log2(range_ / base_)); + DataFormat makeDataFormat(const tt::Setup* setup) { + const double range = 2. * std::sinh(setup->maxEta()) * setup->chosenRofZ(); + const double base = range / setup->gpNumBinsZT(); + const int width = std::ceil(std::log2(setup->gpNumBinsZT())); + return DataFormat(true, width, base, range); } - template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - const int numBinsZT = iConfig.getParameter("ZHoughTransform").getParameter("NumBinsZT"); - const int numStages = iConfig.getParameter("ZHoughTransform").getParameter("NumStages"); - width_ = ceil(log2(pow(numBinsZT, numStages))); - const Format z(iConfig, setup); - range_ = -1.; - for (int eta = 0; eta < setup->numSectorsEta(); eta++) - range_ = max(range_, (sinh(setup->boundarieEta(eta + 1)) - sinh(setup->boundarieEta(eta)))); - range_ *= setup->chosenRofZ(); - const int shift = ceil(log2(range_ / z.base() / pow(2., width_))); - base_ = z.base() * pow(2., shift); + DataFormat makeDataFormat(const tt::Setup* setup) { + const DataFormat zT = makeDataFormat(setup); + const DataFormat r = makeDataFormat(setup); + const int width = setup->widthDSPbb(); + const double range = (zT.range() - zT.base() + 2. * setup->beamWindowZ()) / setup->chosenRofZ(); + const double baseShifted = zT.base() / r.base(); + const int baseShift = std::ceil(std::log2(range / baseShifted)) - width; + const double base = baseShifted * std::pow(2, baseShift); + return DataFormat(true, width, base, range); } - template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - const int numBinsCot = iConfig.getParameter("ZHoughTransform").getParameter("NumBinsCot"); - const int numStages = iConfig.getParameter("ZHoughTransform").getParameter("NumStages"); - width_ = ceil(log2(pow(numBinsCot, numStages))); - const Format zT(iConfig, setup); - range_ = (zT.range() + 2. * setup->beamWindowZ()) / setup->chosenRofZ(); - const int shift = ceil(log2(range_)) - width_; - base_ = pow(2., shift); + DataFormat makeDataFormat(const tt::Setup* setup) { + const int width = 6; + return DataFormat(false, width, 1., width); } template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - const Format zT(iConfig, setup); - const Format cot(iConfig, setup); - const double rangeR = - 2. * max(abs(setup->outerRadius() - setup->chosenRofZ()), abs(setup->innerRadius() - setup->chosenRofZ())); - range_ = zT.base() + cot.base() * rangeR + setup->maxdZ(); - const Format dtc(iConfig, setup); - base_ = dtc.base(); - width_ = ceil(log2(range_ / base_)); - /*const Format z(iConfig, setup); - width_ = z.width(); - range_ = z.range(); - base_ = z.base();*/ + DataFormat makeDataFormat(const tt::Setup* setup) { + const DataFormat phi = makeDataFormat(setup); + const DataFormat phiT = makeDataFormat(setup); + const DataFormat inv2R = makeDataFormat(setup); + const double range = phiT.base() + setup->maxRphi() * inv2R.base(); + const double base = phi.base(); + const int width = std::ceil(std::log2(range / base)); + return DataFormat(true, width, base, range); } - template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - const Format zht(iConfig, setup); - range_ = zht.range() * pow(2, setup->kfinShiftRangeZ()); - base_ = zht.base(); - width_ = ceil(log2(range_ / base_)); + DataFormat makeDataFormat(const tt::Setup* setup) { + const double range = 2. * setup->invPtToDphi() / setup->minPt(); + const double base = range / setup->htNumBinsInv2R(); + const int width = std::ceil(std::log2(setup->htNumBinsInv2R())); + return DataFormat(true, width, base, range); } - - template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - const Format phiT(iConfig, setup); - const Format inv2R(iConfig, setup); - const double chosenRofPhi = - iConfig.getParameter("UseHybrid") ? setup->hybridChosenRofPhi() : setup->chosenRofPhi(); - const double rangeR = 2. * max(abs(setup->outerRadius() - chosenRofPhi), abs(setup->innerRadius() - chosenRofPhi)); - range_ = phiT.base() + inv2R.base() * rangeR + setup->maxdPhi(); - const Format dtc(iConfig, setup); - base_ = dtc.base(); - width_ = ceil(log2(range_ / base_)); - } - - template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - const Format zht(iConfig, setup); - range_ = zht.range() * pow(2, setup->kfinShiftRangePhi()); - base_ = zht.base(); - width_ = ceil(log2(range_ / base_)); - } - - template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - /*const Format z(iConfig, setup); - const double rangeFactor = iConfig.getParameter("KalmanFilter").getParameter("RangeFactor"); - range_ = rangeFactor * z.range(); - base_ = z.base(); - width_ = ceil(log2(range_ / base_));*/ - const Format zT(iConfig, setup); - const Format cot(iConfig, setup); - const double rangeR = - 2. * max(abs(setup->outerRadius() - setup->chosenRofZ()), abs(setup->innerRadius() - setup->chosenRofZ())); - range_ = zT.base() + cot.base() * rangeR + setup->maxdZ(); - const Format dtc(iConfig, setup); - base_ = dtc.base(); - const double rangeFactor = iConfig.getParameter("KalmanFilter").getParameter("RangeFactor"); - range_ *= rangeFactor; - width_ = ceil(log2(range_ / base_)); - } - - template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(false) { - range_ = setup->numLayers(); - width_ = ceil(log2(range_)); - } - - template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) - : DataFormat(false) { - range_ = setup->numSectorsEta(); - width_ = ceil(log2(range_)); - } - template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) - : DataFormat(false) { - range_ = setup->numSectorsPhi(); - width_ = ceil(log2(range_)); + DataFormat makeDataFormat(const tt::Setup* setup) { + const DataFormat phiT = makeDataFormat(setup); + const double range = phiT.range(); + const double base = phiT.base() / setup->htNumBinsPhiT(); + const int width = std::ceil(std::log2(range / base)); + return DataFormat(true, width, base, range); } template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) - : DataFormat(false) { - range_ = setup->numSectorsPhi(); - width_ = setup->numSectorsPhi(); + DataFormat makeDataFormat(const tt::Setup* setup) { + const DataFormat phi = makeDataFormat(setup); + const DataFormat inv2R = makeDataFormat(setup); + const double sigma = setup->pitchRowPS() / 2. / setup->innerRadius(); + const double pt = (setup->pitchCol2S() + setup->scattering()) / 2. * inv2R.range() / 2.; + const double range = sigma + pt; + const double base = phi.base(); + const int width = std::ceil(std::log2(range / base)); + return DataFormat(false, width, base, range); } - - template <> - Format::Format(const edm::ParameterSet& iConfig, const Setup* setup) - : DataFormat(false) { - width_ = 1; - range_ = 1.; - } - - template <> - Format::Format(const edm::ParameterSet& iConfig, const Setup* setup) - : DataFormat(false) { - width_ = setup->numLayers(); - } - - template <> - Format::Format(const edm::ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - const Format inv2R(iConfig, setup); - const Format phiT(iConfig, setup); - const double chosenRofPhi = - iConfig.getParameter("UseHybrid") ? setup->hybridChosenRofPhi() : setup->chosenRofPhi(); - width_ = setup->tfpWidthPhi0(); - range_ = 2. * M_PI / (double)setup->numRegions() + inv2R.range() * chosenRofPhi; - base_ = phiT.base(); - const int shift = ceil(log2(range_ / base_ / pow(2., width_))); - base_ *= pow(2., shift); - } - template <> - Format::Format(const edm::ParameterSet& iConfig, const Setup* setup) - : DataFormat(true) { - const Format inv2R(iConfig, setup); - width_ = setup->tfpWidthInv2R(); - range_ = inv2R.range(); - base_ = inv2R.base(); - const int shift = ceil(log2(range_ / base_ / pow(2., width_))); - base_ *= pow(2., shift); + DataFormat makeDataFormat(const tt::Setup* setup) { + const DataFormat z = makeDataFormat(setup); + const double range = setup->pitchCol2S() / 2. * std::sinh(setup->maxEta()); + const double base = z.base(); + const int width = std::ceil(std::log2(range / base)); + return DataFormat(false, width, base, range); } - template <> - Format::Format(const edm::ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - const Format zT(iConfig, setup); - width_ = setup->tfpWidthZ0(); - range_ = 2. * setup->beamWindowZ(); - base_ = zT.base(); - const int shift = ceil(log2(range_ / base_ / pow(2., width_))); - base_ *= pow(2., shift); + DataFormat makeDataFormat(const tt::Setup* setup) { + const double range = setup->numLayers(); + const int width = std::ceil(std::log2(range)); + return DataFormat(false, width, 1., range); } template <> - Format::Format(const edm::ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - const Format cot(iConfig, setup); - width_ = setup->tfpWidthCot(); - range_ = 2. * setup->maxCot(); - base_ = cot.base(); - const int shift = ceil(log2(range_ / base_ / pow(2., width_))); - base_ *= pow(2., shift); + DataFormat makeDataFormat(const tt::Setup* setup) { + const DataFormat tfp = makeDataFormat(setup); + const DataFormat ht = makeDataFormat(setup); + const double range = ht.range() + 2. * ht.base(); + const double base = ht.base() * std::pow(2., std::floor(std::log2(.5 * tfp.base() / ht.base()))); + const int width = std::ceil(std::log2(range / base)); + return DataFormat(true, width, base, range); } - template <> - Format::Format(const edm::ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - const Format phi0(iConfig, setup); - const Format phiT(iConfig, setup); - const double rangeFactor = iConfig.getParameter("KalmanFilter").getParameter("RangeFactor"); - range_ = rangeFactor * phiT.range(); - base_ = phi0.base(); - width_ = ceil(log2(range_ / base_)); + DataFormat makeDataFormat(const tt::Setup* setup) { + const DataFormat tfp = makeDataFormat(setup); + const DataFormat ht = makeDataFormat(setup); + const double range = ht.range() + 2. * ht.base(); + const double base = ht.base() * std::pow(2., std::floor(std::log2(tfp.base() / ht.base()))); + const int width = std::ceil(std::log2(range / base)); + return DataFormat(true, width, base, range); } - template <> - Format::Format(const edm::ParameterSet& iConfig, const Setup* setup) - : DataFormat(true) { - const Format dr(iConfig, setup); - const Format mht(iConfig, setup); - const double rangeFactor = iConfig.getParameter("KalmanFilter").getParameter("RangeFactor"); - range_ = mht.range() + rangeFactor * mht.base(); - base_ = dr.base(); - width_ = ceil(log2(range_ / base_)); + DataFormat makeDataFormat(const tt::Setup* setup) { + const DataFormat tfp = makeDataFormat(setup); + const DataFormat zT = makeDataFormat(setup); + const DataFormat r = makeDataFormat(setup); + const double range = (zT.base() + 2. * setup->beamWindowZ()) / setup->chosenRofZ(); + const double base = zT.base() / r.base() * std::pow(2., std::floor(std::log2(tfp.base() / zT.base() * r.base()))); + const int width = ceil(log2(range / base)); + return DataFormat(true, width, base, range); } - template <> - Format::Format(const edm::ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - const Format z0(iConfig, setup); - const Format zT(iConfig, setup); - const double rangeFactor = iConfig.getParameter("KalmanFilter").getParameter("RangeFactor"); - range_ = zT.range() + rangeFactor * zT.base(); - base_ = z0.base(); - width_ = ceil(log2(range_ / base_)); + DataFormat makeDataFormat(const tt::Setup* setup) { + const DataFormat tfp = makeDataFormat(setup); + const DataFormat gp = makeDataFormat(setup); + const double range = gp.range(); + const double base = gp.base() * std::pow(2., std::floor(std::log2(tfp.base() / gp.base()))); + const int width = std::ceil(std::log2(range / base)); + return DataFormat(true, width, base, range); } - template <> - Format::Format(const edm::ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - const Format dr(iConfig, setup); - const Format zht(iConfig, setup); - const double rangeFactor = iConfig.getParameter("KalmanFilter").getParameter("RangeFactor"); - range_ = zht.range() + rangeFactor * zht.base(); - base_ = dr.base(); - width_ = ceil(log2(range_ / base_)); + DataFormat makeDataFormat(const tt::Setup* setup) { + const DataFormat phi = makeDataFormat(setup); + const DataFormat phiT = makeDataFormat(setup); + const DataFormat inv2R = makeDataFormat(setup); + const double range = phiT.base() + setup->maxRphi() * inv2R.base(); + const double base = phi.base(); + const int width = std::ceil(std::log2(range / base)); + return DataFormat(true, width, base, range); } - template <> - Format::Format(const edm::ParameterSet& iConfig, const Setup* setup) - : DataFormat(false) { - const Format phi(iConfig, setup); - range_ = setup->maxdPhi(); - base_ = phi.base(); - width_ = ceil(log2(range_ / base_)); + DataFormat makeDataFormat(const tt::Setup* setup) { + const int width = 1; + return DataFormat(false, width, 1., width); } template <> - Format::Format(const edm::ParameterSet& iConfig, const Setup* setup) - : DataFormat(false) { - const Format z(iConfig, setup); - range_ = setup->maxdZ(); - base_ = z.base(); - width_ = ceil(log2(range_ / base_)); + DataFormat makeDataFormat(const tt::Setup* setup) { + const DataFormat kf = makeDataFormat(setup); + const DataFormat zT = makeDataFormat(setup); + const double range = (zT.range() + 2. * setup->beamWindowZ()) / setup->chosenRofZ(); + const double base = kf.base(); + const int width = std::ceil(std::log2(range / base)); + return DataFormat(true, width, base, range); } } // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/src/Demonstrator.cc b/L1Trigger/TrackerTFP/src/Demonstrator.cc index 86a6e5d727246..df90991f150dc 100644 --- a/L1Trigger/TrackerTFP/src/Demonstrator.cc +++ b/L1Trigger/TrackerTFP/src/Demonstrator.cc @@ -1,149 +1,176 @@ #include "L1Trigger/TrackerTFP/interface/Demonstrator.h" #include +#include #include #include #include - -using namespace std; -using namespace edm; -using namespace tt; +#include namespace trackerTFP { - Demonstrator::Demonstrator(const ParameterSet& iConfig, const Setup* setup) - : dirIPBB_(iConfig.getParameter("DirIPBB")), - runTime_(iConfig.getParameter("RunTime")), + Demonstrator::Demonstrator(const Config& iConfig, const tt::Setup* setup) + : dirIPBB_(iConfig.dirIPBB_), + runTime_(iConfig.runTime_), + linkMappingIn_(iConfig.linkMappingIn_), + linkMappingOut_(iConfig.linkMappingOut_), dirIn_(dirIPBB_ + "in.txt"), dirOut_(dirIPBB_ + "out.txt"), dirPre_(dirIPBB_ + "pre.txt"), dirDiff_(dirIPBB_ + "diff.txt"), - numFrames_(setup->numFramesIO()), + numFrames_(setup->numFramesIOHigh()), numFramesInfra_(setup->numFramesInfra()), numRegions_(setup->numRegions()) {} // plays input through modelsim and compares result with output - bool Demonstrator::analyze(const vector>& input, const vector>& output) const { - stringstream ss; + bool Demonstrator::analyze(const std::vector>& input, + const std::vector>& output) const { + // default link mapping + auto linkMapping = + [this](const std::vector& mapC, std::vector& map, const std::vector>& data) { + if (mapC.empty()) { + map.resize(data.size() / numRegions_); + std::iota(map.begin(), map.end(), 0); + } else + map = mapC; + }; // converts input into stringstream - convert(input, ss); + std::stringstream ss; + std::vector map; + linkMapping(linkMappingIn_, map, input); + convert(input, ss, map); // play input through modelsim sim(ss); // converts output into stringstream - convert(output, ss); + map.clear(); + linkMapping(linkMappingOut_, map, output); + convert(output, ss, map); // compares output with modelsim output return compare(ss); } // converts streams of bv into stringstream - void Demonstrator::convert(const vector>& bits, stringstream& ss) const { + void Demonstrator::convert(const std::vector>& bits, + std::stringstream& ss, + const std::vector& mapping) const { // reset ss ss.str(""); ss.clear(); // number of tranceiver in a quad static constexpr int quad = 4; - const int numChannel = bits.size() / numRegions_; - const int voidChannel = numChannel % quad == 0 ? 0 : quad - numChannel % quad; + std::set quads; + for (int channel : mapping) + quads.insert(channel / quad); + std::vector links; + links.reserve(quads.size() * quad); + for (int q : quads) { + const int offset = q * quad; + for (int c = 0; c < quad; c++) + links.push_back(offset + c); + } // start with header - ss << header(numChannel + voidChannel); + ss << header(links); int nFrame(0); // create one packet per region bool first = true; for (int region = 0; region < numRegions_; region++) { - const int offset = region * numChannel; + const int offset = region * mapping.size(); // start with emp 6 frame gap - ss << infraGap(nFrame, numChannel + voidChannel); + ss << infraGap(nFrame, links.size()); for (int frame = 0; frame < numFrames_; frame++) { // write one frame for all channel ss << this->frame(nFrame); - for (int channel = 0; channel < numChannel; channel++) { - const vector& bvs = bits[offset + channel]; - ss << (frame < (int)bvs.size() ? hex(bvs[frame], first) : hex(Frame(), first)); + for (int link : links) { + const auto channel = find(mapping.begin(), mapping.end(), link); + if (channel == mapping.end()) + ss << " 0000 " << std::string(TTBV::S_ / 4, '0'); + else { + const std::vector& bvs = bits[offset + std::distance(mapping.begin(), channel)]; + ss << (frame < static_cast(bvs.size()) ? hex(bvs[frame], first) : hex(tt::Frame(), first)); + } } - for (int channel = 0; channel < voidChannel; channel++) - ss << " 0000 " << string(TTBV::S_ / 4, '0'); - ss << endl; + ss << std::endl; first = false; } } } // plays stringstream through modelsim - void Demonstrator::sim(const stringstream& ss) const { + void Demonstrator::sim(const std::stringstream& ss) const { // write ss to disk - fstream fs; - fs.open(dirIn_.c_str(), fstream::out); + std::fstream fs; + fs.open(dirIn_.c_str(), std::fstream::out); fs << ss.rdbuf(); fs.close(); // run modelsim - stringstream cmd; + std::stringstream cmd; cmd << "cd " << dirIPBB_ << " && ./run_sim -quiet -c work.top -do 'run " << runTime_ << "us' -do 'quit' &> /dev/null"; - system(cmd.str().c_str()); + std::system(cmd.str().c_str()); } // compares stringstream with modelsim output - bool Demonstrator::compare(stringstream& ss) const { + bool Demonstrator::compare(std::stringstream& ss) const { // write ss to disk - fstream fs; - fs.open(dirPre_.c_str(), fstream::out); + std::fstream fs; + fs.open(dirPre_.c_str(), std::fstream::out); fs << ss.rdbuf(); fs.close(); // use linux diff on disk - const string c = "diff " + dirPre_ + " " + dirOut_ + " &> " + dirDiff_; - system(c.c_str()); + const std::string c = "diff " + dirPre_ + " " + dirOut_ + " &> " + dirDiff_; + std::system(c.c_str()); ss.str(""); ss.clear(); // read diff output - fs.open(dirDiff_.c_str(), fstream::in); + fs.open(dirDiff_.c_str(), std::fstream::in); ss << fs.rdbuf(); fs.close(); // count lines, 4 are expected int n(0); - string token; + std::string token; while (getline(ss, token)) n++; return n == 4; } // creates emp file header - string Demonstrator::header(int numLinks) const { - stringstream ss; + std::string Demonstrator::header(const std::vector& links) const { + std::stringstream ss; // file header - ss << "Board CMSSW" << endl - << "Metadata: (strobe,) start of orbit, start of packet, end of packet, valid" << endl - << endl; + ss << "Id: CMSSW" << std::endl + << "Metadata: (strobe,) start of orbit, start of packet, end of packet, valid" << std::endl + << std::endl; // link header ss << " Link "; - for (int link = 0; link < numLinks; link++) - ss << " " << setfill('0') << setw(3) << link << " "; - ss << endl; + for (int link : links) + ss << " " << std::setfill('0') << std::setw(3) << link << " "; + ss << std::endl; return ss.str(); } // creates 6 frame gap between packets - string Demonstrator::infraGap(int& nFrame, int numLinks) const { - stringstream ss; + std::string Demonstrator::infraGap(int& nFrame, int numLinks) const { + std::stringstream ss; for (int gap = 0; gap < numFramesInfra_; gap++) { ss << frame(nFrame); for (int link = 0; link < numLinks; link++) - ss << " 0000 " << string(TTBV::S_ / 4, '0'); - ss << endl; + ss << " 0000 " << std::string(TTBV::S_ / 4, '0'); + ss << std::endl; } return ss.str(); } // creates frame number - string Demonstrator::frame(int& nFrame) const { - stringstream ss; - ss << "Frame " << setfill('0') << setw(4) << nFrame++ << " "; + std::string Demonstrator::frame(int& nFrame) const { + std::stringstream ss; + ss << "Frame " << std::setfill('0') << std::setw(4) << nFrame++ << " "; return ss.str(); } // converts bv into hex - string Demonstrator::hex(const Frame& bv, bool first) const { - stringstream ss; - ss << (first ? " 1001 " : " 0001 ") << setfill('0') << setw(TTBV::S_ / 4) << std::hex << bv.to_ullong(); + std::string Demonstrator::hex(const tt::Frame& bv, bool first) const { + std::stringstream ss; + ss << (first ? " 1001 " : " 0001 ") << std::setfill('0') << std::setw(TTBV::S_ / 4) << std::hex << bv.to_ullong(); return ss.str(); } diff --git a/L1Trigger/TrackerTFP/src/DemonstratorRcd.cc b/L1Trigger/TrackerTFP/src/DemonstratorRcd.cc deleted file mode 100644 index bcc4f439bb8d9..0000000000000 --- a/L1Trigger/TrackerTFP/src/DemonstratorRcd.cc +++ /dev/null @@ -1,4 +0,0 @@ -#include "L1Trigger/TrackerTFP/interface/DemonstratorRcd.h" -#include "FWCore/Framework/interface/eventsetuprecord_registration_macro.h" - -EVENTSETUP_RECORD_REG(trackerTFP::DemonstratorRcd); diff --git a/L1Trigger/TrackerTFP/src/DuplicateRemoval.cc b/L1Trigger/TrackerTFP/src/DuplicateRemoval.cc new file mode 100644 index 0000000000000..4585c3642aab2 --- /dev/null +++ b/L1Trigger/TrackerTFP/src/DuplicateRemoval.cc @@ -0,0 +1,133 @@ +#include "L1Trigger/TrackerTFP/interface/DuplicateRemoval.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace trackerTFP { + + DuplicateRemoval::DuplicateRemoval(const tt::Setup* setup, + const DataFormats* dataFormats, + std::vector& tracks, + std::vector& stubs) + : setup_(setup), dataFormats_(dataFormats), tracks_(tracks), stubs_(stubs) { + numChannel_ = dataFormats_->numChannel(Process::kf); + numLayers_ = setup_->numLayers(); + numInv2R_ = setup_->htNumBinsInv2R() + 2; + numPhiT_ = setup_->htNumBinsPhiT() * setup_->gpNumBinsPhiT(); + numZT_ = setup_->gpNumBinsZT(); + } + + // fill output products + void DuplicateRemoval::produce(const std::vector>& tracksIn, + const std::vector>& stubsIn, + std::vector>& tracksOut, + std::vector>& stubsOut) { + int nTracks(0); + for (const std::vector& tracks : tracksIn) + nTracks += std::accumulate( + tracks.begin(), tracks.end(), 0, [](int sum, TrackKF* track) { return sum + (track ? 1 : 0); }); + std::vector tracks; + tracks.reserve(nTracks); + std::deque stream; + // merge 4 channel to 1 + for (int channel = numChannel_ - 1; channel >= 0; channel--) { + const int offset = channel * numLayers_; + const std::vector& tracksChannel = tracksIn[channel]; + for (int frame = 0; frame < static_cast(tracksChannel.size()); frame++) { + TrackKF* track = tracksChannel[frame]; + if (!track) { + stream.push_back(nullptr); + continue; + } + std::vector stubs; + stubs.reserve(numLayers_); + for (int layer = 0; layer < numLayers_; layer++) + stubs.push_back(stubsIn[offset + layer][frame]); + const bool match = track->match().val(); + const int inv2R = dataFormats_->format(Variable::inv2R, Process::ht).integer(track->inv2R()) + numInv2R_ / 2; + const int phiT = dataFormats_->format(Variable::phiT, Process::ht).integer(track->phiT()) + numPhiT_ / 2; + const int zT = dataFormats_->format(Variable::zT, Process::gp).integer(track->zT()) + numZT_ / 2; + tracks.emplace_back(track, stubs, match, inv2R, phiT, zT); + stream.push_back(&tracks.back()); + } + } + // truncate if desired + if (setup_->enableTruncation() && static_cast(stream.size()) > setup_->numFramesHigh()) { + const auto limit = std::next(stream.begin(), setup_->numFramesHigh()); + stream.erase(limit, stream.end()); + } + // remove duplicates + std::vector killed; + killed.reserve(stream.size()); + std::vector> hits(numZT_, std::vector(numInv2R_, TTBV(0, numPhiT_))); + for (Track*& track : stream) { + if (!track) + continue; + if (track->match_) { + hits[track->zT_][track->inv2R_].set(track->phiT_); + } else { + killed.push_back(track); + track = nullptr; + } + } + // restore duplicates + for (Track* track : killed) { + if (hits[track->zT_][track->inv2R_][track->phiT_]) { + stream.push_back(nullptr); + continue; + } + hits[track->zT_][track->inv2R_].set(track->phiT_); + stream.push_back(track); + } + // truncate + if (setup_->enableTruncation() && static_cast(stream.size()) > setup_->numFramesHigh()) { + const auto limit = std::next(stream.begin(), setup_->numFramesHigh()); + stream.erase(limit, stream.end()); + } + // remove trailing nullptr + for (auto it = stream.end(); it != stream.begin();) + it = (*--it) ? stream.begin() : stream.erase(it); + // convert and store tracks + tracksOut[0].reserve(stream.size()); + for (std::vector& layer : stubsOut) + layer.reserve(stream.size()); + for (Track* track : stream) { + if (!track) { + tracksOut[0].push_back(nullptr); + for (std::vector& layer : stubsOut) + layer.push_back(nullptr); + continue; + } + const DataFormat& gp = dataFormats_->format(Variable::zT, Process::gp); + TrackKF* trackKF = track->track_; + const double inv2R = trackKF->inv2R(); + const double phiT = trackKF->phiT(); + const double zT = trackKF->zT(); + const double cot = trackKF->cot() + gp.digi(zT) / setup_->chosenRofZ(); + tracks_.emplace_back(*trackKF, inv2R, phiT, cot, zT); + tracksOut[0].push_back(&tracks_.back()); + for (int layer = 0; layer < numLayers_; layer++) { + std::vector& layerStubs = stubsOut[layer]; + StubKF* stub = track->stubs_[layer]; + if (!stub) { + layerStubs.push_back(nullptr); + continue; + } + const double r = stub->r(); + const double phi = stub->phi(); + const double z = stub->z(); + const double dPhi = stub->dPhi(); + const double dZ = stub->dZ(); + stubs_.emplace_back(*stub, r, phi, z, dPhi, dZ); + layerStubs.push_back(&stubs_.back()); + } + } + } + +} // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/src/ES_KalmanFilterFormats.cc b/L1Trigger/TrackerTFP/src/ES_KalmanFilterFormats.cc deleted file mode 100644 index f6bd56a4e42b9..0000000000000 --- a/L1Trigger/TrackerTFP/src/ES_KalmanFilterFormats.cc +++ /dev/null @@ -1,4 +0,0 @@ -#include "FWCore/Utilities/interface/typelookup.h" -#include "L1Trigger/TrackerTFP/interface/KalmanFilterFormats.h" - -TYPELOOKUP_DATA_REG(trackerTFP::KalmanFilterFormats); diff --git a/L1Trigger/TrackerTFP/src/ES_TrackQuality.cc b/L1Trigger/TrackerTFP/src/ES_TrackQuality.cc new file mode 100644 index 0000000000000..b591c74b34749 --- /dev/null +++ b/L1Trigger/TrackerTFP/src/ES_TrackQuality.cc @@ -0,0 +1,4 @@ +#include "FWCore/Utilities/interface/typelookup.h" +#include "L1Trigger/TrackerTFP/interface/TrackQuality.h" + +TYPELOOKUP_DATA_REG(trackerTFP::TrackQuality); diff --git a/L1Trigger/TrackerTFP/src/GeometricProcessor.cc b/L1Trigger/TrackerTFP/src/GeometricProcessor.cc index fd0ffaa44a084..01510cdeaa1eb 100644 --- a/L1Trigger/TrackerTFP/src/GeometricProcessor.cc +++ b/L1Trigger/TrackerTFP/src/GeometricProcessor.cc @@ -6,120 +6,113 @@ #include #include -using namespace std; -using namespace edm; -using namespace tt; - namespace trackerTFP { - GeometricProcessor::GeometricProcessor(const ParameterSet& iConfig, - const Setup* setup, + GeometricProcessor::GeometricProcessor(const tt::Setup* setup, const DataFormats* dataFormats, - int region) - : enableTruncation_(iConfig.getParameter("EnableTruncation")), - setup_(setup), - dataFormats_(dataFormats), - region_(region), - input_(dataFormats_->numChannel(Process::gp), vector>(dataFormats_->numChannel(Process::pp))) {} - - // read in and organize input product (fill vector input_) - void GeometricProcessor::consume(const TTDTC& ttDTC) { - auto validFrame = [](int sum, const FrameStub& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); }; - int nStubsPP(0); - for (int channel = 0; channel < dataFormats_->numChannel(Process::pp); channel++) { - const StreamStub& stream = ttDTC.stream(region_, channel); - nStubsPP += accumulate(stream.begin(), stream.end(), 0, validFrame); - } - stubsPP_.reserve(nStubsPP); - for (int channel = 0; channel < dataFormats_->numChannel(Process::pp); channel++) { - for (const FrameStub& frame : ttDTC.stream(region_, channel)) { - StubPP* stub = nullptr; - if (frame.first.isNonnull()) { - stubsPP_.emplace_back(frame, dataFormats_); - stub = &stubsPP_.back(); - } - for (int sector = 0; sector < dataFormats_->numChannel(Process::gp); sector++) - // adding gaps (nullptr) if no stub available or not in sector to emulate f/w - input_[sector][channel].push_back(stub && stub->inSector(sector) ? stub : nullptr); - } - } - // remove all gaps between end and last stub - for (vector>& input : input_) - for (deque& stubs : input) - for (auto it = stubs.end(); it != stubs.begin();) - it = (*--it) ? stubs.begin() : stubs.erase(it); - auto validStub = [](int sum, StubPP* stub) { return sum + (stub ? 1 : 0); }; - int nStubsGP(0); - for (const vector>& sector : input_) - for (const deque& channel : sector) - nStubsGP += accumulate(channel.begin(), channel.end(), 0, validStub); - stubsGP_.reserve(nStubsGP); + const LayerEncoding* layerEncoding, + std::vector& stubs) + : setup_(setup), dataFormats_(dataFormats), layerEncoding_(layerEncoding), stubs_(stubs) { + numChannelIn_ = dataFormats_->numChannel(Process::pp); + numChannelOut_ = dataFormats_->numChannel(Process::gp); } // fill output products - void GeometricProcessor::produce(StreamsStub& accepted, StreamsStub& lost) { - for (int sector = 0; sector < dataFormats_->numChannel(Process::gp); sector++) { - vector>& inputs = input_[sector]; - vector> stacks(dataFormats_->numChannel(Process::pp)); - const int sectorPhi = sector % setup_->numSectorsPhi(); - const int sectorEta = sector / setup_->numSectorsPhi(); - auto size = [](int sum, const deque& stubs) { return sum + stubs.size(); }; - const int nStubs = accumulate(inputs.begin(), inputs.end(), 0, size); - vector acceptedSector; - vector lostSector; - acceptedSector.reserve(nStubs); - lostSector.reserve(nStubs); + void GeometricProcessor::produce(const std::vector>& streamsIn, + std::vector>& streamsOut) { + for (int channelOut = 0; channelOut < numChannelOut_; channelOut++) { + // helper + const int phiT = channelOut % setup_->gpNumBinsPhiT() - setup_->gpNumBinsPhiT() / 2; + const int zT = channelOut / setup_->gpNumBinsPhiT() - setup_->gpNumBinsZT() / 2; + auto valid = [phiT, zT](StubPP* stub) { + const bool phiTValid = stub && phiT >= stub->phiTMin() && phiT <= stub->phiTMax(); + const bool zTValid = stub && zT >= stub->zTMin() && zT <= stub->zTMax(); + return (phiTValid && zTValid) ? stub : nullptr; + }; + // input streams of stubs + std::vector> inputs(numChannelIn_); + for (int channelIn = 0; channelIn < numChannelIn_; channelIn++) { + const std::vector& streamIn = streamsIn[channelIn]; + std::transform(streamIn.begin(), streamIn.end(), std::back_inserter(inputs[channelIn]), valid); + } + // fifo for each stream + std::vector> stacks(streamsIn.size()); + // output stream + std::deque& output = streamsOut[channelOut]; // clock accurate firmware emulation, each while trip describes one clock tick, one stub in and one stub out per tick - while (!all_of(inputs.begin(), inputs.end(), [](const deque& stubs) { return stubs.empty(); }) or - !all_of(stacks.begin(), stacks.end(), [](const deque& stubs) { return stubs.empty(); })) { + while ( + !std::all_of(inputs.begin(), inputs.end(), [](const std::deque& stubs) { return stubs.empty(); }) || + !std::all_of(stacks.begin(), stacks.end(), [](const std::deque& stubs) { return stubs.empty(); })) { // fill input fifos - for (int channel = 0; channel < dataFormats_->numChannel(Process::pp); channel++) { - deque& stack = stacks[channel]; - StubPP* stub = pop_front(inputs[channel]); + for (int channelIn = 0; channelIn < numChannelIn_; channelIn++) { + std::deque& stack = stacks[channelIn]; + StubPP* stub = pop_front(inputs[channelIn]); if (stub) { - stubsGP_.emplace_back(*stub, sectorPhi, sectorEta); - if (enableTruncation_ && (int)stack.size() == setup_->gpDepthMemory() - 1) - lostSector.push_back(pop_front(stack)); - stack.push_back(&stubsGP_.back()); + // convert stub + StubGP* stubGP = produce(*stub, phiT, zT); + // buffer overflow + if (setup_->enableTruncation() && static_cast(stack.size()) == setup_->gpDepthMemory() - 1) + pop_front(stack); + stack.push_back(stubGP); } } // merge input fifos to one stream, prioritizing higher input channel over lower channel bool nothingToRoute(true); - for (int channel = dataFormats_->numChannel(Process::pp) - 1; channel >= 0; channel--) { - StubGP* stub = pop_front(stacks[channel]); + for (int channelIn = 0; channelIn < numChannelIn_; channelIn++) { + StubGP* stub = pop_front(stacks[channelIn]); if (stub) { nothingToRoute = false; - acceptedSector.push_back(stub); + output.push_back(stub); break; } } if (nothingToRoute) - acceptedSector.push_back(nullptr); + output.push_back(nullptr); } // truncate if desired - if (enableTruncation_ && (int)acceptedSector.size() > setup_->numFrames()) { - const auto limit = next(acceptedSector.begin(), setup_->numFrames()); - copy_if(limit, acceptedSector.end(), back_inserter(lostSector), [](const StubGP* stub) { return stub; }); - acceptedSector.erase(limit, acceptedSector.end()); - } + if (setup_->enableTruncation() && static_cast(output.size()) > setup_->numFramesHigh()) + output.resize(setup_->numFramesHigh()); // remove all gaps between end and last stub - for (auto it = acceptedSector.end(); it != acceptedSector.begin();) - it = (*--it) ? acceptedSector.begin() : acceptedSector.erase(it); - // fill products - auto put = [](const vector& stubs, StreamStub& stream) { - auto toFrame = [](StubGP* stub) { return stub ? stub->frame() : FrameStub(); }; - stream.reserve(stubs.size()); - transform(stubs.begin(), stubs.end(), back_inserter(stream), toFrame); - }; - const int index = region_ * dataFormats_->numChannel(Process::gp) + sector; - put(acceptedSector, accepted[index]); - put(lostSector, lost[index]); + for (auto it = output.end(); it != output.begin();) + it = (*--it) ? output.begin() : output.erase(it); } } + // convert stub + StubGP* GeometricProcessor::produce(const StubPP& stub, int phiT, int zT) { + const DataFormat& dfPhiT = dataFormats_->format(Variable::phiT, Process::gp); + const DataFormat& dfZT = dataFormats_->format(Variable::zT, Process::gp); + const DataFormat& dfCot = dataFormats_->format(Variable::cot, Process::gp); + const DataFormat& dfR = dataFormats_->format(Variable::r, Process::gp); + const DataFormat& dfL = dataFormats_->format(Variable::layer, Process::gp); + const double cot = dfCot.digi(dfZT.floating(zT) / setup_->chosenRofZ()); + // determine kf layer id + const std::vector& le = layerEncoding_->layerEncoding(zT); + const int layerId = setup_->layerId(stub.frame().first); + const auto it = std::find(le.begin(), le.end(), layerId); + const int kfLayerId = std::min(static_cast(std::distance(le.begin(), it)), setup_->numLayers() - 1); + // create data fields + const double r = stub.r(); + const double phi = stub.phi() - dfPhiT.floating(phiT); + const double z = stub.z() - (stub.r() + dfR.digi(setup_->chosenRofPhi())) * cot; + TTBV layer(kfLayerId, dfL.width()); + if (stub.layer()[4]) { // barrel + layer.set(5); + if (stub.layer()[3]) // psTilt + layer.set(3); + if (stub.layer().val(3) < 3) // layerId < 3 + layer.set(4); + } else if (stub.layer()[3]) // psTilt + layer.set(4); + const int inv2RMin = stub.inv2RMin(); + const int inv2RMax = stub.inv2RMax(); + stubs_.emplace_back(stub, r, phi, z, layer, inv2RMin, inv2RMax); + return &stubs_.back(); + } + // remove and return first element of deque, returns nullptr if empty template - T* GeometricProcessor::pop_front(deque& ts) const { + T* GeometricProcessor::pop_front(std::deque& ts) const { T* t = nullptr; if (!ts.empty()) { t = ts.front(); diff --git a/L1Trigger/TrackerTFP/src/HoughTransform.cc b/L1Trigger/TrackerTFP/src/HoughTransform.cc index 5995285b06a9c..cbe7f7cfc7808 100644 --- a/L1Trigger/TrackerTFP/src/HoughTransform.cc +++ b/L1Trigger/TrackerTFP/src/HoughTransform.cc @@ -5,204 +5,209 @@ #include #include #include -#include -#include #include -using namespace std; -using namespace edm; -using namespace tt; - namespace trackerTFP { - HoughTransform::HoughTransform(const ParameterSet& iConfig, - const Setup* setup, + HoughTransform::HoughTransform(const tt::Setup* setup, const DataFormats* dataFormats, - int region) - : enableTruncation_(iConfig.getParameter("EnableTruncation")), - setup_(setup), + const LayerEncoding* layerEncoding, + std::vector& stubs) + : setup_(setup), dataFormats_(dataFormats), - inv2R_(dataFormats_->format(Variable::inv2R, Process::ht)), - phiT_(dataFormats_->format(Variable::phiT, Process::ht)), - region_(region), - input_(dataFormats_->numChannel(Process::ht), vector>(dataFormats_->numChannel(Process::gp))) {} - - // read in and organize input product (fill vector input_) - void HoughTransform::consume(const StreamsStub& streams) { - const int offset = region_ * dataFormats_->numChannel(Process::gp); - auto validFrame = [](int sum, const FrameStub& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); }; - int nStubsGP(0); - for (int sector = 0; sector < dataFormats_->numChannel(Process::gp); sector++) { - const StreamStub& stream = streams[offset + sector]; - nStubsGP += accumulate(stream.begin(), stream.end(), 0, validFrame); - } - stubsGP_.reserve(nStubsGP); - for (int sector = 0; sector < dataFormats_->numChannel(Process::gp); sector++) { - const int sectorPhi = sector % setup_->numSectorsPhi(); - const int sectorEta = sector / setup_->numSectorsPhi(); - for (const FrameStub& frame : streams[offset + sector]) { - // Store input stubs in vector, so rest of HT algo can work with pointers to them (saves CPU) - StubGP* stub = nullptr; - if (frame.first.isNonnull()) { - stubsGP_.emplace_back(frame, dataFormats_, sectorPhi, sectorEta); - stub = &stubsGP_.back(); - } - for (int binInv2R = 0; binInv2R < dataFormats_->numChannel(Process::ht); binInv2R++) - input_[binInv2R][sector].push_back(stub && stub->inInv2RBin(binInv2R) ? stub : nullptr); - } - } - // remove all gaps between end and last stub - for (vector>& input : input_) - for (deque& stubs : input) - for (auto it = stubs.end(); it != stubs.begin();) - it = (*--it) ? stubs.begin() : stubs.erase(it); - auto validStub = [](int sum, StubGP* stub) { return sum + (stub ? 1 : 0); }; - int nStubsHT(0); - for (const vector>& binInv2R : input_) - for (const deque& sector : binInv2R) - nStubsHT += accumulate(sector.begin(), sector.end(), 0, validStub); - stubsHT_.reserve(nStubsHT); + layerEncoding_(layerEncoding), + inv2R_(&dataFormats_->format(Variable::inv2R, Process::ht)), + phiT_(&dataFormats_->format(Variable::phiT, Process::ht)), + zT_(&dataFormats_->format(Variable::zT, Process::gp)), + phi_(&dataFormats_->format(Variable::phi, Process::ht)), + z_(&dataFormats_->format(Variable::z, Process::gp)), + stubs_(stubs) { + numChannelIn_ = dataFormats_->numChannel(Process::gp); + numChannelOut_ = dataFormats_->numChannel(Process::ht); + chan_ = setup_->kfNumWorker(); + mux_ = numChannelOut_ / chan_; } // fill output products - void HoughTransform::produce(StreamsStub& accepted, StreamsStub& lost) { - for (int binInv2R = 0; binInv2R < dataFormats_->numChannel(Process::ht); binInv2R++) { - const int inv2R = inv2R_.toSigned(binInv2R); - deque acceptedAll; - deque lostAll; - for (deque& inputSector : input_[binInv2R]) { - const int size = inputSector.size(); - vector acceptedSector; - vector lostSector; - acceptedSector.reserve(size); - lostSector.reserve(size); + void HoughTransform::produce(const std::vector>& streamsIn, + std::vector>& streamsOut) { + // count and reserve ht stubs + auto multiplicity = [](int sum, StubGP* s) { return sum + (s ? 1 + s->inv2RMax() - s->inv2RMin() : 0); }; + int nStubs(0); + for (const std::vector& input : streamsIn) + nStubs += std::accumulate(input.begin(), input.end(), 0, multiplicity); + stubs_.reserve(nStubs); + for (int channelOut = 0; channelOut < numChannelOut_; channelOut++) { + const int inv2Ru = mux_ * (channelOut % chan_) + channelOut / chan_; + const int inv2R = inv2R_->toSigned(inv2Ru); + std::deque& output = streamsOut[channelOut]; + for (int channelIn = numChannelIn_ - 1; channelIn >= 0; channelIn--) { + const std::vector& input = streamsIn[channelIn]; + std::vector stubs; + stubs.reserve(2 * input.size()); // associate stubs with inv2R and phiT bins - fillIn(inv2R, inputSector, acceptedSector, lostSector); - // Process::ht collects all stubs before readout starts -> remove all gaps - acceptedSector.erase(remove(acceptedSector.begin(), acceptedSector.end(), nullptr), acceptedSector.end()); + fillIn(inv2R, channelIn, input, stubs); + // apply truncation + if (setup_->enableTruncation() && static_cast(stubs.size()) > setup_->numFramesHigh()) + stubs.resize(setup_->numFramesHigh()); + // ht collects all stubs before readout starts -> remove all gaps + stubs.erase(std::remove(stubs.begin(), stubs.end(), nullptr), stubs.end()); // identify tracks - readOut(acceptedSector, lostSector, acceptedAll, lostAll); + readOut(stubs, output); } - // truncate accepted stream - const auto limit = enableTruncation_ - ? next(acceptedAll.begin(), min(setup_->numFrames(), (int)acceptedAll.size())) - : acceptedAll.end(); - copy_if(limit, acceptedAll.end(), back_inserter(lostAll), [](StubHT* stub) { return stub; }); - acceptedAll.erase(limit, acceptedAll.end()); - // store found tracks - auto put = [](const deque& stubs, StreamStub& stream) { - stream.reserve(stubs.size()); - for (StubHT* stub : stubs) - stream.emplace_back(stub ? stub->frame() : FrameStub()); - }; - const int offset = region_ * dataFormats_->numChannel(Process::ht); - put(acceptedAll, accepted[offset + binInv2R]); - // store lost tracks - put(lostAll, lost[offset + binInv2R]); + // apply truncation + if (setup_->enableTruncation() && static_cast(output.size()) > setup_->numFramesHigh()) + output.resize(setup_->numFramesHigh()); + // remove trailing gaps + for (auto it = output.end(); it != output.begin();) + it = (*--it) ? output.begin() : output.erase(it); } } // associate stubs with phiT bins in this inv2R column - void HoughTransform::fillIn(int inv2R, - deque& inputSector, - vector& acceptedSector, - vector& lostSector) { + void HoughTransform::fillIn(int inv2R, int sector, const std::vector& input, std::vector& output) { + const DataFormat& gp = dataFormats_->format(Variable::phiT, Process::gp); + auto inv2RrangeCheck = [inv2R](StubGP* stub) { + return (stub && stub->inv2RMin() <= inv2R && stub->inv2RMax() >= inv2R) ? stub : nullptr; + }; + const int gpPhiT = gp.toSigned(sector % setup_->gpNumBinsPhiT()); + const int zT = sector / setup_->gpNumBinsPhiT() - setup_->gpNumBinsZT() / 2; + const double inv2Rf = inv2R_->floating(inv2R); + const double zTf = zT_->floating(zT); + const double cotf = zTf / setup_->chosenRofZ(); + auto convert = [this, inv2Rf, gpPhiT, zT, gp](StubGP* stub, int phiTht, double phi, double z) { + const double phiTf = phiT_->floating(phiTht); + const int phiT = phiT_->integer(gp.floating(gpPhiT) + phiTf); + const double htPhi = phi - (inv2Rf * stub->r() + phiTf); + stubs_.emplace_back(*stub, stub->r(), htPhi, z, stub->layer(), phiT, zT); + return &stubs_.back(); + }; + // Latency of ht fifo firmware + static constexpr int latency = 1; + // static delay container + std::deque delay(latency, nullptr); // fifo, used to store stubs which belongs to a second possible track - deque stack; + std::deque stack; + // stream of incroming stubs + std::deque stream; + std::transform(input.begin(), input.end(), std::back_inserter(stream), inv2RrangeCheck); // clock accurate firmware emulation, each while trip describes one clock tick, one stub in and one stub out per tick - while (!inputSector.empty() || !stack.empty()) { + while (!stream.empty() || !stack.empty() || + !std::all_of(delay.begin(), delay.end(), [](const StubHT* stub) { return !stub; })) { StubHT* stubHT = nullptr; - StubGP* stubGP = pop_front(inputSector); + StubGP* stubGP = pop_front(stream); if (stubGP) { - const double phiT = stubGP->phi() - inv2R_.floating(inv2R) * stubGP->r(); - const int major = phiT_.integer(phiT); - if (phiT_.inRange(major)) { + double phi = stubGP->phi(); + double z = stubGP->z(); + if (false) { + const double d = inv2Rf * (stubGP->r() + setup_->chosenRofPhi()); + const double dPhi = asin(d) - d; + const double dZ = dPhi / inv2Rf * cotf; + phi = phi_->digi(phi - dPhi); + z = z_->digi(z - dZ); + } + const double phiT = phi - inv2Rf * stubGP->r(); + const int major = phiT_->integer(phiT); + if (major >= -setup_->htNumBinsPhiT() / 2 && major < setup_->htNumBinsPhiT() / 2) { // major candidate has pt > threshold (3 GeV) - // stubHT records which HT bin this stub is added to - stubsHT_.emplace_back(*stubGP, major, inv2R); - stubHT = &stubsHT_.back(); + stubHT = convert(stubGP, major, phi, z); } - const double chi = phiT - phiT_.floating(major); - if (abs(stubGP->r() * inv2R_.base()) + 2. * abs(chi) >= phiT_.base()) { + const double chi = phi_->digi(phiT - phiT_->floating(major)); + if (abs(stubGP->r() * inv2R_->base()) + 2. * abs(chi) >= phiT_->base()) { // stub belongs to two candidates const int minor = chi >= 0. ? major + 1 : major - 1; - if (phiT_.inRange(minor)) { + if (minor >= -setup_->htNumBinsPhiT() / 2 && minor < setup_->htNumBinsPhiT() / 2) { // second (minor) candidate has pt > threshold (3 GeV) - stubsHT_.emplace_back(*stubGP, minor, inv2R); - if (enableTruncation_ && (int)stack.size() == setup_->htDepthMemory() - 1) - // buffer overflow - lostSector.push_back(pop_front(stack)); - // store minor stub in fifo - stack.push_back(&stubsHT_.back()); + StubHT* stub = convert(stubGP, minor, phi, z); + delay.push_back(stub); } } } + // add nullptr to delay pipe if stub didn't fill any cell + if (static_cast(delay.size()) == latency) + delay.push_back(nullptr); + // take fifo latency into account (read before write) + StubHT* stub = pop_front(delay); + if (stub) { + // buffer overflow + if (setup_->enableTruncation() && static_cast(stack.size()) == setup_->htDepthMemory() - 1) + pop_front(stack); + // store minor stub in fifo + stack.push_back(stub); + } // take a minor stub if no major stub available - acceptedSector.push_back(stubHT ? stubHT : pop_front(stack)); + output.push_back(stubHT ? stubHT : pop_front(stack)); } - // truncate to many input stubs - const auto limit = enableTruncation_ - ? next(acceptedSector.begin(), min(setup_->numFrames(), (int)acceptedSector.size())) - : acceptedSector.end(); - copy_if(limit, acceptedSector.end(), back_inserter(lostSector), [](StubHT* stub) { return stub; }); - acceptedSector.erase(limit, acceptedSector.end()); } // identify tracks - void HoughTransform::readOut(const vector& acceptedSector, - const vector& lostSector, - deque& acceptedAll, - deque& lostAll) const { + void HoughTransform::readOut(const std::vector& input, std::deque& output) const { + auto toBinPhiT = [this](StubHT* stub) { + const DataFormat& gp = dataFormats_->format(Variable::phiT, Process::gp); + const double phiT = phiT_->floating(stub->phiT()); + const double local = phiT - gp.digi(phiT); + return phiT_->integer(local) + setup_->htNumBinsPhiT() / 2; + }; + auto toLayerId = [this](StubHT* stub) { + const DataFormat& layer = dataFormats_->format(Variable::layer, Process::ctb); + return stub->layer().val(layer.width()); + }; // used to recognise in which order tracks are found TTBV trkFoundPhiTs(0, setup_->htNumBinsPhiT()); // hitPattern for all possible tracks, used to find tracks - vector patternHits(setup_->htNumBinsPhiT(), TTBV(0, setup_->numLayers())); - // found unsigned phiTs, ordered in time - vector binsPhiT; - // stub container for all possible tracks - vector> tracks(setup_->htNumBinsPhiT()); - for (int binPhiT = 0; binPhiT < setup_->htNumBinsPhiT(); binPhiT++) { - const int phiT = phiT_.toSigned(binPhiT); - auto samePhiT = [phiT](int sum, StubHT* stub) { return sum + (stub->phiT() == phiT); }; - const int numAccepted = accumulate(acceptedSector.begin(), acceptedSector.end(), 0, samePhiT); - const int numLost = accumulate(lostSector.begin(), lostSector.end(), 0, samePhiT); - tracks[binPhiT].reserve(numAccepted + numLost); - } - for (StubHT* stub : acceptedSector) { - const int binPhiT = phiT_.toUnsigned(stub->phiT()); + std::vector patternHits(setup_->htNumBinsPhiT(), TTBV(0, setup_->numLayers())); + // found phiTs, ordered in time + std::vector phiTs; + phiTs.reserve(setup_->htNumBinsPhiT()); + for (StubHT* stub : input) { + const int binPhiT = toBinPhiT(stub); + const int layerId = toLayerId(stub); TTBV& pattern = patternHits[binPhiT]; - pattern.set(stub->layer()); - tracks[binPhiT].push_back(stub); - if (pattern.count() >= setup_->htMinLayers() && !trkFoundPhiTs[binPhiT]) { - // first time track found - trkFoundPhiTs.set(binPhiT); - binsPhiT.push_back(binPhiT); - } + pattern.set(layerId); + if (trkFoundPhiTs[binPhiT] || noTrack(pattern, stub->zT())) + continue; + // first time track found + trkFoundPhiTs.set(binPhiT); + phiTs.push_back(binPhiT); } // read out found tracks ordered as found - for (int binPhiT : binsPhiT) { - const vector& track = tracks[binPhiT]; - acceptedAll.insert(acceptedAll.end(), track.begin(), track.end()); - } - // look for lost tracks - for (StubHT* stub : lostSector) { - const int binPhiT = phiT_.toUnsigned(stub->phiT()); - if (!trkFoundPhiTs[binPhiT]) - tracks[binPhiT].push_back(stub); + for (int phiT : phiTs) { + auto samePhiT = [phiT, toBinPhiT](StubHT* stub) { return toBinPhiT(stub) == phiT; }; + // read out stubs in reverse order to emulate f/w (backtracking linked list) + std::copy_if(input.rbegin(), input.rend(), std::back_inserter(output), samePhiT); } - for (int binPhiT : trkFoundPhiTs.ids(false)) { - const vector& track = tracks[binPhiT]; - set layers; - auto toLayer = [](StubHT* stub) { return stub->layer(); }; - transform(track.begin(), track.end(), inserter(layers, layers.begin()), toLayer); - if ((int)layers.size() >= setup_->htMinLayers()) - lostAll.insert(lostAll.end(), track.begin(), track.end()); + } + + // track identification + bool HoughTransform::noTrack(const TTBV& pattern, int zT) const { + // not enough seeding layer + if (pattern.count(0, setup_->kfMaxSeedingLayer()) < 2) + return true; + // check min layers req + const int minLayers = + setup_->htMinLayers() - (((zT == -4 || zT == 3) && (!pattern.test(5) && !pattern.test(7))) ? 1 : 0); + // prepare pattern analysis + const TTBV& maybePattern = layerEncoding_->maybePattern(zT); + int nHits(0); + int nGaps(0); + bool doubleGap = false; + for (int layer = 0; layer < setup_->numLayers(); layer++) { + if (pattern.test(layer)) { + doubleGap = false; + if (++nHits == minLayers) + return false; + } else if (nHits < setup_->kfMinLayers() && !maybePattern.test(layer)) { + if (++nGaps == setup_->kfMaxGaps() || doubleGap) + break; + doubleGap = true; + } } + return true; } // remove and return first element of deque, returns nullptr if empty template - T* HoughTransform::pop_front(deque& ts) const { + T* HoughTransform::pop_front(std::deque& ts) const { T* t = nullptr; if (!ts.empty()) { t = ts.front(); diff --git a/L1Trigger/TrackerTFP/src/KalmanFilter.cc b/L1Trigger/TrackerTFP/src/KalmanFilter.cc index 7b64f0a1f00e9..52ec39c21a035 100644 --- a/L1Trigger/TrackerTFP/src/KalmanFilter.cc +++ b/L1Trigger/TrackerTFP/src/KalmanFilter.cc @@ -9,218 +9,292 @@ #include #include -using namespace std; -using namespace edm; -using namespace tt; - namespace trackerTFP { - KalmanFilter::KalmanFilter(const ParameterSet& iConfig, - const Setup* setup, + KalmanFilter::KalmanFilter(const tt::Setup* setup, const DataFormats* dataFormats, + const LayerEncoding* layerEncoding, KalmanFilterFormats* kalmanFilterFormats, - int region) - : enableTruncation_(iConfig.getParameter("EnableTruncation")), - setup_(setup), + std::vector& tracks, + std::vector& stubs) + : setup_(setup), dataFormats_(dataFormats), + layerEncoding_(layerEncoding), kalmanFilterFormats_(kalmanFilterFormats), - region_(region), - input_(dataFormats_->numChannel(Process::kf)), - layer_(0), - x0_(&kalmanFilterFormats_->format(VariableKF::x0)), - x1_(&kalmanFilterFormats_->format(VariableKF::x1)), - x2_(&kalmanFilterFormats_->format(VariableKF::x2)), - x3_(&kalmanFilterFormats_->format(VariableKF::x3)), - H00_(&kalmanFilterFormats_->format(VariableKF::H00)), - H12_(&kalmanFilterFormats_->format(VariableKF::H12)), - m0_(&kalmanFilterFormats_->format(VariableKF::m0)), - m1_(&kalmanFilterFormats_->format(VariableKF::m1)), - v0_(&kalmanFilterFormats_->format(VariableKF::v0)), - v1_(&kalmanFilterFormats_->format(VariableKF::v1)), - r0_(&kalmanFilterFormats_->format(VariableKF::r0)), - r1_(&kalmanFilterFormats_->format(VariableKF::r1)), - S00_(&kalmanFilterFormats_->format(VariableKF::S00)), - S01_(&kalmanFilterFormats_->format(VariableKF::S01)), - S12_(&kalmanFilterFormats_->format(VariableKF::S12)), - S13_(&kalmanFilterFormats_->format(VariableKF::S13)), - K00_(&kalmanFilterFormats_->format(VariableKF::K00)), - K10_(&kalmanFilterFormats_->format(VariableKF::K10)), - K21_(&kalmanFilterFormats_->format(VariableKF::K21)), - K31_(&kalmanFilterFormats_->format(VariableKF::K31)), - R00_(&kalmanFilterFormats_->format(VariableKF::R00)), - R11_(&kalmanFilterFormats_->format(VariableKF::R11)), - R00Rough_(&kalmanFilterFormats_->format(VariableKF::R00Rough)), - R11Rough_(&kalmanFilterFormats_->format(VariableKF::R11Rough)), - invR00Approx_(&kalmanFilterFormats_->format(VariableKF::invR00Approx)), - invR11Approx_(&kalmanFilterFormats_->format(VariableKF::invR11Approx)), - invR00Cor_(&kalmanFilterFormats_->format(VariableKF::invR00Cor)), - invR11Cor_(&kalmanFilterFormats_->format(VariableKF::invR11Cor)), - invR00_(&kalmanFilterFormats_->format(VariableKF::invR00)), - invR11_(&kalmanFilterFormats_->format(VariableKF::invR11)), - C00_(&kalmanFilterFormats_->format(VariableKF::C00)), - C01_(&kalmanFilterFormats_->format(VariableKF::C01)), - C11_(&kalmanFilterFormats_->format(VariableKF::C11)), - C22_(&kalmanFilterFormats_->format(VariableKF::C22)), - C23_(&kalmanFilterFormats_->format(VariableKF::C23)), - C33_(&kalmanFilterFormats_->format(VariableKF::C33)) { - C00_->updateRangeActual(pow(dataFormats_->base(Variable::inv2R, Process::kfin), 2)); - C11_->updateRangeActual(pow(dataFormats_->base(Variable::phiT, Process::kfin), 2)); - C22_->updateRangeActual(pow(dataFormats_->base(Variable::cot, Process::kfin), 2)); - C33_->updateRangeActual(pow(dataFormats_->base(Variable::zT, Process::kfin), 2)); - } - - // read in and organize input product (fill vector input_) - void KalmanFilter::consume(const StreamsTrack& streamsTrack, const StreamsStub& streamsStub) { - auto valid = [](const auto& frame) { return frame.first.isNonnull(); }; - auto acc = [](int sum, const auto& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); }; - int nTracks(0); - int nStubs(0); - const int offset = region_ * dataFormats_->numChannel(Process::kf); - for (int channel = 0; channel < dataFormats_->numChannel(Process::kf); channel++) { - const int channelTrack = offset + channel; - const StreamTrack& streamTracks = streamsTrack[channelTrack]; - nTracks += accumulate(streamTracks.begin(), streamTracks.end(), 0, acc); - for (int layer = 0; layer < setup_->numLayers(); layer++) { - const int channelStub = channelTrack * setup_->numLayers() + layer; - const StreamStub& streamStubs = streamsStub[channelStub]; - nStubs += accumulate(streamStubs.begin(), streamStubs.end(), 0, acc); - } - } - tracks_.reserve(nTracks); - stubs_.reserve(nStubs); - // N.B. One input stream for track & one for its stubs in each layer. If a track has N stubs in one layer, and fewer in all other layers, then next valid track will be N frames later - for (int channel = 0; channel < dataFormats_->numChannel(Process::kf); channel++) { - const int channelTrack = offset + channel; - const StreamTrack& streamTracks = streamsTrack[channelTrack]; - vector& tracks = input_[channel]; - tracks.reserve(streamTracks.size()); - for (int frame = 0; frame < (int)streamTracks.size(); frame++) { - const FrameTrack& frameTrack = streamTracks[frame]; - // Select frames with valid track - if (frameTrack.first.isNull()) { - if (dataFormats_->hybrid()) - tracks.push_back(nullptr); - continue; - } - auto endOfTrk = find_if(next(streamTracks.begin(), frame + 1), streamTracks.end(), valid); - if (dataFormats_->hybrid()) - endOfTrk = next(streamTracks.begin(), frame + 1); - // No. of frames before next track indicates gives max. no. of stubs this track had in any layer - const int maxStubsPerLayer = distance(next(streamTracks.begin(), frame), endOfTrk); - tracks.insert(tracks.end(), maxStubsPerLayer - 1, nullptr); - deque stubs; - for (int layer = 0; layer < setup_->numLayers(); layer++) { - const int channelStub = channelTrack * setup_->numLayers() + layer; - const StreamStub& streamStubs = streamsStub[channelStub]; - // Get stubs on this track - for (int i = frame; i < frame + maxStubsPerLayer; i++) { - const FrameStub& frameStub = streamStubs[i]; - if (frameStub.first.isNull()) - break; - // Store input stubs, so remainder of KF algo can work with pointers to them (saves CPU) - stubs_.emplace_back(frameStub, dataFormats_, layer); - stubs.push_back(&stubs_.back()); - } - } - // Store input tracks, so remainder of KF algo can work with pointers to them (saves CPU) - tracks_.emplace_back(frameTrack, dataFormats_, vector(stubs.begin(), stubs.end())); - tracks.push_back(&tracks_.back()); - } - } - } + tracks_(tracks), + stubs_(stubs), + layer_(0) {} // fill output products - void KalmanFilter::produce(StreamsStub& acceptedStubs, - StreamsTrack& acceptedTracks, - StreamsStub& lostStubs, - StreamsTrack& lostTracks, + void KalmanFilter::produce(const std::vector>& tracksIn, + const std::vector>& stubsIn, + std::vector>& tracksOut, + std::vector>>& stubsOut, int& numAcceptedStates, - int& numLostStates) { - auto put = [this]( - const deque& states, StreamsStub& streamsStubs, StreamsTrack& streamsTracks, int channel) { - const int streamId = region_ * dataFormats_->numChannel(Process::kf) + channel; - const int offset = streamId * setup_->numLayers(); - StreamTrack& tracks = streamsTracks[streamId]; - tracks.reserve(states.size()); - for (int layer = 0; layer < setup_->numLayers(); layer++) - streamsStubs[offset + layer].reserve(states.size()); - for (State* state : states) { - tracks.emplace_back(state->frame()); - vector stubs; - state->fill(stubs); - for (const StubKF& stub : stubs) - streamsStubs[offset + stub.layer()].emplace_back(stub.frame()); - // adding a gap to all layer without a stub - for (int layer : state->hitPattern().ids(false)) - streamsStubs[offset + layer].emplace_back(FrameStub()); - } - }; - auto count = [this](int sum, const State* state) { - return sum + ((state && state->hitPattern().count() >= setup_->kfMinLayers()) ? 1 : 0); - }; + int& numLostStates, + std::deque>& chi2s) { for (int channel = 0; channel < dataFormats_->numChannel(Process::kf); channel++) { - deque stream; - deque lost; + std::deque stream; // proto state creation - int trackId(0); - for (TrackKFin* track : input_[channel]) { - State* state = nullptr; - if (track) { - // Store states, so remainder of KF algo can work with pointers to them (saves CPU) - states_.emplace_back(dataFormats_, track, trackId++); - state = &states_.back(); - } - stream.push_back(state); - } + createProtoStates(tracksIn, stubsIn, channel, stream); + // seed building + for (layer_ = 0; layer_ < setup_->kfMaxSeedingLayer(); layer_++) + addSeedLayer(stream); + // calulcate seed parameter + calcSeeds(stream); // Propagate state to each layer in turn, updating it with all viable stub combinations there, using KF maths - for (layer_ = 0; layer_ < setup_->numLayers(); layer_++) + for (layer_ = setup_->kfNumSeedStubs(); layer_ < setup_->numLayers(); layer_++) addLayer(stream); - // calculate number of states before truncating - const int numUntruncatedStates = accumulate(stream.begin(), stream.end(), 0, count); - // untruncated best state selection - deque untruncatedStream = stream; - accumulator(untruncatedStream); + // count total number of final states + const int nStates = + accumulate(stream.begin(), stream.end(), 0, [](int sum, State* state) { return sum + (state ? 1 : 0); }); // apply truncation - if (enableTruncation_ && (int)stream.size() > setup_->numFrames()) - stream.resize(setup_->numFrames()); - // calculate number of states after truncating - const int numTruncatedStates = accumulate(stream.begin(), stream.end(), 0, count); - // best state per candidate selection - accumulator(stream); - deque truncatedStream = stream; - // storing of best states missed due to truncation - sort(untruncatedStream.begin(), untruncatedStream.end()); - sort(truncatedStream.begin(), truncatedStream.end()); - set_difference(untruncatedStream.begin(), - untruncatedStream.end(), - truncatedStream.begin(), - truncatedStream.end(), - back_inserter(lost)); - // store found tracks - put(stream, acceptedStubs, acceptedTracks, channel); - // store lost tracks - put(lost, lostStubs, lostTracks, channel); + if (setup_->enableTruncation() && static_cast(stream.size()) > setup_->numFramesHigh()) + stream.resize(setup_->numFramesHigh()); + // cycle event, remove gaps + stream.erase(std::remove(stream.begin(), stream.end(), nullptr), stream.end()); // store number of states which got taken into account - numAcceptedStates += numTruncatedStates; + numAcceptedStates += stream.size(); // store number of states which got not taken into account due to truncation - numLostStates += numUntruncatedStates - numTruncatedStates; + numLostStates += nStates - stream.size(); + // apply final cuts + std::vector finals; + finals.reserve(stream.size()); + finalize(stream, finals); + // best track per candidate selection + std::vector best; + best.reserve(stream.size()); + accumulator(finals, best); + // store chi2s + for (Track* track : best) + chi2s.emplace_back(track->chi20_, track->chi21_); + // Transform States into Tracks + std::vector& tracks = tracksOut[channel]; + std::vector>& stubs = stubsOut[channel]; + conv(best, tracks, stubs); + } + } + + // create Proto States + void KalmanFilter::createProtoStates(const std::vector>& tracksIn, + const std::vector>& stubsIn, + int channel, + std::deque& stream) { + const int numLayers = setup_->numLayers(); + const int offsetL = channel * numLayers; + const std::vector& tracksChannel = tracksIn[channel]; + int trackId(0); + for (int frame = 0; frame < static_cast(tracksChannel.size());) { + TrackCTB* track = tracksChannel[frame]; + if (!track) { + frame++; + continue; + } + const auto begin = std::next(tracksChannel.begin(), frame); + const auto end = std::find_if(begin + 1, tracksChannel.end(), [](TrackCTB* track) { return track; }); + const int size = std::distance(begin, end); + std::vector> stubs(numLayers); + for (std::vector& layer : stubs) + layer.reserve(size); + for (int layer = 0; layer < numLayers; layer++) { + const std::vector& layerAll = stubsIn[layer + offsetL]; + std::vector& layerTrack = stubs[layer]; + for (int frameS = 0; frameS < size; frameS++) { + Stub* stub = layerAll[frameS + frame]; + if (!stub) + break; + layerTrack.push_back(stub); + } + } + const TTBV& maybePattern = layerEncoding_->maybePattern(track->zT()); + states_.emplace_back(kalmanFilterFormats_, track, stubs, maybePattern, trackId++); + stream.insert(stream.end(), size - 1, nullptr); + stream.push_back(&states_.back()); + frame += size; + } + } + + // calulcate seed parameter + void KalmanFilter::calcSeeds(std::deque& stream) { + auto update = [this](State* s) { + updateRangeActual(VariableKF::m0, s->m0()); + updateRangeActual(VariableKF::m1, s->m1()); + updateRangeActual(VariableKF::v0, s->v0()); + updateRangeActual(VariableKF::v1, s->v1()); + updateRangeActual(VariableKF::H00, s->H00()); + updateRangeActual(VariableKF::H12, s->H12()); + }; + for (State*& state : stream) { + if (!state) + continue; + State* s1 = state->parent(); + State* s0 = s1->parent(); + update(s0); + update(s1); + const double dH = digi(VariableKF::dH, s1->H00() - s0->H00()); + const double invdH = digi(VariableKF::invdH, 1.0 / dH); + const double invdH2 = digi(VariableKF::invdH2, 1.0 / dH / dH); + const double H12 = digi(VariableKF::H2, s1->H00() * s1->H00()); + const double H02 = digi(VariableKF::H2, s0->H00() * s0->H00()); + const double H32 = digi(VariableKF::H2, s1->H12() * s1->H12()); + const double H22 = digi(VariableKF::H2, s0->H12() * s0->H12()); + const double H1m0 = digi(VariableKF::Hm0, s1->H00() * s0->m0()); + const double H0m1 = digi(VariableKF::Hm0, s0->H00() * s1->m0()); + const double H3m2 = digi(VariableKF::Hm1, s1->H12() * s0->m1()); + const double H2m3 = digi(VariableKF::Hm1, s0->H12() * s1->m1()); + const double H1v0 = digi(VariableKF::Hv0, s1->H00() * s0->v0()); + const double H0v1 = digi(VariableKF::Hv0, s0->H00() * s1->v0()); + const double H3v2 = digi(VariableKF::Hv1, s1->H12() * s0->v1()); + const double H2v3 = digi(VariableKF::Hv1, s0->H12() * s1->v1()); + const double H12v0 = digi(VariableKF::H2v0, H12 * s0->v0()); + const double H02v1 = digi(VariableKF::H2v0, H02 * s1->v0()); + const double H32v2 = digi(VariableKF::H2v1, H32 * s0->v1()); + const double H22v3 = digi(VariableKF::H2v1, H22 * s1->v1()); + const double x0 = digi(VariableKF::x0, (s1->m0() - s0->m0()) * invdH); + const double x2 = digi(VariableKF::x2, (s1->m1() - s0->m1()) * invdH); + const double x1 = digi(VariableKF::x1, (H1m0 - H0m1) * invdH); + const double x3 = digi(VariableKF::x3, (H3m2 - H2m3) * invdH); + const double C00 = digi(VariableKF::C00, (s1->v0() + s0->v0()) * invdH2); + const double C22 = digi(VariableKF::C22, (s1->v1() + s0->v1()) * invdH2); + const double C01 = -digi(VariableKF::C01, (H1v0 + H0v1) * invdH2); + const double C23 = -digi(VariableKF::C23, (H3v2 + H2v3) * invdH2); + const double C11 = digi(VariableKF::C11, (H12v0 + H02v1) * invdH2); + const double C33 = digi(VariableKF::C33, (H32v2 + H22v3) * invdH2); + // create updated state + const double chi20 = digi(VariableKF::chi20, 0.); + const double chi21 = digi(VariableKF::chi21, 0.); + states_.emplace_back(State(s1, {x0, x1, x2, x3, chi20, chi21, C00, C11, C22, C33, C01, C23})); + state = &states_.back(); + updateRangeActual(VariableKF::x0, x0); + updateRangeActual(VariableKF::x1, x1); + updateRangeActual(VariableKF::x2, x2); + updateRangeActual(VariableKF::x3, x3); + updateRangeActual(VariableKF::C00, C00); + updateRangeActual(VariableKF::C01, C01); + updateRangeActual(VariableKF::C11, C11); + updateRangeActual(VariableKF::C22, C22); + updateRangeActual(VariableKF::C23, C23); + updateRangeActual(VariableKF::C33, C33); + } + } + + // apply final cuts + void KalmanFilter::finalize(const std::deque& stream, std::vector& finals) { + for (State* state : stream) { + TrackCTB* track = state->track(); + int numConsistent(0); + int numConsistentPS(0); + TTBV hitPattern = state->hitPattern(); + std::vector stubs; + std::vector phis; + std::vector zs; + stubs.reserve(setup_->numLayers()); + phis.reserve(setup_->numLayers()); + zs.reserve(setup_->numLayers()); + double chi20(0.); + double chi21(0.); + // stub residual cut + State* s = state; + while ((s = s->parent())) { + const double dPhi = state->x1() + s->H00() * state->x0(); + const double dZ = state->x3() + s->H12() * state->x2(); + const double phi = digi(VariableKF::m0, s->m0() - dPhi); + const double z = digi(VariableKF::m1, s->m1() - dZ); + const bool validPhi = dataFormats_->format(Variable::phi, Process::kf).inRange(phi); + const bool validZ = dataFormats_->format(Variable::z, Process::kf).inRange(z); + StubCTB& stubCTB = s->stub()->stubCTB_; + if (validPhi && validZ) { + chi20 += pow(phi, 2); + chi21 += pow(z, 2); + stubs.push_back(&stubCTB); + phis.push_back(phi); + zs.push_back(z); + if (std::abs(phi) <= s->dPhi() && std::abs(z) <= s->dZ()) { + numConsistent++; + if (setup_->psModule(stubCTB.frame().first)) + numConsistentPS++; + } + } else + hitPattern.reset(s->layer()); + } + const double ndof = hitPattern.count() - 2; + chi20 /= ndof; + chi21 /= ndof; + // layer cut + bool invalidLayers = hitPattern.count() < setup_->kfMinLayers(); + // track parameter cuts + const double cotTrack = dataFormats_->format(Variable::cot, Process::kf).digi(track->zT() / setup_->chosenRofZ()); + const double inv2R = state->x0() + track->inv2R(); + const double phiT = state->x1() + track->phiT(); + const double cot = state->x2() + cotTrack; + const double zT = state->x3() + track->zT(); + // pt cut + const bool validX0 = dataFormats_->format(Variable::inv2R, Process::kf).inRange(inv2R); + // cut on phi sector boundaries + const bool validX1 = dataFormats_->format(Variable::phiT, Process::kf).inRange(phiT); + // cot cut + const bool validX2 = dataFormats_->format(Variable::cot, Process::kf).inRange(cot); + // zT cut + const bool validX3 = dataFormats_->format(Variable::zT, Process::kf).inRange(zT); + if (invalidLayers || !validX0 || !validX1 || !validX2 || !validX3) + continue; + const int trackId = state->trackId(); + finals_.emplace_back(trackId, + numConsistent, + numConsistentPS, + inv2R, + phiT, + cot, + zT, + chi20, + chi21, + hitPattern, + track, + stubs, + phis, + zs); + } + } + + // Transform States into Tracks + void KalmanFilter::conv(const std::vector& best, + std::vector& tracks, + std::vector>& stubs) { + const DataFormat& dfInv2R = dataFormats_->format(Variable::inv2R, Process::ht); + const DataFormat& dfPhiT = dataFormats_->format(Variable::phiT, Process::ht); + tracks.reserve(best.size()); + for (std::vector& layer : stubs) + layer.reserve(best.size()); + for (Track* track : best) { + const std::vector layers = track->hitPattern_.ids(); + for (int iStub = 0; iStub < track->hitPattern_.count(); iStub++) { + StubCTB* s = track->stubs_[iStub]; + stubs_.emplace_back(*s, s->r(), track->phi_[iStub], track->z_[iStub], s->dPhi(), s->dZ()); + stubs[layers[iStub]].push_back(&stubs_.back()); + } + TrackCTB* trackCTB = track->track_; + const bool inInv2R = dfInv2R.integer(track->inv2R_) == dfInv2R.integer(trackCTB->inv2R()); + const bool inPhiT = dfPhiT.integer(track->phiT_) == dfPhiT.integer(trackCTB->phiT()); + const TTBV match(inInv2R && inPhiT, 1); + tracks_.emplace_back(*trackCTB, track->inv2R_, track->phiT_, track->cot_, track->zT_, match); + tracks.push_back(&tracks_.back()); } } // adds a layer to states - void KalmanFilter::addLayer(deque& stream) { + void KalmanFilter::addLayer(std::deque& stream) { // Latency of KF Associator block firmware static constexpr int latency = 5; // dynamic state container for clock accurate emulation - deque streamOutput; + std::deque streamOutput; // Memory stack used to handle combinatorics - deque stack; + std::deque stack; // static delay container - vector delay(latency, nullptr); + std::deque delay(latency, nullptr); // each trip corresponds to a f/w clock tick // done if no states to process left, taking as much time as needed while (!stream.empty() || !stack.empty() || - !all_of(delay.begin(), delay.end(), [](const State* state) { return state == nullptr; })) { + !std::all_of(delay.begin(), delay.end(), [](const State* state) { return state == nullptr; })) { State* state = pop_front(stream); // Process a combinatoric state if no (non-combinatoric?) state available if (!state) @@ -228,8 +302,7 @@ namespace trackerTFP { streamOutput.push_back(state); // The remainder of the code in this loop deals with combinatoric states. if (state) - // Assign next combinatoric stub to state - comb(state); + state = state->comb(states_, layer_); delay.push_back(state); state = pop_front(delay); if (state) @@ -238,200 +311,236 @@ namespace trackerTFP { stream = streamOutput; // Update state with next stub using KF maths for (State*& state : stream) - if (state && state->stub() && state->layer() == layer_) + if (state && state->hitPattern().pmEncode() == layer_) update(state); } - // Assign next combinatoric (i.e. not first in layer) stub to state - void KalmanFilter::comb(State*& state) { - const TrackKFin* track = state->track(); - const StubKFin* stub = state->stub(); - const vector& stubs = track->layerStubs(layer_); - const TTBV& hitPattern = state->hitPattern(); - StubKFin* stubNext = nullptr; - bool valid = state->stub() && state->layer() == layer_; - if (valid) { - // Get next unused stub on this layer - const int pos = distance(stubs.begin(), find(stubs.begin(), stubs.end(), stub)) + 1; - if (pos != (int)stubs.size()) - stubNext = stubs[pos]; - // picks next stub on different layer, nullifies state if skipping layer is not valid - else { - // having already maximum number of added layers - if (hitPattern.count() == setup_->kfMaxLayers()) - valid = false; - // Impossible for this state to ever get enough layers to form valid track - if (hitPattern.count() + track->hitPattern().count(stub->layer() + 1, setup_->numLayers()) < - setup_->kfMinLayers()) - valid = false; - // not diffrent layers left - if (layer_ == setup_->numLayers() - 1) - valid = false; - if (valid) { - // pick next stub on next populated layer - for (int nextLayer = layer_ + 1; nextLayer < setup_->numLayers(); nextLayer++) { - if (track->hitPattern(nextLayer)) { - stubNext = track->layerStub(nextLayer); - break; - } - } - } - } + // adds a layer to states to build seeds + void KalmanFilter::addSeedLayer(std::deque& stream) { + // Latency of KF Associator block firmware + static constexpr int latency = 5; + // dynamic state container for clock accurate emulation + std::deque streamOutput; + // Memory stack used to handle combinatorics + std::deque stack; + // static delay container + std::deque delay(latency, nullptr); + // each trip corresponds to a f/w clock tick + // done if no states to process left, taking as much time as needed + while (!stream.empty() || !stack.empty() || + !std::all_of(delay.begin(), delay.end(), [](const State* state) { return state == nullptr; })) { + State* state = pop_front(stream); + // Process a combinatoric state if no (non-combinatoric?) state available + if (!state) + state = pop_front(stack); + streamOutput.push_back(state); + // The remainder of the code in this loop deals with combinatoric states. + if (state) + state = state->combSeed(states_, layer_); + delay.push_back(state); + state = pop_front(delay); + if (state) + stack.push_back(state); } - if (valid) { - // create combinatoric state - states_.emplace_back(state, stubNext); - state = &states_.back(); - } else - state = nullptr; + stream = streamOutput; + // Update state with next stub using KF maths + for (State*& state : stream) + if (state) + state = state->update(states_, layer_); } // best state selection - void KalmanFilter::accumulator(deque& stream) { - // accumulator delivers contigious stream of best state per track - // remove gaps and not final states - stream.erase( - remove_if(stream.begin(), - stream.end(), - [this](State* state) { return !state || state->hitPattern().count() < setup_->kfMinLayers(); }), - stream.end()); - // Determine quality of completed state - for (State* state : stream) - state->finish(); - // sort in number of skipped layers - auto lessSkippedLayers = [](State* lhs, State* rhs) { return lhs->numSkippedLayers() < rhs->numSkippedLayers(); }; - stable_sort(stream.begin(), stream.end(), lessSkippedLayers); + void KalmanFilter::accumulator(std::vector& finals, std::vector& best) { + // create container of pointer to make sorts less CPU intense + std::transform(finals.begin(), finals.end(), std::back_inserter(best), [](Track& track) { return &track; }); + // prepare arrival order + std::vector trackIds; + trackIds.reserve(best.size()); + for (Track* track : best) { + const int trackId = track->trackId_; + if (std::find_if(trackIds.begin(), trackIds.end(), [trackId](int id) { return id == trackId; }) == trackIds.end()) + trackIds.push_back(trackId); + } + // sort in chi2 + auto smallerChi2 = [](Track* lhs, Track* rhs) { return lhs->chi20_ + lhs->chi21_ < rhs->chi20_ + rhs->chi21_; }; + std::stable_sort(best.begin(), best.end(), smallerChi2); // sort in number of consistent stubs - auto moreConsistentLayers = [](State* lhs, State* rhs) { - return lhs->numConsistentLayers() > rhs->numConsistentLayers(); + auto moreConsistentLayers = [](Track* lhs, Track* rhs) { return lhs->numConsistent_ > rhs->numConsistent_; }; + std::stable_sort(best.begin(), best.end(), moreConsistentLayers); + // sort in number of consistent ps stubs + auto moreConsistentLayersPS = [](Track* lhs, Track* rhs) { return lhs->numConsistentPS_ > rhs->numConsistentPS_; }; + std::stable_sort(best.begin(), best.end(), moreConsistentLayersPS); + // sort in track id as arrived + auto order = [&trackIds](auto lhs, auto rhs) { + const auto l = find(trackIds.begin(), trackIds.end(), lhs->trackId_); + const auto r = find(trackIds.begin(), trackIds.end(), rhs->trackId_); + return std::distance(r, l) < 0; }; - stable_sort(stream.begin(), stream.end(), moreConsistentLayers); - // sort in track id - stable_sort(stream.begin(), stream.end(), [](State* lhs, State* rhs) { return lhs->trackId() < rhs->trackId(); }); + std::stable_sort(best.begin(), best.end(), order); // keep first state (best due to previous sorts) per track id - stream.erase( - unique(stream.begin(), stream.end(), [](State* lhs, State* rhs) { return lhs->track() == rhs->track(); }), - stream.end()); + auto same = [](Track* lhs, Track* rhs) { return lhs->trackId_ == rhs->trackId_; }; + best.erase(std::unique(best.begin(), best.end(), same), best.end()); } // updates state void KalmanFilter::update(State*& state) { // All variable names & equations come from Fruhwirth KF paper http://dx.doi.org/10.1016/0168-9002%2887%2990887-4", where F taken as unit matrix. Stub uncertainties projected onto (phi,z), assuming no correlations between r-phi & r-z planes. // stub phi residual wrt input helix - const double m0 = m0_->digi(state->m0()); + const double m0 = state->m0(); // stub z residual wrt input helix - const double m1 = m1_->digi(state->m1()); + const double m1 = state->m1(); // stub projected phi uncertainty squared); - const double v0 = v0_->digi(state->v0()); + const double v0 = state->v0(); // stub projected z uncertainty squared - const double v1 = v1_->digi(state->v1()); + const double v1 = state->v1(); + // Derivative of predicted stub coords wrt helix params: stub radius minus chosenRofPhi + const double H00 = state->H00(); + // Derivative of predicted stub coords wrt helix params: stub radius minus chosenRofZ + const double H12 = state->H12(); + updateRangeActual(VariableKF::m0, m0); + updateRangeActual(VariableKF::m1, m1); + updateRangeActual(VariableKF::v0, v0); + updateRangeActual(VariableKF::v1, v1); + updateRangeActual(VariableKF::H00, H00); + updateRangeActual(VariableKF::H12, H12); // helix inv2R wrt input helix - double x0 = x0_->digi(state->x0()); + double x0 = state->x0(); // helix phi at radius ChosenRofPhi wrt input helix - double x1 = x1_->digi(state->x1()); + double x1 = state->x1(); // helix cot(Theta) wrt input helix - double x2 = x2_->digi(state->x2()); + double x2 = state->x2(); // helix z at radius chosenRofZ wrt input helix - double x3 = x3_->digi(state->x3()); - // Derivative of predicted stub coords wrt helix params: stub radius minus chosenRofPhi - const double H00 = H00_->digi(state->H00()); - // Derivative of predicted stub coords wrt helix params: stub radius minus chosenRofZ - const double H12 = H12_->digi(state->H12()); + double x3 = state->x3(); // cov. matrix - double C00 = C00_->digi(state->C00()); - double C01 = C01_->digi(state->C01()); - double C11 = C11_->digi(state->C11()); - double C22 = C22_->digi(state->C22()); - double C23 = C23_->digi(state->C23()); - double C33 = C33_->digi(state->C33()); + double C00 = state->C00(); + double C01 = state->C01(); + double C11 = state->C11(); + double C22 = state->C22(); + double C23 = state->C23(); + double C33 = state->C33(); + // chi2s + double chi20 = state->chi20(); + double chi21 = state->chi21(); // stub phi residual wrt current state - const double r0C = x1_->digi(m0 - x1); - const double r0 = r0_->digi(r0C - x0 * H00); + const double r0C = digi(VariableKF::x1, m0 - x1); + const double r0 = digi(VariableKF::r0, r0C - x0 * H00); // stub z residual wrt current state - const double r1C = x3_->digi(m1 - x3); - const double r1 = r1_->digi(r1C - x2 * H12); + const double r1C = digi(VariableKF::x3, m1 - x3); + const double r1 = digi(VariableKF::r1, r1C - x2 * H12); // matrix S = H*C - const double S00 = S00_->digi(C01 + H00 * C00); - const double S01 = S01_->digi(C11 + H00 * C01); - const double S12 = S12_->digi(C23 + H12 * C22); - const double S13 = S13_->digi(C33 + H12 * C23); + const double S00 = digi(VariableKF::S00, C01 + H00 * C00); + const double S01 = digi(VariableKF::S01, C11 + H00 * C01); + const double S12 = digi(VariableKF::S12, C23 + H12 * C22); + const double S13 = digi(VariableKF::S13, C33 + H12 * C23); // Cov. matrix of predicted residuals R = V+HCHt = C+H*St - const double R00C = S01_->digi(v0 + S01); - const double R00 = R00_->digi(R00C + H00 * S00); - const double R11C = S13_->digi(v1 + S13); - const double R11 = R11_->digi(R11C + H12 * S12); - // imrpoved dynamic cancelling - const int msb0 = max(0, (int)ceil(log2(R00 / R00_->base()))); - const int msb1 = max(0, (int)ceil(log2(R11 / R11_->base()))); - const double R00Rough = R00Rough_->digi(R00 * pow(2., 16 - msb0)); - const double invR00Approx = invR00Approx_->digi(1. / R00Rough); - const double invR00Cor = invR00Cor_->digi(2. - invR00Approx * R00Rough); - const double invR00 = invR00_->digi(invR00Approx * invR00Cor * pow(2., 16 - msb0)); - const double R11Rough = R11Rough_->digi(R11 * pow(2., 16 - msb1)); - const double invR11Approx = invR11Approx_->digi(1. / R11Rough); - const double invR11Cor = invR11Cor_->digi(2. - invR11Approx * R11Rough); - const double invR11 = invR11_->digi(invR11Approx * invR11Cor * pow(2., 16 - msb1)); + const double R00 = digi(VariableKF::R00, v0 + S01 + H00 * S00); + const double R11 = digi(VariableKF::R11, v1 + S13 + H12 * S12); + // improved dynamic cancelling + const int msb0 = std::max(0, static_cast(std::ceil(std::log2(R00 / base(VariableKF::R00))))); + const int msb1 = std::max(0, static_cast(std::ceil(std::log2(R11 / base(VariableKF::R11))))); + const int shift0 = width(VariableKF::R00) - msb0; + const int shift1 = width(VariableKF::R11) - msb1; + const double R00Shifted = R00 * std::pow(2., shift0); + const double R11Shifted = R11 * std::pow(2., shift1); + const double R00Rough = digi(VariableKF::R00Rough, R00Shifted); + const double R11Rough = digi(VariableKF::R11Rough, R11Shifted); + const double invR00Approx = digi(VariableKF::invR00Approx, 1. / R00Rough); + const double invR11Approx = digi(VariableKF::invR11Approx, 1. / R11Rough); + const double invR00Cor = digi(VariableKF::invR00Cor, 2. - invR00Approx * R00Shifted); + const double invR11Cor = digi(VariableKF::invR11Cor, 2. - invR11Approx * R11Shifted); + const double invR00 = digi(VariableKF::invR00, invR00Approx * invR00Cor); + const double invR11 = digi(VariableKF::invR11, invR11Approx * invR11Cor); + // shift S to "undo" shifting of R + auto digiShifted = [](double val, double base) { return floor(val / base * 2. + 1.e-11) * base / 2.; }; + const double S00Shifted = digiShifted(S00 * std::pow(2., shift0), base(VariableKF::S00Shifted)); + const double S01Shifted = digiShifted(S01 * std::pow(2., shift0), base(VariableKF::S01Shifted)); + const double S12Shifted = digiShifted(S12 * std::pow(2., shift1), base(VariableKF::S12Shifted)); + const double S13Shifted = digiShifted(S13 * std::pow(2., shift1), base(VariableKF::S13Shifted)); // Kalman gain matrix K = S*R(inv) - const double K00 = K00_->digi(S00 * invR00); - const double K10 = K10_->digi(S01 * invR00); - const double K21 = K21_->digi(S12 * invR11); - const double K31 = K31_->digi(S13 * invR11); - // Updated helix params & their cov. matrix - x0 = x0_->digi(x0 + r0 * K00); - x1 = x1_->digi(x1 + r0 * K10); - x2 = x2_->digi(x2 + r1 * K21); - x3 = x3_->digi(x3 + r1 * K31); - C00 = C00_->digi(C00 - S00 * K00); - C01 = C01_->digi(C01 - S01 * K00); - C11 = C11_->digi(C11 - S01 * K10); - C22 = C22_->digi(C22 - S12 * K21); - C23 = C23_->digi(C23 - S13 * K21); - C33 = C33_->digi(C33 - S13 * K31); + const double K00 = digi(VariableKF::K00, S00Shifted * invR00); + const double K10 = digi(VariableKF::K10, S01Shifted * invR00); + const double K21 = digi(VariableKF::K21, S12Shifted * invR11); + const double K31 = digi(VariableKF::K31, S13Shifted * invR11); + // Updated helix params, their cov. matrix + x0 = digi(VariableKF::x0, x0 + r0 * K00); + x1 = digi(VariableKF::x1, x1 + r0 * K10); + x2 = digi(VariableKF::x2, x2 + r1 * K21); + x3 = digi(VariableKF::x3, x3 + r1 * K31); + C00 = digi(VariableKF::C00, C00 - S00 * K00); + C01 = digi(VariableKF::C01, C01 - S01 * K00); + C11 = digi(VariableKF::C11, C11 - S01 * K10); + C22 = digi(VariableKF::C22, C22 - S12 * K21); + C23 = digi(VariableKF::C23, C23 - S13 * K21); + C33 = digi(VariableKF::C33, C33 - S13 * K31); + // squared residuals + const double r0Shifted = digiShifted(r0 * std::pow(2., shift0), base(VariableKF::r0Shifted)); + const double r1Shifted = digiShifted(r1 * std::pow(2., shift1), base(VariableKF::r1Shifted)); + const double r02 = digi(VariableKF::r02, r0 * r0); + const double r12 = digi(VariableKF::r12, r1 * r1); + chi20 = digi(VariableKF::chi20, chi20 + r02 * invR00); + chi21 = digi(VariableKF::chi21, chi21 + r12 * invR11); + // update variable ranges to tune variable granularity + updateRangeActual(VariableKF::r0, r0); + updateRangeActual(VariableKF::r1, r1); + updateRangeActual(VariableKF::S00, S00); + updateRangeActual(VariableKF::S01, S01); + updateRangeActual(VariableKF::S12, S12); + updateRangeActual(VariableKF::S13, S13); + updateRangeActual(VariableKF::S00Shifted, S00Shifted); + updateRangeActual(VariableKF::S01Shifted, S01Shifted); + updateRangeActual(VariableKF::S12Shifted, S12Shifted); + updateRangeActual(VariableKF::S13Shifted, S13Shifted); + updateRangeActual(VariableKF::R00, R00); + updateRangeActual(VariableKF::R11, R11); + updateRangeActual(VariableKF::R00Rough, R00Rough); + updateRangeActual(VariableKF::R11Rough, R11Rough); + updateRangeActual(VariableKF::invR00Approx, invR00Approx); + updateRangeActual(VariableKF::invR11Approx, invR11Approx); + updateRangeActual(VariableKF::invR00Cor, invR00Cor); + updateRangeActual(VariableKF::invR11Cor, invR11Cor); + updateRangeActual(VariableKF::invR00, invR00); + updateRangeActual(VariableKF::invR11, invR11); + updateRangeActual(VariableKF::K00, K00); + updateRangeActual(VariableKF::K10, K10); + updateRangeActual(VariableKF::K21, K21); + updateRangeActual(VariableKF::K31, K31); + updateRangeActual(VariableKF::r0Shifted, r0Shifted); + updateRangeActual(VariableKF::r1Shifted, r1Shifted); + updateRangeActual(VariableKF::r02, r02); + updateRangeActual(VariableKF::r12, r12); + // range checks + const bool validX0 = inRange(VariableKF::x0, x0); + const bool validX1 = inRange(VariableKF::x1, x1); + const bool validX2 = inRange(VariableKF::x2, x2); + const bool validX3 = inRange(VariableKF::x3, x3); + // chi2 cut + const double dof = state->hitPattern().count() - 1; + const double chi2 = (chi20 + chi21) / 2.; + const bool validChi2 = chi2 < setup_->kfCutChi2() * dof; + if (!validX0 || !validX1 || !validX2 || !validX3 || !validChi2) { + state = nullptr; + return; + } // create updated state - states_.emplace_back(State(state, (initializer_list){x0, x1, x2, x3, C00, C11, C22, C33, C01, C23})); + states_.emplace_back(State(state, {x0, x1, x2, x3, chi20, chi21, C00, C11, C22, C33, C01, C23})); state = &states_.back(); - // update variable ranges to tune variable granularity - m0_->updateRangeActual(m0); - m1_->updateRangeActual(m1); - v0_->updateRangeActual(v0); - v1_->updateRangeActual(v1); - H00_->updateRangeActual(H00); - H12_->updateRangeActual(H12); - r0_->updateRangeActual(r0); - r1_->updateRangeActual(r1); - S00_->updateRangeActual(S00); - S01_->updateRangeActual(S01); - S12_->updateRangeActual(S12); - S13_->updateRangeActual(S13); - R00_->updateRangeActual(R00); - R11_->updateRangeActual(R11); - R00Rough_->updateRangeActual(R00Rough); - invR00Approx_->updateRangeActual(invR00Approx); - invR00Cor_->updateRangeActual(invR00Cor); - invR00_->updateRangeActual(invR00); - R11Rough_->updateRangeActual(R11Rough); - invR11Approx_->updateRangeActual(invR11Approx); - invR11Cor_->updateRangeActual(invR11Cor); - invR11_->updateRangeActual(invR11); - K00_->updateRangeActual(K00); - K10_->updateRangeActual(K10); - K21_->updateRangeActual(K21); - K31_->updateRangeActual(K31); - x0_->updateRangeActual(x0); - x1_->updateRangeActual(x1); - x2_->updateRangeActual(x2); - x3_->updateRangeActual(x3); - C00_->updateRangeActual(C00); - C01_->updateRangeActual(C01); - C11_->updateRangeActual(C11); - C22_->updateRangeActual(C22); - C23_->updateRangeActual(C23); - C33_->updateRangeActual(C33); + updateRangeActual(VariableKF::x0, x0); + updateRangeActual(VariableKF::x1, x1); + updateRangeActual(VariableKF::x2, x2); + updateRangeActual(VariableKF::x3, x3); + updateRangeActual(VariableKF::C00, C00); + updateRangeActual(VariableKF::C01, C01); + updateRangeActual(VariableKF::C11, C11); + updateRangeActual(VariableKF::C22, C22); + updateRangeActual(VariableKF::C23, C23); + updateRangeActual(VariableKF::C33, C33); + updateRangeActual(VariableKF::chi20, chi20); + updateRangeActual(VariableKF::chi21, chi21); } // remove and return first element of deque, returns nullptr if empty template - T* KalmanFilter::pop_front(deque& ts) const { + T* KalmanFilter::pop_front(std::deque& ts) const { T* t = nullptr; if (!ts.empty()) { t = ts.front(); @@ -440,15 +549,4 @@ namespace trackerTFP { return t; } - // remove and return first element of vector, returns nullptr if empty - template - T* KalmanFilter::pop_front(vector& ts) const { - T* t = nullptr; - if (!ts.empty()) { - t = ts.front(); - ts.erase(ts.begin()); - } - return t; - } - } // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/src/KalmanFilterFormats.cc b/L1Trigger/TrackerTFP/src/KalmanFilterFormats.cc index fe3625a32a566..0aba76070dcc6 100644 --- a/L1Trigger/TrackerTFP/src/KalmanFilterFormats.cc +++ b/L1Trigger/TrackerTFP/src/KalmanFilterFormats.cc @@ -9,60 +9,56 @@ #include #include -using namespace std; -using namespace edm; -using namespace tt; - namespace trackerTFP { constexpr auto variableKFstrs_ = { - "x0", "x1", "x2", "x3", "H00", "H12", "m0", "m1", "v0", - "v1", "r0", "r1", "S00", "S01", "S12", "S13", "K00", "K10", - "K21", "K31", "R00", "R11", "R00Rough", "R11Rough", "invR00Approx", "invR11Approx", "invR00Cor", - "invR11Cor", "invR00", "invR11", "C00", "C01", "C11", "C22", "C23", "C33"}; - - void KalmanFilterFormats::endJob() { + "x0", "x1", "x2", "x3", "H00", "H12", "m0", "m1", + "v0", "v1", "r0", "r1", "S00", "S01", "S12", "S13", + "S00Shifted", "S01Shifted", "S12Shifted", "S13Shifted", "K00", "K10", "K21", "K31", + "R00", "R11", "R00Rough", "R11Rough", "invR00Approx", "invR11Approx", "invR00Cor", "invR11Cor", + "invR00", "invR11", "C00", "C01", "C11", "C22", "C23", "C33", + "r0Shifted", "r1Shifted", "r02", "r12", "chi20", "chi21"}; + + void KalmanFilterFormats::endJob(std::stringstream& ss) { const int wName = - strlen(*max_element(variableKFstrs_.begin(), variableKFstrs_.end(), [](const auto& a, const auto& b) { - return strlen(a) < strlen(b); + std::strlen(*std::max_element(variableKFstrs_.begin(), variableKFstrs_.end(), [](const auto& a, const auto& b) { + return std::strlen(a) < std::strlen(b); })); - static constexpr int wWidth = 3; - for (VariableKF v = VariableKF::begin; v != VariableKF::end; v = VariableKF(+v + 1)) { - const pair& range = format(v).rangeActual(); - const double r = format(v).twos() ? max(abs(range.first), abs(range.second)) * 2. : range.second; - const int width = ceil(log2(r / format(v).base())); - cout << setw(wName) << *next(variableKFstrs_.begin(), +v) << ": " << setw(wWidth) << width << " " << setw(wWidth) - << format(v).width() << " | " << setw(wWidth) << format(v).width() - width << endl; + for (VariableKF v = VariableKF::begin; v != VariableKF::dH; v = VariableKF(+v + 1)) { + const double r = + format(v).twos() ? std::max(std::abs(format(v).min()), std::abs(format(v).max())) * 2. : format(v).max(); + const int delta = format(v).width() - ceil(log2(r / format(v).base())); + ss << std::setw(wName) << *std::next(variableKFstrs_.begin(), +v) << ": "; + ss << std::setw(3) << (delta == -2147483648 ? "-" : std::to_string(delta)) << std::endl; } } - KalmanFilterFormats::KalmanFilterFormats() : iConfig_(), dataFormats_(nullptr), setup_(nullptr) { - formats_.reserve(+VariableKF::end); - } + KalmanFilterFormats::KalmanFilterFormats() { formats_.reserve(+VariableKF::end); } - KalmanFilterFormats::KalmanFilterFormats(const ParameterSet& iConfig, const DataFormats* dataFormats) - : iConfig_(dataFormats->hybrid() ? iConfig.getParameter("hybrid") - : iConfig.getParameter("tmtt")), - dataFormats_(dataFormats), - setup_(dataFormats_->setup()) { - formats_.reserve(+VariableKF::end); + void KalmanFilterFormats::beginRun(const DataFormats* dataFormats, const ConfigKF& iConfig) { + dataFormats_ = dataFormats; + iConfig_ = iConfig; fillFormats(); } template void KalmanFilterFormats::fillFormats() { - formats_.emplace_back(FormatKF(dataFormats_, iConfig_)); - if constexpr (++it != VariableKF::end) - fillFormats<++it>(); + formats_.emplace_back(makeDataFormat(dataFormats_, iConfig_)); + if constexpr (it + 1 != VariableKF::end) + fillFormats(); } - DataFormatKF::DataFormatKF(const VariableKF& v, bool twos) + DataFormatKF::DataFormatKF( + const VariableKF& v, bool twos, bool enableIntegerEmulation, int width, double base, double range) : v_(v), twos_(twos), - width_(0), - base_(1.), - range_(0.), - rangeActual_(numeric_limits::max(), numeric_limits::lowest()) {} + enableIntegerEmulation_(enableIntegerEmulation), + width_(width), + base_(base), + range_(range), + min_(std::numeric_limits::max()), + abs_(std::numeric_limits::max()), + max_(std::numeric_limits::lowest()) {} // returns false if data format would oferflow for this double value bool DataFormatKF::inRange(double d) const { @@ -72,376 +68,578 @@ namespace trackerTFP { } void DataFormatKF::updateRangeActual(double d) { - rangeActual_ = make_pair(min(rangeActual_.first, d), max(rangeActual_.second, d)); - if (!inRange(d)) { - string v = *next(variableKFstrs_.begin(), +v_); + min_ = std::min(min_, d); + abs_ = std::min(abs_, std::abs(d)); + max_ = std::max(max_, d); + if (enableIntegerEmulation_ && !inRange(d)) { + std::string v = *std::next(variableKFstrs_.begin(), +v_); cms::Exception exception("out_of_range"); exception.addContext("trackerTFP:DataFormatKF::updateRangeActual"); exception << "Variable " << v << " = " << d << " is out of range " << (twos_ ? -range_ / 2. : 0) << " to " - << (twos_ ? range_ / 2. : range_) << "." << endl; + << (twos_ ? range_ / 2. : range_) << "." << std::endl; if (twos_ || d >= 0.) - exception.addAdditionalInfo("Consider raising BaseShift" + v + " in KalmnaFilterFormats_cfi.py."); + exception.addAdditionalInfo("Consider raising BaseShift" + v + " in KalmanFilterFormats_cfi.py"); + exception.addAdditionalInfo("Consider disabling integer emulation in KalmanFilterFormats_cfi.py"); throw exception; } } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::x0, true) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& input = dataFormats->format(Variable::inv2R, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftx0"); - base_ = pow(2, baseShift) * input.base(); - width_ = dataFormats->setup()->widthDSPbb(); - calcRange(); + const int baseShift = iConfig.baseShiftx0_; + const double base = std::pow(2, baseShift) * input.base(); + const int width = dataFormats->setup()->widthDSPbb(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::x0, true, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::x1, true) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& input = dataFormats->format(Variable::phiT, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftx1"); - base_ = pow(2, baseShift) * input.base(); - width_ = dataFormats->setup()->widthDSPbb(); - calcRange(); + const int baseShift = iConfig.baseShiftx1_; + const double base = std::pow(2, baseShift) * input.base(); + const int width = dataFormats->setup()->widthDSPbb(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::x1, true, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::x2, true) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& input = dataFormats->format(Variable::cot, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftx2"); - base_ = pow(2, baseShift) * input.base(); - width_ = dataFormats->setup()->widthDSPbb(); - calcRange(); + const int baseShift = iConfig.baseShiftx2_; + const double base = std::pow(2, baseShift) * input.base(); + const int width = dataFormats->setup()->widthDSPbb(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::x2, true, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::x3, true) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& input = dataFormats->format(Variable::zT, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftx3"); - base_ = pow(2, baseShift) * input.base(); - width_ = dataFormats->setup()->widthDSPbb(); - calcRange(); + const int baseShift = iConfig.baseShiftx3_; + const double base = std::pow(2, baseShift) * input.base(); + const int width = dataFormats->setup()->widthDSPbb(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::x3, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& ctb = dataFormats->format(Variable::r, Process::ctb); + const double base = ctb.base(); + const int width = ctb.width(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::H00, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& ctb = dataFormats->format(Variable::r, Process::ctb); + const double base = ctb.base(); + const double rangeMin = 2. * dataFormats->setup()->maxRz(); + const int width = std::ceil(std::log2(rangeMin / base)); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::H12, true, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::H00, true) { - const DataFormat& kfin = dataFormats->format(Variable::r, Process::kfin); - base_ = kfin.base(); - width_ = kfin.width(); - range_ = kfin.range(); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& ctb = dataFormats->format(Variable::phi, Process::ctb); + const double base = ctb.base(); + const int width = ctb.width(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::m0, true, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::H12, true) { - const Setup* setup = dataFormats->setup(); - const DataFormat& kfin = dataFormats->format(Variable::r, Process::kfin); - base_ = kfin.base(); - range_ = 2. * max(abs(setup->outerRadius() - setup->chosenRofZ()), abs(setup->innerRadius() - setup->chosenRofZ())); - width_ = ceil(log2(range_ / base_)); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& ctb = dataFormats->format(Variable::z, Process::ctb); + const double base = ctb.base(); + const int width = ctb.width(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::m1, true, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::m0, true) { - const DataFormat& kfin = dataFormats->format(Variable::phi, Process::kfin); - base_ = kfin.base(); - width_ = kfin.width(); - range_ = kfin.range(); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& dPhi = dataFormats->format(Variable::dPhi, Process::ctb); + const DataFormatKF S01 = makeDataFormat(dataFormats, iConfig); + const double range = dPhi.range() * dPhi.range() * 4.; + const double base = S01.base(); + const int width = std::ceil(std::log2(range / base) - 1.e-11); + return DataFormatKF(VariableKF::v0, false, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::m1, true) { - const DataFormat& kfin = dataFormats->format(Variable::z, Process::kfin); - base_ = kfin.base(); - width_ = kfin.width(); - range_ = kfin.range(); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& dZ = dataFormats->format(Variable::dZ, Process::ctb); + const DataFormatKF S13 = makeDataFormat(dataFormats, iConfig); + const double range = dZ.range() * dZ.range() * 4.; + const double base = S13.base(); + const int width = std::ceil(std::log2(range / base) - 1.e-11); + return DataFormatKF(VariableKF::v1, false, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::v0, false) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftv0"); - base_ = pow(2., baseShift) * x1.base() * x1.base(); - width_ = dataFormats->setup()->widthDSPbu(); - calcRange(); + const int baseShift = iConfig.baseShiftr0_; + const double base = std::pow(2., baseShift) * x1.base(); + const int width = dataFormats->setup()->widthDSPbb(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::r0, true, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::v1, true) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftv1"); - base_ = pow(2., baseShift) * x3.base() * x3.base(); - width_ = dataFormats->setup()->widthDSPbu(); - calcRange(); + const int baseShift = iConfig.baseShiftr1_; + const double base = std::pow(2., baseShift) * x3.base(); + const int width = dataFormats->setup()->widthDSPbb(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::r1, true, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::r0, true) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x0 = dataFormats->format(Variable::inv2R, Process::kf); + const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.baseShiftS00_; + const double base = std::pow(2., baseShift) * x0.base() * x1.base(); + const int width = dataFormats->setup()->widthDSPab(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::S00, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftr0"); - base_ = pow(2., baseShift) * x1.base(); - width_ = dataFormats->setup()->widthDSPbb(); - calcRange(); + const int baseShift = iConfig.baseShiftS01_; + const double base = std::pow(2., baseShift) * x1.base() * x1.base(); + const int width = dataFormats->setup()->widthDSPab(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::S01, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x2 = dataFormats->format(Variable::cot, Process::kf); + const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.baseShiftS12_; + const double base = std::pow(2., baseShift) * x2.base() * x3.base(); + const int width = dataFormats->setup()->widthDSPab(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::S12, true, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::r1, true) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftr1"); - base_ = pow(2., baseShift) * x3.base(); - width_ = dataFormats->setup()->widthDSPbb(); - calcRange(); + const int baseShift = iConfig.baseShiftS13_; + const double base = std::pow(2., baseShift) * x3.base() * x3.base(); + const int width = dataFormats->setup()->widthDSPab(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::S13, true, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::S00, true) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& x0 = dataFormats->format(Variable::inv2R, Process::kf); const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftS00"); - base_ = pow(2., baseShift) * x0.base() * x1.base(); - width_ = dataFormats->setup()->widthDSPbb(); - calcRange(); + const int baseShift = iConfig.baseShiftS00Shifted_; + const double base = std::pow(2., baseShift) * x0.base() * x1.base(); + const int width = dataFormats->setup()->widthDSPab(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::S00Shifted, true, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::S01, true) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftS01"); - base_ = pow(2., baseShift) * x1.base() * x1.base(); - width_ = dataFormats->setup()->widthDSPbb(); - calcRange(); + const int baseShift = iConfig.baseShiftS01Shifted_; + const double base = std::pow(2., baseShift) * x1.base() * x1.base(); + const int width = dataFormats->setup()->widthDSPab(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::S01Shifted, true, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::S12, true) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& x2 = dataFormats->format(Variable::cot, Process::kf); const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftS12"); - base_ = pow(2., baseShift) * x2.base() * x3.base(); - width_ = dataFormats->setup()->widthDSPbb(); - calcRange(); + const int baseShift = iConfig.baseShiftS12Shifted_; + const double base = std::pow(2., baseShift) * x2.base() * x3.base(); + const int width = dataFormats->setup()->widthDSPab(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::S12Shifted, true, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::S13, true) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftS13"); - base_ = pow(2., baseShift) * x3.base() * x3.base(); - width_ = dataFormats->setup()->widthDSPbb(); - calcRange(); + const int baseShift = iConfig.baseShiftS13Shifted_; + const double base = std::pow(2., baseShift) * x3.base() * x3.base(); + const int width = dataFormats->setup()->widthDSPab(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::S13Shifted, true, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::K00, true) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& x0 = dataFormats->format(Variable::inv2R, Process::kf); const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftK00"); - base_ = pow(2., baseShift) * x0.base() / x1.base(); - width_ = dataFormats->setup()->widthDSPab(); - calcRange(); + const int baseShift = iConfig.baseShiftK00_; + const double base = std::pow(2., baseShift) * x0.base() / x1.base(); + const int width = dataFormats->setup()->widthDSPbb(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::K00, true, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::K10, true) { - const int baseShift = iConfig.getParameter("BaseShiftK10"); - base_ = pow(2., baseShift); - width_ = dataFormats->setup()->widthDSPab(); - calcRange(); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const int baseShift = iConfig.baseShiftK10_; + const double base = std::pow(2., baseShift); + const int width = dataFormats->setup()->widthDSPbb(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::K10, true, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::K21, true) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& x2 = dataFormats->format(Variable::cot, Process::kf); const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftK21"); - base_ = pow(2., baseShift) * x2.base() / x3.base(); - width_ = dataFormats->setup()->widthDSPab(); - calcRange(); + const int baseShift = iConfig.baseShiftK21_; + const double base = std::pow(2., baseShift) * x2.base() / x3.base(); + const int width = dataFormats->setup()->widthDSPbb(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::K21, true, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::K31, true) { - const int baseShift = iConfig.getParameter("BaseShiftK31"); - base_ = pow(2., baseShift); - width_ = dataFormats->setup()->widthDSPab(); - calcRange(); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const int baseShift = iConfig.baseShiftK31_; + const double base = std::pow(2., baseShift); + const int width = dataFormats->setup()->widthDSPbb(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::K31, true, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::R00, false) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftR00"); - base_ = pow(2., baseShift) * x1.base() * x1.base(); - width_ = dataFormats->setup()->widthDSPbu(); - calcRange(); + const int baseShift = iConfig.baseShiftR00_; + const int width = iConfig.widthR00_; + const double base = std::pow(2., baseShift) * x1.base() * x1.base(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::R00, false, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::R11, false) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftR11"); - base_ = pow(2., baseShift) * x3.base() * x3.base(); - width_ = dataFormats->setup()->widthDSPbu(); - calcRange(); + const int baseShift = iConfig.baseShiftR11_; + const int width = iConfig.widthR11_; + const double base = std::pow(2., baseShift) * x3.base() * x3.base(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::R11, false, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::R00Rough, false) { - const FormatKF R00(dataFormats, iConfig); - width_ = dataFormats->setup()->widthAddrBRAM18(); - range_ = R00.range(); - const int baseShift = R00.width() - width_; - base_ = pow(2., baseShift) * R00.base(); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF R00 = makeDataFormat(dataFormats, iConfig); + const int width = dataFormats->setup()->widthAddrBRAM18(); + const double range = R00.range(); + const int baseShift = R00.width() - width - 1; + const double base = std::pow(2., baseShift) * R00.base(); + return DataFormatKF(VariableKF::R00Rough, false, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::R11Rough, false) { - const FormatKF R11(dataFormats, iConfig); - width_ = dataFormats->setup()->widthAddrBRAM18(); - range_ = R11.range(); - const int baseShift = R11.width() - width_; - base_ = pow(2., baseShift) * R11.base(); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF R11 = makeDataFormat(dataFormats, iConfig); + const int width = dataFormats->setup()->widthAddrBRAM18(); + const double range = R11.range(); + const int baseShift = R11.width() - width - 1; + const double base = std::pow(2., baseShift) * R11.base(); + return DataFormatKF(VariableKF::R11Rough, false, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::invR00Approx, false) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftInvR00Approx"); - base_ = pow(2., baseShift) / x1.base() / x1.base(); - width_ = dataFormats->setup()->widthDSPbu(); - calcRange(); + const int baseShift = iConfig.baseShiftInvR00Approx_; + const double base = std::pow(2., baseShift) / x1.base() / x1.base(); + const int width = dataFormats->setup()->widthDSPbu(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::invR00Approx, false, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::invR11Approx, false) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftInvR11Approx"); - base_ = pow(2., baseShift) / x3.base() / x3.base(); - width_ = dataFormats->setup()->widthDSPbu(); - calcRange(); + const int baseShift = iConfig.baseShiftInvR11Approx_; + const double base = std::pow(2., baseShift) / x3.base() / x3.base(); + const int width = dataFormats->setup()->widthDSPbu(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::invR11Approx, false, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::invR00Cor, false) { - const int baseShift = iConfig.getParameter("BaseShiftInvR00Cor"); - base_ = pow(2., baseShift); - width_ = dataFormats->setup()->widthDSPbu(); - calcRange(); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const int baseShift = iConfig.baseShiftInvR00Cor_; + const double base = std::pow(2., baseShift); + const int width = dataFormats->setup()->widthDSPau(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::invR00Cor, false, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::invR11Cor, false) { - const int baseShift = iConfig.getParameter("BaseShiftInvR11Cor"); - base_ = pow(2., baseShift); - width_ = dataFormats->setup()->widthDSPbu(); - calcRange(); + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const int baseShift = iConfig.baseShiftInvR11Cor_; + const double base = std::pow(2., baseShift); + const int width = dataFormats->setup()->widthDSPau(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::invR11Cor, false, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::invR00, false) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftInvR00"); - base_ = pow(2., baseShift) / x1.base() / x1.base(); - width_ = dataFormats->setup()->widthDSPau(); - calcRange(); + const int baseShift = iConfig.baseShiftInvR00_; + const double base = std::pow(2., baseShift) / x1.base() / x1.base(); + const int width = dataFormats->setup()->widthDSPbu(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::invR00, false, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::invR11, false) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftInvR11"); - base_ = pow(2., baseShift) / x3.base() / x3.base(); - width_ = dataFormats->setup()->widthDSPau(); - calcRange(); + const int baseShift = iConfig.baseShiftInvR11_; + const double base = std::pow(2., baseShift) / x3.base() / x3.base(); + const int width = dataFormats->setup()->widthDSPbu(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::invR11, false, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::C00, false) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& x0 = dataFormats->format(Variable::inv2R, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftC00"); - base_ = pow(2., baseShift) * x0.base() * x0.base(); - width_ = dataFormats->setup()->widthDSPbu(); - calcRange(); + const int baseShift = iConfig.baseShiftC00_; + const int width = iConfig.widthC00_; + const double base = std::pow(2., baseShift) * x0.base() * x0.base(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::C00, false, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::C01, true) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& x0 = dataFormats->format(Variable::inv2R, Process::kf); const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftC01"); - base_ = pow(2., baseShift) * x0.base() * x1.base(); - width_ = dataFormats->setup()->widthDSPbb(); - calcRange(); + const int baseShift = iConfig.baseShiftC01_; + const int width = iConfig.widthC01_; + const double base = std::pow(2., baseShift) * x0.base() * x1.base(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::C01, true, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::C11, false) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftC11"); - base_ = pow(2., baseShift) * x1.base() * x1.base(); - width_ = dataFormats->setup()->widthDSPbu(); - calcRange(); + const int baseShift = iConfig.baseShiftC11_; + const int width = iConfig.widthC11_; + const double base = std::pow(2., baseShift) * x1.base() * x1.base(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::C11, false, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::C22, false) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& x2 = dataFormats->format(Variable::cot, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftC22"); - base_ = pow(2., baseShift) * x2.base() * x2.base(); - width_ = dataFormats->setup()->widthDSPbu(); - calcRange(); + const int baseShift = iConfig.baseShiftC22_; + const int width = iConfig.widthC22_; + const double base = std::pow(2., baseShift) * x2.base() * x2.base(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::C22, false, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::C23, true) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& x2 = dataFormats->format(Variable::cot, Process::kf); const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftC23"); - base_ = pow(2., baseShift) * x2.base() * x3.base(); - width_ = dataFormats->setup()->widthDSPbb(); - calcRange(); + const int baseShift = iConfig.baseShiftC23_; + const int width = iConfig.widthC23_; + const double base = std::pow(2., baseShift) * x2.base() * x3.base(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::C23, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.baseShiftC33_; + const int width = iConfig.widthC33_; + const double base = std::pow(2., baseShift) * x3.base() * x3.base(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::C33, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.baseShiftr0Shifted_; + const double base = std::pow(2., baseShift) * x1.base(); + const int width = dataFormats->setup()->widthDSPbb(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::r0Shifted, true, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.baseShiftr1Shifted_; + const double base = std::pow(2., baseShift) * x3.base(); + const int width = dataFormats->setup()->widthDSPbb(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::r1Shifted, true, iConfig.enableIntegerEmulation_, width, base, range); } template <> - FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::C33, false) { + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.baseShiftr02_; + const double base = std::pow(2., baseShift) * x1.base() * x1.base(); + const int width = dataFormats->setup()->widthDSPbu(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::r02, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); - const int baseShift = iConfig.getParameter("BaseShiftC33"); - base_ = pow(2., baseShift) * x3.base() * x3.base(); - width_ = dataFormats->setup()->widthDSPbu(); - calcRange(); + const int baseShift = iConfig.baseShiftr12_; + const double base = std::pow(2., baseShift) * x3.base() * x3.base(); + const int width = dataFormats->setup()->widthDSPbu(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::r12, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const int baseShift = iConfig.baseShiftchi20_; + const double base = std::pow(2., baseShift); + const int width = dataFormats->setup()->widthDSPbu(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::chi20, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const int baseShift = iConfig.baseShiftchi21_; + const double base = std::pow(2., baseShift); + const int width = dataFormats->setup()->widthDSPbu(); + const double range = base * std::pow(2, width); + return DataFormatKF(VariableKF::chi21, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormat& ctb = dataFormats->format(Variable::r, Process::ctb); + const int width = dataFormats->setup()->widthAddrBRAM18(); + const double range = dataFormats->setup()->outerRadius() - dataFormats->setup()->innerRadius(); + const double base = ctb.base() * std::pow(2, std::ceil(std::log2(range / ctb.base())) - width); + return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF H00 = makeDataFormat(dataFormats, iConfig); + const int width = dataFormats->setup()->widthDSPbu(); + const double range = 1. / dataFormats->setup()->kfMinSeedDeltaR(); + const int baseShift = std::ceil(std::log2(range * std::pow(2., -width) * H00.base())); + const double base = std::pow(2., baseShift) / H00.base(); + return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF H00 = makeDataFormat(dataFormats, iConfig); + const int width = dataFormats->setup()->widthDSPbu(); + const double range = 1. / pow(dataFormats->setup()->kfMinSeedDeltaR(), 2); + const double baseH2 = H00.base() * H00.base(); + const int baseShift = std::ceil(std::log2(range * std::pow(2., -width) * baseH2)); + const double base = std::pow(2., baseShift) / baseH2; + return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF H00 = makeDataFormat(dataFormats, iConfig); + const int width = H00.width() + H00.width(); + const double base = H00.base() * H00.base(); + const double range = H00.range() * H00.range(); + return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF H00 = makeDataFormat(dataFormats, iConfig); + const DataFormatKF m0 = makeDataFormat(dataFormats, iConfig); + const int width = H00.width() + m0.width(); + const double base = H00.base() * m0.base(); + const double range = H00.range() * m0.range(); + return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF H12 = makeDataFormat(dataFormats, iConfig); + const DataFormatKF m1 = makeDataFormat(dataFormats, iConfig); + const int width = H12.width() + m1.width(); + const double base = H12.base() * m1.base(); + const double range = H12.range() * m1.range(); + return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF H00 = makeDataFormat(dataFormats, iConfig); + const DataFormatKF v0 = makeDataFormat(dataFormats, iConfig); + const int width = dataFormats->setup()->widthDSPab(); + const double base = H00.base() * v0.base() * pow(2, H00.width() + v0.width() - width); + const double range = H00.range() * v0.range(); + return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF H12 = makeDataFormat(dataFormats, iConfig); + const DataFormatKF v1 = makeDataFormat(dataFormats, iConfig); + const int width = dataFormats->setup()->widthDSPab(); + const double base = H12.base() * v1.base() * pow(2, H12.width() + v1.width() - width); + const double range = H12.range() * v1.range(); + return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF H00 = makeDataFormat(dataFormats, iConfig); + const DataFormatKF v0 = makeDataFormat(dataFormats, iConfig); + const int width = dataFormats->setup()->widthDSPau(); + const double base = H00.base() * H00.base() * v0.base() * pow(2, 2 * H00.width() + v0.width() - width); + const double range = H00.range() * H00.range() * v0.range(); + return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range); + } + + template <> + DataFormatKF makeDataFormat(const DataFormats* dataFormats, const ConfigKF& iConfig) { + const DataFormatKF H12 = makeDataFormat(dataFormats, iConfig); + const DataFormatKF v1 = makeDataFormat(dataFormats, iConfig); + const int width = dataFormats->setup()->widthDSPau(); + const double base = H12.base() * H12.base() * v1.base() * pow(2, 2 * H12.width() + v1.width() - width); + const double range = H12.range() * H12.range() * v1.range(); + return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range); } } // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/src/KalmanFilterFormatsRcd.cc b/L1Trigger/TrackerTFP/src/KalmanFilterFormatsRcd.cc deleted file mode 100644 index 347bd9e9db443..0000000000000 --- a/L1Trigger/TrackerTFP/src/KalmanFilterFormatsRcd.cc +++ /dev/null @@ -1,4 +0,0 @@ -#include "L1Trigger/TrackerTFP/interface/KalmanFilterFormatsRcd.h" -#include "FWCore/Framework/interface/eventsetuprecord_registration_macro.h" - -EVENTSETUP_RECORD_REG(trackerTFP::KalmanFilterFormatsRcd); diff --git a/L1Trigger/TrackerTFP/src/LayerEncoding.cc b/L1Trigger/TrackerTFP/src/LayerEncoding.cc index 0687987c3bd25..b0fc7459062ec 100644 --- a/L1Trigger/TrackerTFP/src/LayerEncoding.cc +++ b/L1Trigger/TrackerTFP/src/LayerEncoding.cc @@ -7,167 +7,147 @@ #include #include -using namespace std; -using namespace tt; - namespace trackerTFP { LayerEncoding::LayerEncoding(const DataFormats* dataFormats) : setup_(dataFormats->setup()), dataFormats_(dataFormats), - zT_(&dataFormats->format(Variable::zT, Process::zht)), - cot_(&dataFormats->format(Variable::cot, Process::zht)), - layerEncoding_(setup_->numSectorsEta(), - vector>>(pow(2, zT_->width()), vector>(pow(2, cot_->width())))), - layerEncodingMap_(setup_->numSectorsEta(), - vector>>( - pow(2, zT_->width()), vector>(pow(2, cot_->width())))), - maybeLayer_(setup_->numSectorsEta(), - vector>>(pow(2, zT_->width()), vector>(pow(2, cot_->width())))) { + zT_(&dataFormats->format(Variable::zT, Process::gp)), + layerEncoding_(std::vector>(pow(2, zT_->width()))), + maybePattern_(std::vector(pow(2, zT_->width()), TTBV(0, setup_->numLayers()))), + nullLE_(setup_->numLayers(), 0), + nullMP_(0, setup_->numLayers()) { // number of boundaries of fiducial area in r-z plane for a given set of rough r-z track parameter static constexpr int boundaries = 2; + // z at radius chosenRofZ wrt zT of sectorZT of this bin boundaries + const std::vector z0s = {-setup_->beamWindowZ(), setup_->beamWindowZ()}; // find unique sensor mouldes in r-z // allowed distance in r and z in cm between modules to consider them not unique static constexpr double delta = 1.e-3; - vector sensorModules; + std::vector sensorModules; sensorModules.reserve(setup_->sensorModules().size()); - for (const SensorModule& sm : setup_->sensorModules()) + for (const tt::SensorModule& sm : setup_->sensorModules()) sensorModules.push_back(&sm); - auto smallerR = [](const SensorModule* lhs, const SensorModule* rhs) { return lhs->r() < rhs->r(); }; - auto smallerZ = [](const SensorModule* lhs, const SensorModule* rhs) { return lhs->z() < rhs->z(); }; - auto equalRZ = [](const SensorModule* lhs, const SensorModule* rhs) { - return abs(lhs->r() - rhs->r()) < delta && abs(lhs->z() - rhs->z()) < delta; + auto smallerR = [](const tt::SensorModule* lhs, const tt::SensorModule* rhs) { return lhs->r() < rhs->r(); }; + auto smallerZ = [](const tt::SensorModule* lhs, const tt::SensorModule* rhs) { return lhs->z() < rhs->z(); }; + auto equalRZ = [](const tt::SensorModule* lhs, const tt::SensorModule* rhs) { + return std::abs(lhs->r() - rhs->r()) < delta && std::abs(lhs->z() - rhs->z()) < delta; }; - stable_sort(sensorModules.begin(), sensorModules.end(), smallerR); - stable_sort(sensorModules.begin(), sensorModules.end(), smallerZ); - sensorModules.erase(unique(sensorModules.begin(), sensorModules.end(), equalRZ), sensorModules.end()); + std::stable_sort(sensorModules.begin(), sensorModules.end(), smallerZ); + std::stable_sort(sensorModules.begin(), sensorModules.end(), smallerR); + sensorModules.erase(std::unique(sensorModules.begin(), sensorModules.end(), equalRZ), sensorModules.end()); + std::stable_sort(sensorModules.begin(), sensorModules.end(), smallerZ); + sensorModules.erase(std::unique(sensorModules.begin(), sensorModules.end(), equalRZ), sensorModules.end()); // find set of moudles for each set of rough r-z track parameter - // loop over eta sectors - for (int binEta = 0; binEta < setup_->numSectorsEta(); binEta++) { - // cotTheta of eta sector centre - const double sectorCot = (sinh(setup_->boundarieEta(binEta + 1)) + sinh(setup_->boundarieEta(binEta))) / 2.; - // z at radius choenRofZ of eta sector centre - const double sectorZT = setup_->chosenRofZ() * sectorCot; - // loop over bins in zT - for (int binZT = 0; binZT < pow(2, zT_->width()); binZT++) { - // z at radius chosenRofZ wrt zT of sectorZT of this bin centre - const double zT = zT_->floating(zT_->toSigned(binZT)); - // z at radius chosenRofZ wrt zT of sectorZT of this bin boundaries - const vector zTs = {sectorZT + zT - zT_->base() / 2., sectorZT + zT + zT_->base() / 2.}; - // loop over bins in cotTheta - for (int binCot = 0; binCot < pow(2, cot_->width()); binCot++) { - // cotTheta wrt sectorCot of this bin centre - const double cot = cot_->floating(cot_->toSigned(binCot)); - // layer ids crossed by left and right rough r-z parameter shape boundaries - vector> layers(boundaries); - map& layermaps = layerEncodingMap_[binEta][binZT][binCot]; - // cotTheta wrt sectorCot of this bin boundaries - const vector cots = {sectorCot + cot - cot_->base() / 2., sectorCot + cot + cot_->base() / 2.}; - // loop over all unique modules - for (const SensorModule* sm : sensorModules) { - // check if module is crossed by left and right rough r-z parameter shape boundaries - for (int i = 0; i < boundaries; i++) { - const int j = boundaries - i - 1; - const double zTi = zTs[sm->r() > setup_->chosenRofZ() ? i : j]; - const double coti = cots[sm->r() > setup_->chosenRofZ() ? j : i]; - // distance between module and boundary in moudle tilt angle direction - const double d = - (zTi - sm->z() + (sm->r() - setup_->chosenRofZ()) * coti) / (sm->cosTilt() - sm->sinTilt() * coti); - // compare distance with module size and add module layer id to layers if module is crossed - if (abs(d) < sm->numColumns() * sm->pitchCol() / 2.) { - layers[i].insert(sm->layerId()); - layermaps[sm->layerId()] = sm; - } - } - } - // mayber layers are given by layer ids crossed by only one booundary - set maybeLayer; - set_symmetric_difference(layers[0].begin(), - layers[0].end(), - layers[1].begin(), - layers[1].end(), - inserter(maybeLayer, maybeLayer.end())); - // layerEncoding is given by sorted layer ids crossed by any booundary - set layerEncoding; - set_union(layers[0].begin(), - layers[0].end(), - layers[1].begin(), - layers[1].end(), - inserter(layerEncoding, layerEncoding.end())); - vector& le = layerEncoding_[binEta][binZT][binCot]; - le = vector(layerEncoding.begin(), layerEncoding.end()); - vector& ml = maybeLayer_[binEta][binZT][binCot]; - ml.reserve(maybeLayer.size()); - for (int m : maybeLayer) { - int layer = distance(le.begin(), find(le.begin(), le.end(), m)); - if (layer >= setup_->numLayers()) - layer = setup_->numLayers() - 1; - ml.push_back(layer); - } - } - } - } - const bool print = false; - if (!print) - return; - static constexpr int widthLayer = 3; - static constexpr auto layerIds = {1, 2, 3, 4, 5, 6, 11, 12, 13, 14, 15}; - stringstream ss; - for (int layer : layerIds) { - auto encode = [layer, this](const vector& layers, int& l) { - const auto it = find(layers.begin(), layers.end(), layer); - if (it == layers.end()) - return false; - l = distance(layers.begin(), it); - if (l >= setup_->numLayers()) - l = setup_->numLayers() - 1; - return true; - }; - for (int binEta = 0; binEta < setup_->numSectorsEta(); binEta++) { - for (int binZT = 0; binZT < pow(2, zT_->width()); binZT++) { - for (int binCot = 0; binCot < pow(2, cot_->width()); binCot++) { - const int zT = - binZT < pow(2, zT_->width() - 1) ? binZT + pow(2, zT_->width() - 1) : binZT - pow(2, zT_->width() - 1); - const int cot = binCot < pow(2, cot_->width() - 1) ? binCot + pow(2, cot_->width() - 1) - : binCot - pow(2, cot_->width() - 1); - const vector& layers = layerEncoding_[binEta][zT][cot]; - const vector& maybes = maybeLayer_[binEta][zT][cot]; - int layerKF(-1); - if (encode(layers, layerKF)) - ss << "1" << TTBV(layerKF, widthLayer) << (encode(maybes, layerKF) ? "1" : "0"); - else - ss << "00000"; - ss << endl; - } + // loop over zT bins + for (int binZT = 0; binZT < std::pow(2, zT_->width()); binZT++) { + // z at radius chosenRofZ + const double zT = zT_->floating(zT_->toSigned(binZT)); + // z at radius chosenRofZ wrt zT of sectorZT of this bin boundaries + const std::vector zTs = {zT - zT_->base() / 2., zT + zT_->base() / 2.}; + std::vector> cots(boundaries); + for (int i = 0; i < boundaries; i++) + for (double z0 : z0s) + cots[i].push_back((zTs[i] - z0) / setup_->chosenRofZ()); + // layer ids crossed by left and right rough r-z parameter shape boundaries + std::vector> layers(boundaries); + // loop over all unique modules + for (const tt::SensorModule* sm : sensorModules) { + // check if module is crossed by left and right rough r-z parameter shape boundaries + for (int i = 0; i < boundaries; i++) { + const double zTi = zTs[i]; + const double coti = sm->r() < setup_->chosenRofZ() ? cots[i][i == 0 ? 0 : 1] : cots[i][i == 0 ? 1 : 0]; + // distance between module and boundary in moudle tilt angle direction + const double d = + (zTi - sm->z() + (sm->r() - setup_->chosenRofZ()) * coti) / (sm->cosTilt() - sm->sinTilt() * coti); + // compare distance with module size and add module layer id to layers if module is crossed + if (std::abs(d) < sm->numColumns() * sm->pitchCol() / 2.) + layers[i].insert(sm->layerId()); } } + // mayber layers are given by layer ids crossed by only one boundary + std::set maybeLayer; + std::set_symmetric_difference(layers[0].begin(), + layers[0].end(), + layers[1].begin(), + layers[1].end(), + std::inserter(maybeLayer, maybeLayer.end())); + // layerEncoding is given by sorted layer ids crossed by any boundary + std::set layerEncoding; + std::set_union(layers[0].begin(), + layers[0].end(), + layers[1].begin(), + layers[1].end(), + std::inserter(layerEncoding, layerEncoding.end())); + // fill layerEncoding_ + std::vector& le = layerEncoding_[binZT]; + le = std::vector(layerEncoding.begin(), layerEncoding.end()); + le.resize(setup_->numLayers(), -1); + // fill maybePattern_ + TTBV& mp = maybePattern_[binZT]; + for (int m : maybeLayer) + mp.set(std::min(static_cast(std::distance(le.begin(), std::find(le.begin(), le.end(), m))), + setup_->numLayers() - 1)); } - fstream file; - file.open("layerEncoding.txt", ios::out); - file << ss.rdbuf(); - file.close(); } - // encoded layer id for given eta sector, bin in zT, bin in cotThea and decoed layer id, returns -1 if layer incositent with track - const int LayerEncoding::layerIdKF(int binEta, int binZT, int binCot, int layerId) const { - const vector& layers = layerEncoding_[binEta][binZT][binCot]; - const auto it = find(layers.begin(), layers.end(), layerId); - if (it == layers.end()) - return -1; - int layer = distance(layers.begin(), it); - if (layer >= setup_->numLayers()) - layer = setup_->numLayers() - 1; - return layer; + // Set of layers for given bin in zT + const std::vector& LayerEncoding::layerEncoding(int zT) const { + const int binZT = zT_->toUnsigned(zT); + return zT_->inRange(zT) ? layerEncoding_.at(binZT) : nullLE_; + } + + // Set of layers for given zT in cm + const std::vector& LayerEncoding::layerEncoding(double zT) const { + const int binZT = zT_->integer(zT); + return layerEncoding(binZT); } - // pattern of maybe layers for given eta sector, bin in zT and bin in cotThea - TTBV LayerEncoding::maybePattern(int binEta, int binZT, int binCot) const { - TTBV ttBV(0, setup_->numLayers()); - const vector& layers = layerEncoding_[binEta][binZT][binCot]; - const vector& maybes = maybeLayer_[binEta][binZT][binCot]; - for (int m : maybes) - ttBV.set(distance(layers.begin(), find(layers.begin(), layers.end(), m))); - return ttBV; + // pattern of maybe layers for given bin in zT + const TTBV& LayerEncoding::maybePattern(int zT) const { + const int binZT = zT_->toUnsigned(zT); + return zT_->inRange(zT) ? maybePattern_[binZT] : nullMP_; + } + + // pattern of maybe layers for given zT in cm + const TTBV& LayerEncoding::maybePattern(double zT) const { + const int binZT = zT_->integer(zT); + return maybePattern(binZT); + } + + // fills numPS, num2S, numMissingPS and numMissingPS for given hitPattern and trajectory + void LayerEncoding::analyze( + int hitpattern, double cot, double z0, int& numPS, int& num2S, int& numMissingPS, int& numMissing2S) const { + // look up layer encoding nad maybe pattern + const double zT = z0 + setup_->chosenRofZ() * cot; + const std::vector& le = this->layerEncoding(zT); + const TTBV& mp = this->maybePattern(zT); + const TTBV hp(hitpattern, setup_->numLayers()); + // loop from innermost layer to outermost hitted layer + for (int layerIdKF = 0; layerIdKF <= hp.pmEncode(); layerIdKF++) { + // look up layer Id [1-6 barrel, 11-15 disks] + const int layerId = le[layerIdKF]; + // identify module type + bool ps = layerId <= setup_->numBarrelLayerPS(); + const bool barrel = layerId <= setup_->numBarrelLayer(); + if (!barrel) { + // calc disk id (0 - 4) + const int diskId = layerId - setup_->offsetLayerDisks() - setup_->offsetLayerId(); + // avergae disk z position + const double z = setup_->hybridDiskZ(diskId) * (cot < 0. ? -1. : 1.); + // innermost edge of 2S modules + const double rLimit = setup_->disk2SR(diskId, 0) - setup_->pitchCol2S(); + // trajectory radius at avergae disk z position + const double r = (z - z0) / cot; + // compare with innermost edge of 2S modules to identify PS + if (r < rLimit) + ps = true; + } + if (hp.test(layerIdKF)) // layer is hit + ps ? numPS++ : num2S++; + else if (!mp.test(layerIdKF)) // layer is not hit but should have been hitted (roughly by) trajectory + ps ? numMissingPS++ : numMissing2S++; + } } } // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/src/LayerEncodingRcd.cc b/L1Trigger/TrackerTFP/src/LayerEncodingRcd.cc deleted file mode 100644 index 785cc2f0af36f..0000000000000 --- a/L1Trigger/TrackerTFP/src/LayerEncodingRcd.cc +++ /dev/null @@ -1,4 +0,0 @@ -#include "L1Trigger/TrackerTFP/interface/LayerEncodingRcd.h" -#include "FWCore/Framework/interface/eventsetuprecord_registration_macro.h" - -EVENTSETUP_RECORD_REG(trackerTFP::LayerEncodingRcd); diff --git a/L1Trigger/TrackerTFP/src/MiniHoughTransform.cc b/L1Trigger/TrackerTFP/src/MiniHoughTransform.cc deleted file mode 100644 index c81ed02da8eb1..0000000000000 --- a/L1Trigger/TrackerTFP/src/MiniHoughTransform.cc +++ /dev/null @@ -1,317 +0,0 @@ -#include "L1Trigger/TrackerTFP/interface/MiniHoughTransform.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace edm; -using namespace tt; - -namespace trackerTFP { - - MiniHoughTransform::MiniHoughTransform(const ParameterSet& iConfig, - const Setup* setup, - const DataFormats* dataFormats, - int region) - : enableTruncation_(iConfig.getParameter("EnableTruncation")), - setup_(setup), - dataFormats_(dataFormats), - inv2R_(dataFormats_->format(Variable::inv2R, Process::ht)), - phiT_(dataFormats_->format(Variable::phiT, Process::ht)), - region_(region), - numBinsInv2R_(setup_->htNumBinsInv2R()), - numCells_(setup_->mhtNumCells()), - numNodes_(setup_->mhtNumDLBNodes()), - numChannel_(setup_->mhtNumDLBChannel()), - input_(numBinsInv2R_) {} - - // read in and organize input product (fill vector input_) - void MiniHoughTransform::consume(const StreamsStub& streams) { - auto valid = [](int sum, const FrameStub& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); }; - int nStubsHT(0); - for (int binInv2R = 0; binInv2R < numBinsInv2R_; binInv2R++) { - const StreamStub& stream = streams[region_ * numBinsInv2R_ + binInv2R]; - nStubsHT += accumulate(stream.begin(), stream.end(), 0, valid); - } - stubsHT_.reserve(nStubsHT); - stubsMHT_.reserve(nStubsHT * numCells_); - for (int binInv2R = 0; binInv2R < numBinsInv2R_; binInv2R++) { - const int inv2R = inv2R_.toSigned(binInv2R); - const StreamStub& stream = streams[region_ * numBinsInv2R_ + binInv2R]; - vector& stubs = input_[binInv2R]; - stubs.reserve(stream.size()); - // Store input stubs in vector, so rest of MHT algo can work with pointers to them (saves CPU) - for (const FrameStub& frame : stream) { - StubHT* stub = nullptr; - if (frame.first.isNonnull()) { - stubsHT_.emplace_back(frame, dataFormats_, inv2R); - stub = &stubsHT_.back(); - } - stubs.push_back(stub); - } - } - } - - // fill output products - void MiniHoughTransform::produce(StreamsStub& accepted, StreamsStub& lost) { - // fill MHT cells - vector> stubsCells(numBinsInv2R_ * numCells_); - for (int channel = 0; channel < numBinsInv2R_; channel++) - fill(channel, input_[channel], stubsCells); - // perform static load balancing - vector> streamsSLB(numBinsInv2R_); - for (int channel = 0; channel < numBinsInv2R_; channel++) { - vector> tmp(numCells_); - // gather streams to mux together: same MHT cell of 4 adjacent MHT input streams - for (int k = 0; k < numCells_; k++) - swap(tmp[k], stubsCells[(channel / numCells_) * numBinsInv2R_ + channel % numCells_ + k * numCells_]); - slb(tmp, streamsSLB[channel], lost[channel]); - } - // dynamic load balancing stage 1 - vector> streamsDLB(numBinsInv2R_); - for (int node = 0; node < numNodes_; node++) { - vector> tmp(numChannel_); - // gather streams to dynamically balance them - for (int k = 0; k < numChannel_; k++) - swap(tmp[k], streamsSLB[(node / numCells_) * numNodes_ + node % numCells_ + k * numCells_]); - dlb(tmp); - for (int k = 0; k < numChannel_; k++) - swap(tmp[k], streamsDLB[node * numChannel_ + k]); - } - // dynamic load balancing stage 2 - vector> streamsMHT(numBinsInv2R_); - for (int node = 0; node < numNodes_; node++) { - vector> tmp(numChannel_); - // gather streams to dynamically balance them - for (int k = 0; k < numChannel_; k++) - swap(tmp[k], streamsDLB[node + k * numNodes_]); - dlb(tmp); - for (int k = 0; k < numChannel_; k++) - swap(tmp[k], streamsMHT[node * numChannel_ + k]); - } - // fill output product - for (int channel = 0; channel < numBinsInv2R_; channel++) { - const vector& stubs = streamsMHT[channel]; - StreamStub& stream = accepted[region_ * numBinsInv2R_ + channel]; - stream.reserve(stubs.size()); - for (StubMHT* stub : stubs) - stream.emplace_back(stub ? stub->frame() : FrameStub()); - } - } - - // perform finer pattern recognition per track - void MiniHoughTransform::fill(int channel, const vector& stubs, vector>& streams) { - if (stubs.empty()) - return; - int id; - auto differentHT = [&id](StubHT* stub) { return id != stub->trackId(); }; - auto differentMHT = [&id](StubMHT* stub) { return !stub || id != stub->trackId(); }; - for (auto it = stubs.begin(); it != stubs.end();) { - const auto start = it; - id = (*it)->trackId(); - it = find_if(it, stubs.end(), differentHT); - const int size = distance(start, it); - // create finer track candidates stub container - vector> mhtCells(numCells_); - for (vector& mhtCell : mhtCells) - mhtCell.reserve(size); - // fill finer track candidates stub container - for (auto stub = start; stub != it; stub++) { - const double r = (*stub)->r(); - const double chi = (*stub)->phi(); - // identify finer track candidates for this stub - // 0 and 1 belong to the MHT cells with larger inv2R; 0 and 2 belong to those with smaller track PhiT - vector cells; - cells.reserve(numCells_); - const bool compA = 2. * abs(chi) < phiT_.base(); - const bool compB = 2. * abs(chi) < abs(r * inv2R_.base()); - const bool compAB = compA && compB; - if (chi >= 0. && r >= 0.) { - cells.push_back(3); - if (compA) - cells.push_back(1); - if (compAB) - cells.push_back(2); - } - if (chi >= 0. && r < 0.) { - cells.push_back(1); - if (compA) - cells.push_back(3); - if (compAB) - cells.push_back(0); - } - if (chi < 0. && r >= 0.) { - cells.push_back(0); - if (compA) - cells.push_back(2); - if (compAB) - cells.push_back(1); - } - if (chi < 0. && r < 0.) { - cells.push_back(2); - if (compA) - cells.push_back(0); - if (compAB) - cells.push_back(3); - } - // organise stubs in finer track candidates - for (int cell : cells) { - const int inv2R = cell / setup_->mhtNumBinsPhiT(); - const int phiT = cell % setup_->mhtNumBinsPhiT(); - stubsMHT_.emplace_back(**stub, phiT, inv2R); - mhtCells[cell].push_back(&stubsMHT_.back()); - } - } - // perform pattern recognition - for (int sel = 0; sel < numCells_; sel++) { - deque& stream = streams[channel * numCells_ + sel]; - vector& mhtCell = mhtCells[sel]; - set layers; - auto toLayer = [](StubMHT* stub) { return stub->layer(); }; - transform(mhtCell.begin(), mhtCell.end(), inserter(layers, layers.begin()), toLayer); - if ((int)layers.size() < setup_->mhtMinLayers()) - mhtCell.clear(); - for (StubMHT* stub : mhtCell) - stream.push_back(stub); - stream.insert(stream.end(), size - (int)mhtCell.size(), nullptr); - } - } - for (int sel = 0; sel < numCells_; sel++) { - deque& stream = streams[channel * numCells_ + sel]; - // remove all gaps between end and last stub - for (auto it = stream.end(); it != stream.begin();) - it = (*--it) ? stream.begin() : stream.erase(it); - // read out fine track cannot start before rough track has read in completely, add gaps to take this into account - int pos(0); - for (auto it = stream.begin(); it != stream.end();) { - if (!(*it)) { - it = stream.erase(it); - continue; - } - id = (*it)->trackId(); - const int s = distance(it, find_if(it, stream.end(), differentMHT)); - const int d = distance(stream.begin(), it); - pos += s; - if (d < pos) { - const int diff = pos - d; - it = stream.insert(it, diff, nullptr); - it = next(it, diff); - } else - it = stream.erase(remove(next(stream.begin(), pos), it, nullptr), it); - it = next(it, s); - } - // adjust stream start so that first output stub is in first place in case of quickest track - if (!stream.empty()) - stream.erase(stream.begin(), next(stream.begin(), setup_->mhtMinLayers())); - } - } - - // Static load balancing of inputs: mux 4 streams to 1 stream - void MiniHoughTransform::slb(vector>& inputs, vector& accepted, StreamStub& lost) const { - if (all_of(inputs.begin(), inputs.end(), [](const deque& stubs) { return stubs.empty(); })) - return; - auto size = [](int sum, const deque& stubs) { return sum = stubs.size(); }; - const int nFrames = accumulate(inputs.begin(), inputs.end(), 0, size); - accepted.reserve(nFrames); - // input fifos - vector> stacks(numCells_); - // helper for handshake - TTBV empty(-1, numCells_, true); - TTBV enable(0, numCells_); - // clock accurate firmware emulation, each while trip describes one clock tick, one stub in and one stub out per tick - while (!all_of(inputs.begin(), inputs.end(), [](const deque& d) { return d.empty(); }) or - !all_of(stacks.begin(), stacks.end(), [](const deque& d) { return d.empty(); })) { - // store stub in fifo - for (int channel = 0; channel < numCells_; channel++) { - StubMHT* stub = pop_front(inputs[channel]); - if (stub) - stacks[channel].push_back(stub); - } - // identify empty fifos - for (int channel = 0; channel < numCells_; channel++) - empty[channel] = stacks[channel].empty(); - // chose new fifo to read from if current fifo got empty - const int iEnableOld = enable.plEncode(); - if (enable.none() || empty[iEnableOld]) { - enable.reset(); - const int iNotEmpty = empty.plEncode(false); - if (iNotEmpty < numCells_) - enable.set(iNotEmpty); - } - // read from chosen fifo - const int iEnable = enable.plEncode(); - if (enable.any()) - accepted.push_back(pop_front(stacks[iEnable])); - else - // gap if no fifo has been chosen - accepted.push_back(nullptr); - } - // perform truncation if desired - if (enableTruncation_ && (int)accepted.size() > setup_->numFrames()) { - const auto limit = next(accepted.begin(), setup_->numFrames()); - auto valid = [](int sum, StubMHT* stub) { return sum + (stub ? 1 : 0); }; - const int nLost = accumulate(limit, accepted.end(), 0, valid); - lost.reserve(nLost); - for (auto it = limit; it != accepted.end(); it++) - if (*it) - lost.emplace_back((*it)->frame()); - accepted.erase(limit, accepted.end()); - } - // cosmetics -- remove gaps at the end of stream - for (auto it = accepted.end(); it != accepted.begin();) - it = (*--it) == nullptr ? accepted.erase(it) : accepted.begin(); - } - - // Dynamic load balancing of inputs: swapping parts of streams to balance the amount of tracks per stream - void MiniHoughTransform::dlb(vector>& streams) const { - if (all_of(streams.begin(), streams.end(), [](const vector& stubs) { return stubs.empty(); })) - return; - auto maxSize = [](int size, const vector& stream) { return size = max(size, (int)stream.size()); }; - const int nMax = accumulate(streams.begin(), streams.end(), 0, maxSize); - for (vector& stream : streams) - stream.resize(nMax, nullptr); - vector prevTrks(numChannel_, -1); - bool swapping(false); - vector loads(numChannel_, 0); - for (int i = 0; i < nMax; i++) { - TTBV newTrks(0, numChannel_); - for (int k = 0; k < numChannel_; k++) - if (!streams[numChannel_ - k - 1][i] && streams[k][i] && streams[k][i]->trackId() != prevTrks[k]) - newTrks.set(k); - for (int k = 0; k < numChannel_; k++) - if (newTrks[k]) - if ((swapping && loads[numChannel_ - k - 1] > loads[k]) || - (!swapping && loads[k] > loads[numChannel_ - k - 1])) - swapping = !swapping; - for (int k = 0; k < numChannel_; k++) { - if (streams[k][i]) - loads[swapping ? numChannel_ - k - 1 : k]++; - prevTrks[k] = streams[k][i] ? streams[k][i]->trackId() : -1; - } - if (swapping) - swap(streams[0][i], streams[1][i]); - } - // remove all gaps between end and last stub - for (vector& stream : streams) - for (auto it = stream.end(); it != stream.begin();) - it = (*--it) ? stream.begin() : stream.erase(it); - } - - // remove and return first element of deque, returns nullptr if empty - template - T* MiniHoughTransform::pop_front(deque& ts) const { - T* t = nullptr; - if (!ts.empty()) { - t = ts.front(); - ts.pop_front(); - } - return t; - } - -} // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/src/State.cc b/L1Trigger/TrackerTFP/src/State.cc index 739be28ddbe2a..f87050b388eb0 100644 --- a/L1Trigger/TrackerTFP/src/State.cc +++ b/L1Trigger/TrackerTFP/src/State.cc @@ -1,65 +1,38 @@ #include "L1Trigger/TrackerTFP/interface/State.h" -using namespace std; -using namespace tt; - namespace trackerTFP { - // default constructor - State::State(State* state) - : dataFormats_(state->dataFormats_), - setup_(state->setup_), - track_(state->track_), - trackId_(state->trackId_), - parent_(state->parent_), - stub_(state->stub_), - layerMap_(state->layerMap_), - hitPattern_(state->hitPattern_), - x0_(state->x0_), - x1_(state->x1_), - x2_(state->x2_), - x3_(state->x3_), - C00_(state->C00_), - C01_(state->C01_), - C11_(state->C11_), - C22_(state->C22_), - C23_(state->C23_), - C33_(state->C33_), - numSkippedLayers_(state->numSkippedLayers_), - numConsistentLayers_(state->numConsistentLayers_) {} + // + State::Stub::Stub(KalmanFilterFormats* formats, const tt::FrameStub& frame) + : stubCTB_(frame, formats->dataFormats()) { + const tt::Setup* setup = formats->setup(); + H12_ = formats->format(VariableKF::H12).digi(stubCTB_.r() + setup->chosenRofPhi() - setup->chosenRofZ()); + v0_ = formats->format(VariableKF::v0).digi(std::pow(2. * stubCTB_.dPhi(), 2)); + v1_ = formats->format(VariableKF::v1).digi(std::pow(2. * stubCTB_.dZ(), 2)); + } // proto state constructor - State::State(const DataFormats* dataFormats, TrackKFin* track, int trackId) - : dataFormats_(dataFormats), - setup_(dataFormats->setup()), + State::State(KalmanFilterFormats* formats, + TrackCTB* track, + const std::vector>& stubs, + const TTBV& maybePattern, + int trackId) + : formats_(formats), + setup_(formats->setup()), track_(track), + stubs_(stubs), + maybePattern_(maybePattern), trackId_(trackId), - parent_(nullptr), - stub_(nullptr), - layerMap_(setup_->numLayers()), hitPattern_(0, setup_->numLayers()), - numSkippedLayers_(0), - numConsistentLayers_(0) { - // initial track parameter residuals w.r.t. found track - x0_ = 0.; - x1_ = 0.; - x2_ = 0.; - x3_ = 0.; - // initial uncertainties - C00_ = pow(dataFormats_->base(Variable::inv2R, Process::kfin), 2) * pow(2, setup_->kfShiftInitialC00()); - C11_ = pow(dataFormats_->base(Variable::phiT, Process::kfin), 2) * pow(2, setup_->kfShiftInitialC11()); - C22_ = pow(dataFormats_->base(Variable::cot, Process::kfin), 2) * pow(2, setup_->kfShiftInitialC22()); - C33_ = pow(dataFormats_->base(Variable::zT, Process::kfin), 2) * pow(2, setup_->kfShiftInitialC33()); - C01_ = 0.; - C23_ = 0.; - // first stub from first layer on input track with stubs - stub_ = track->layerStub(track->hitPattern().plEncode()); - } - - // combinatoric state constructor - State::State(State* state, StubKFin* stub) : State(state) { - parent_ = state->parent(); - stub_ = stub; + trackPattern_(0, setup_->numLayers()) { + for (const std::vector& stubs : stubs_) { + if (!stubs.empty()) + trackPattern_.set(layer_); + layer_++; + } + layer_ = trackPattern_.plEncode(); + stub_ = stubs_[layer_].front(); + hitPattern_.set(layer_); } // updated state constructor @@ -70,56 +43,143 @@ namespace trackerTFP { x1_ = doubles[1]; x2_ = doubles[2]; x3_ = doubles[3]; - C00_ = doubles[4]; - C11_ = doubles[5]; - C22_ = doubles[6]; - C33_ = doubles[7]; - C01_ = doubles[8]; - C23_ = doubles[9]; - // update maps - const int layer = stub_->layer(); - hitPattern_.set(layer); - const vector& stubs = track_->layerStubs(layer); - layerMap_[layer] = distance(stubs.begin(), find(stubs.begin(), stubs.end(), stub_)); + chi20_ = doubles[4]; + chi21_ = doubles[5]; + C00_ = doubles[6]; + C11_ = doubles[7]; + C22_ = doubles[8]; + C33_ = doubles[9]; + C01_ = doubles[10]; + C23_ = doubles[11]; // pick next stub (first stub in next layer with stub) stub_ = nullptr; - if (hitPattern_.count() == setup_->kfMaxLayers()) + if (hitPattern_.count() >= setup_->kfMinLayers() || hitPattern_.count() == setup_->kfMaxLayers()) { + layer_ = 0; return; - for (int nextLayer = layer + 1; nextLayer < setup_->numLayers(); nextLayer++) { - if (track_->hitPattern(nextLayer)) { - stub_ = track_->layerStub(nextLayer); - break; - } } + layer_ = trackPattern_.plEncode(layer_ + 1, setup_->numLayers()); + if (layer_ == setup_->numLayers()) + return; + stub_ = stubs_[layer_].front(); + hitPattern_.set(layer_); } - // fills collection of stubs added so far to state - void State::fill(vector& stubs) const { - stubs.reserve(hitPattern_.count()); - State* s = parent_; - while (s) { - stubs.emplace_back(*(s->stub()), x0_, x1_, x2_, x3_); - s = s->parent(); + // combinatoric and seed building state constructor + State::State(State* state, State* parent, Stub* stub, int layer) : State(state) { + parent_ = parent; + stub_ = stub; + layer_ = layer; + hitPattern_ = parent ? parent->hitPattern() : TTBV(0, setup_->numLayers()); + hitPattern_.set(layer_); + } + + // + State* State::update(std::deque& states, int layer) { + if (!hitPattern_.test(layer) || hitPattern_.count() > setup_->kfNumSeedStubs()) + return this; + layer_ = trackPattern_.plEncode(layer_ + 1, setup_->numLayers()); + states.emplace_back(this, this, stubs_[layer_].front(), layer_); + return &states.back(); + } + + // + State* State::combSeed(std::deque& states, int layer) { + // handle trivial state + if (!hitPattern_.test(layer) || hitPattern_.count() > setup_->kfNumSeedStubs()) + return nullptr; + // pick next stub on layer + const std::vector& stubs = stubs_[layer]; + const int pos = std::distance(stubs.begin(), std::find(stubs.begin(), stubs.end(), stub_)) + 1; + if (pos < static_cast(stubs.size())) { + states.emplace_back(this, parent_, stubs[pos], layer); + return &states.back(); + } + // skip this layer + const int nextLayer = trackPattern_.plEncode(layer + 1, setup_->numLayers()); + if (gapCheck(nextLayer)) { + states.emplace_back(this, parent_, stubs_[nextLayer].front(), nextLayer); + return &states.back(); + } + return nullptr; + } + + // + State* State::comb(std::deque& states, int layer) { + // handle skipping and min reached + if (!hitPattern_.test(layer)) { + if (!stub_ && trackPattern_[layer] && hitPattern_.count() < setup_->kfMaxLayers()) { + states.emplace_back(this, parent_, stubs_[layer].front(), layer); + return &states.back(); + } + return nullptr; + } + // handle part of seed + if (hitPattern_.pmEncode() != layer) + return nullptr; + // handle multiple stubs on layer + const std::vector& stubs = stubs_[layer]; + const int pos = std::distance(stubs.begin(), find(stubs.begin(), stubs.end(), stub_)) + 1; + if (pos < static_cast(stubs.size())) { + states.emplace_back(this, parent_, stubs[pos], layer); + return &states.back(); } + // handle skip + const int nextLayer = trackPattern_.plEncode(layer + 1, setup_->numLayers()); + if (gapCheck(nextLayer)) { + states.emplace_back(this, parent_, stubs_[nextLayer].front(), nextLayer); + return &states.back(); + } + return nullptr; } - // Determine quality of completed state - void State::finish() { - auto consistent = [this](int sum, const StubKF& stub) { - static const DataFormat& phi = dataFormats_->format(Variable::phi, Process::kf); - static const DataFormat& z = dataFormats_->format(Variable::z, Process::kf); - // Check stub consistent with helix, allowing for stub uncertainty - const bool inRange0 = 2. * abs(stub.phi()) - stub.dPhi() < phi.base(); - const bool inRange1 = 2. * abs(stub.z()) - stub.dZ() < z.base(); - return sum + (inRange0 && inRange1 ? 1 : 0); - }; - vector stubs; - fill(stubs); - numConsistentLayers_ = accumulate(stubs.begin(), stubs.end(), 0, consistent); - TTBV pattern = hitPattern_; - pattern |= maybePattern(); - // Skipped layers before final stub on state - numSkippedLayers_ = pattern.count(0, hitPattern_.pmEncode(), false); + // + bool State::gapCheck(int layer) const { + if (layer >= setup_->numLayers()) + return false; + bool gap(false); + int hits(0); + int gaps(0); + for (int k = 0; k < setup_->numLayers(); k++) { + if (k == setup_->kfMaxSeedingLayer()) + if (hits < setup_->kfNumSeedStubs()) + return false; + if (hitPattern_[k]) { + gap = false; + if (++hits >= setup_->kfMinLayers() && k >= layer) + return true; + } else if (!maybePattern_[k]) { + if (gap || ++gaps > setup_->kfMaxGaps()) + return false; + gap = true; + } + } + return false; } + // copy constructor + State::State(State* state) + : formats_(state->formats_), + setup_(state->setup_), + track_(state->track_), + stubs_(state->stubs_), + maybePattern_(state->maybePattern_), + trackId_(state->trackId_), + parent_(state->parent_), + stub_(state->stub_), + layer_(state->layer_), + hitPattern_(state->hitPattern_), + trackPattern_(state->trackPattern_), + x0_(state->x0_), + x1_(state->x1_), + x2_(state->x2_), + x3_(state->x3_), + chi20_(state->chi20_), + chi21_(state->chi21_), + C00_(state->C00_), + C01_(state->C01_), + C11_(state->C11_), + C22_(state->C22_), + C23_(state->C23_), + C33_(state->C33_) {} + } // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/src/TrackFindingProcessor.cc b/L1Trigger/TrackerTFP/src/TrackFindingProcessor.cc new file mode 100644 index 0000000000000..e51476e3e69f0 --- /dev/null +++ b/L1Trigger/TrackerTFP/src/TrackFindingProcessor.cc @@ -0,0 +1,282 @@ +#include "L1Trigger/TrackerTFP/interface/TrackFindingProcessor.h" +#include "L1Trigger/TrackTrigger/interface/StubPtConsistency.h" + +#include +#include +#include +#include +#include + +namespace trackerTFP { + + TrackFindingProcessor::TrackFindingProcessor(const tt::Setup* setup, + const DataFormats* dataFormats, + const TrackQuality* trackQuality) + : setup_(setup), dataFormats_(dataFormats), trackQuality_(trackQuality) { + bfield_ = setup_->bField(); + } + + // + TrackFindingProcessor::Track::Track(const tt::FrameTrack& frameTrack, + const tt::Frame& frameTQ, + const std::vector& ttStubRefs, + const TrackQuality* tq) + : ttTrackRef_(frameTrack.first), ttStubRefs_(ttStubRefs), valid_(true) { + partials_.reserve(partial_in); + const double rangeInvR = -2. * TTTrack_TrackWord::minRinv; + const double rangePhi0 = -2. * TTTrack_TrackWord::minPhi0; + const double rangeCot = -2. * TTTrack_TrackWord::minTanl; + const double rangeZ0 = -2. * TTTrack_TrackWord::minZ0; + const double rangeD0 = -2. * TTTrack_TrackWord::minD0; + const double baseInvR = rangeInvR / std::pow(2., TTTrack_TrackWord::TrackBitWidths::kRinvSize); + const double basePhi0 = rangePhi0 / std::pow(2., TTTrack_TrackWord::TrackBitWidths::kPhiSize); + const double baseCot = rangeCot / std::pow(2., TTTrack_TrackWord::TrackBitWidths::kTanlSize); + const double baseZ0 = rangeZ0 / std::pow(2., TTTrack_TrackWord::TrackBitWidths::kZ0Size); + const double baseD0 = rangeD0 / std::pow(2., TTTrack_TrackWord::TrackBitWidths::kD0Size); + const int nLayers = TTTrack_TrackWord::TrackBitWidths::kHitPatternSize; + const TTBV other_MVAs = TTBV(0, 2 * TTTrack_TrackWord::TrackBitWidths::kMVAQualitySize); + const TTBV chi2bend = TTBV(0, TTTrack_TrackWord::TrackBitWidths::kBendChi2Size); + const TTBV valid = TTBV(1, TTTrack_TrackWord::TrackBitWidths::kValidSize); + // convert bits into nice formats + const DataFormats* df = tq->dataFormats(); + const tt::Setup* setup = df->setup(); + const TrackDR trackDR(frameTrack, df); + inv2R_ = trackDR.inv2R(); + phiT_ = trackDR.phiT(); + cot_ = trackDR.cot(); + zT_ = trackDR.zT(); + const double d0 = std::max(std::min(ttTrackRef_->d0(), -TTTrack_TrackWord::minD0), TTTrack_TrackWord::minD0); + TTBV ttBV = TTBV(frameTQ); + tq->format(VariableTQ::chi2rz).extract(ttBV, chi2rz_); + tq->format(VariableTQ::chi2rphi).extract(ttBV, chi2rphi_); + mva_ = TTBV(ttBV, numBinsMVA_).val(); + ttBV >>= numBinsMVA_; + hitPattern_ = ttBV; + channel_ = cot_ < 0. ? 0 : 1; + // convert nice formats into bits + const double z0 = zT_ - cot_ * setup->chosenRofZ(); + const double phi0 = phiT_ - inv2R_ * setup->chosenRofPhi(); + double invR = -2. * inv2R_; + if (invR < TTTrack_TrackWord::minRinv) + invR = TTTrack_TrackWord::minRinv + df->format(Variable::inv2R, Process::dr).base(); + else if (invR > -TTTrack_TrackWord::minRinv) + invR = -TTTrack_TrackWord::minRinv - df->format(Variable::inv2R, Process::dr).base(); + const double chi2rphi = chi2rphi_ / (hitPattern_.count() - 2); + const double chi2rz = chi2rz_ / (hitPattern_.count() - 2); + int chi2rphiBin(-1); + for (double d : TTTrack_TrackWord::chi2RPhiBins) + if (chi2rphi >= d) + chi2rphiBin++; + else + break; + int chi2rzBin(-1); + for (double d : TTTrack_TrackWord::chi2RZBins) + if (chi2rz >= d) + chi2rzBin++; + else + break; + if (std::abs(invR) > rangeInvR / 2.) + valid_ = false; + if (std::abs(phi0) > rangePhi0 / 2.) + valid_ = false; + if (std::abs(cot_) > rangeCot / 2.) + valid_ = false; + if (std::abs(z0) > rangeZ0 / 2.) + valid_ = false; + if (std::abs(d0) > rangeD0 / 2.) + valid_ = false; + if (!valid_) + return; + const TTBV MVA_quality(mva_, TTTrack_TrackWord::TrackBitWidths::kMVAQualitySize); + const TTBV hit_pattern(hitPattern_.resize(nLayers).val(), nLayers); + const TTBV D0(d0, baseD0, TTTrack_TrackWord::TrackBitWidths::kD0Size, true); + const TTBV Chi2rz(chi2rzBin, TTTrack_TrackWord::TrackBitWidths::kChi2RZSize); + const TTBV Z0(z0, baseZ0, TTTrack_TrackWord::TrackBitWidths::kZ0Size, true); + const TTBV tanL(cot_, baseCot, TTTrack_TrackWord::TrackBitWidths::kTanlSize, true); + const TTBV Chi2rphi(chi2rphiBin, TTTrack_TrackWord::TrackBitWidths::kChi2RPhiSize); + const TTBV Phi0(phi0, basePhi0, TTTrack_TrackWord::TrackBitWidths::kPhiSize, true); + const TTBV InvR(invR, baseInvR, TTTrack_TrackWord::TrackBitWidths::kRinvSize, true); + partials_.emplace_back((valid + InvR + Phi0 + Chi2rphi).str()); + partials_.emplace_back((tanL + Z0 + Chi2rz).str()); + partials_.emplace_back((D0 + chi2bend + hit_pattern + MVA_quality + other_MVAs).str()); + } + + // fill output products + void TrackFindingProcessor::produce(const tt::StreamsTrack& inputs, + const tt::StreamsStub& stubs, + tt::TTTracks& ttTracks, + tt::StreamsTrack& outputs) { + // organize input tracks + std::vector> streams(outputs.size()); + consume(inputs, stubs, streams); + // emualte data format f/w + produce(streams, outputs); + // produce TTTracks + produce(outputs, ttTracks); + } + + // + void TrackFindingProcessor::consume(const tt::StreamsTrack& inputs, + const tt::StreamsStub& stubs, + std::vector>& outputs) { + // count input objects + int nTracks(0); + auto valid = [](int sum, const tt::FrameTrack& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); }; + for (const tt::StreamTrack& tracks : inputs) + nTracks += std::accumulate(tracks.begin(), tracks.end(), 0, valid); + tracks_.reserve(nTracks); + // convert input data + for (int region = 0; region < setup_->numRegions(); region++) { + const int offsetTQ = region * setup_->tqNumChannel(); + const int offsetTFP = region * setup_->tfpNumChannel(); + const int offsetStub = region * setup_->numLayers(); + const tt::StreamTrack& streamDR = inputs[offsetTQ]; + const tt::StreamTrack& streamTQ = inputs[offsetTQ + 1]; + for (int channel = 0; channel < setup_->tfpNumChannel(); channel++) + outputs[offsetTFP + channel] = std::deque(streamDR.size(), nullptr); + for (int frame = 0; frame < static_cast(streamDR.size()); frame++) { + const tt::FrameTrack& frameTrack = streamDR[frame]; + const tt::Frame& frameTQ = streamTQ[frame].second; + if (frameTrack.first.isNull()) + continue; + std::vector ttStubRefs; + ttStubRefs.reserve(setup_->numLayers()); + for (int layer = 0; layer < setup_->numLayers(); layer++) { + const TTStubRef& ttStubRef = stubs[offsetStub + layer][frame].first; + if (ttStubRef.isNonnull()) + ttStubRefs.push_back(ttStubRef); + } + tracks_.emplace_back(frameTrack, frameTQ, ttStubRefs, trackQuality_); + Track& track = tracks_.back(); + outputs[offsetTFP + track.channel_][frame] = track.valid_ ? &track : nullptr; + } + // remove all gaps between end and last track + for (int channel = 0; channel < setup_->tfpNumChannel(); channel++) { + std::deque input = outputs[offsetTFP + channel]; + for (auto it = input.end(); it != input.begin();) + it = (*--it) ? input.begin() : input.erase(it); + } + } + } + + // emualte data format f/w + void TrackFindingProcessor::produce(std::vector>& inputs, tt::StreamsTrack& outputs) const { + for (int channel = 0; channel < static_cast(inputs.size()); channel++) { + std::deque& input = inputs[channel]; + std::deque stack; + std::deque output; + // clock accurate firmware emulation, each while trip describes one clock tick, one stub in and one stub out per tick + while (!input.empty() || !stack.empty()) { + output.emplace_back(tt::FrameTrack()); + tt::FrameTrack& frame = output.back(); + Track* track = pop_front(input); + if (track) + for (const PartialFrame& pf : track->partials_) + stack.emplace_back(track->ttTrackRef_, pf); + TTBV ttBV; + for (int i = 0; i < partial_out; i++) { + if (stack.empty()) { + ttBV += TTBV(0, partial_width); + continue; + } + const PartialFrameTrack& pft = stack.front(); + frame.first = pft.first; + ttBV += TTBV(pft.second.to_string()); + stack.pop_front(); + } + frame.second = ttBV.bs(); + } + // perorm truncation + if (setup_->enableTruncation() && static_cast(output.size()) > setup_->numFramesIOHigh()) + output.resize(setup_->numFramesIOHigh()); + outputs[channel] = tt::StreamTrack(output.begin(), output.end()); + } + } + + // produce TTTracks + void TrackFindingProcessor::produce(const tt::StreamsTrack& inputs, tt::TTTracks& outputs) const { + // collect input TTTrackRefs + std::vector ttTrackRefs; + ttTrackRefs.reserve(tracks_.size()); + const TTTrack* last = nullptr; + for (const tt::StreamTrack& stream : inputs) { + for (const tt::FrameTrack& frame : stream) { + const TTTrackRef& ttTrackRef = frame.first; + if (frame.first.isNull() || last == ttTrackRef.get()) + continue; + last = ttTrackRef.get(); + ttTrackRefs.push_back(ttTrackRef); + } + } + // convert input TTTrackRefs into output TTTracks + const DataFormat& dfZT = dataFormats_->format(Variable::zT, Process::gp); + outputs.reserve(ttTrackRefs.size()); + for (const TTTrackRef& ttTrackRef : ttTrackRefs) { + auto match = [&ttTrackRef](const Track& track) { return track.ttTrackRef_ == ttTrackRef; }; + const auto it = std::find_if(tracks_.begin(), tracks_.end(), match); + // TTTrack conversion + const int region = ttTrackRef->phiSector(); + const double aRinv = -2. * it->inv2R_; + const double aphi = tt::deltaPhi(it->phiT_ - it->inv2R_ * setup_->chosenRofPhi() + region * setup_->baseRegion()); + const double aTanLambda = it->cot_; + const double az0 = it->zT_ - it->cot_ * setup_->chosenRofZ(); + const double ad0 = -ttTrackRef->d0(); + const double aChi2xyfit = it->chi2rphi_; + const double aChi2zfit = it->chi2rz_; + const double trkMVA1 = (TTTrack_TrackWord::tqMVABins[it->mva_]); + static constexpr double trkMVA2 = 0.; + static constexpr double trkMVA3 = 0.; + const unsigned int aHitpattern = it->hitPattern_.val(); + const unsigned int nPar = ttTrackRef->nFitPars(); + outputs.emplace_back(aRinv, + aphi, + aTanLambda, + az0, + ad0, + aChi2xyfit, + aChi2zfit, + trkMVA1, + trkMVA2, + trkMVA3, + aHitpattern, + nPar, + bfield_); + TTTrack& ttTrack = outputs.back(); + ttTrack.setPhiSector(region); + ttTrack.setEtaSector(dfZT.toUnsigned(dfZT.integer(it->zT_))); + ttTrack.setTrackSeedType(ttTrackRef->trackSeedType()); + ttTrack.setStubRefs(it->ttStubRefs_); + ttTrack.setStubPtConsistency(StubPtConsistency::getConsistency( + ttTrack, setup_->trackerGeometry(), setup_->trackerTopology(), bfield_, nPar)); + } + } + + // produce StreamsTrack + void TrackFindingProcessor::produce(const std::vector& inputs, tt::StreamsTrack& outputs) const { + int iTrk(-1); + const TTTrack* last = nullptr; + for (tt::StreamTrack& stream : outputs) { + for (tt::FrameTrack& frame : stream) { + const TTTrackRef& ttTrackRef = frame.first; + if (ttTrackRef.isNull()) + continue; + if (last != ttTrackRef.get()) + iTrk++; + last = ttTrackRef.get(); + frame.first = inputs[iTrk]; + } + } + } + + // remove and return first element of deque, returns nullptr if empty + template + T* TrackFindingProcessor::pop_front(std::deque& ts) const { + T* t = nullptr; + if (!ts.empty()) { + t = ts.front(); + ts.pop_front(); + } + return t; + } + +} // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/src/TrackQuality.cc b/L1Trigger/TrackerTFP/src/TrackQuality.cc new file mode 100644 index 0000000000000..bba1a631e205d --- /dev/null +++ b/L1Trigger/TrackerTFP/src/TrackQuality.cc @@ -0,0 +1,281 @@ +/* +Track Quality Body file +C.Brown & C.Savard 07/2020 +*/ + +#include "L1Trigger/TrackerTFP/interface/TrackQuality.h" +#include "L1Trigger/TrackTrigger/interface/StubPtConsistency.h" + +#include +#include +#include +#include "conifer.h" +#include "ap_fixed.h" + +namespace trackerTFP { + + TrackQuality::TrackQuality(const ConfigTQ& iConfig, const DataFormats* dataFormats) + : dataFormats_(dataFormats), + model_(iConfig.model_), + featureNames_(iConfig.featureNames_), + baseShiftCot_(iConfig.baseShiftCot_), + baseShiftZ0_(iConfig.baseShiftZ0_), + baseShiftAPfixed_(iConfig.baseShiftAPfixed_), + chi2rphiConv_(iConfig.chi2rphiConv_), + chi2rzConv_(iConfig.chi2rzConv_), + weightBinFraction_(iConfig.weightBinFraction_), + dzTruncation_(iConfig.dzTruncation_), + dphiTruncation_(iConfig.dphiTruncation_) { + dataFormatsTQ_.reserve(+VariableTQ::end); + fillDataFormats(iConfig); + } + + // constructs TQ data formats + template + void TrackQuality::fillDataFormats(const ConfigTQ& iConfig) { + dataFormatsTQ_.emplace_back(makeDataFormat(dataFormats_, iConfig)); + if constexpr (v + 1 != VariableTQ::end) + fillDataFormats(iConfig); + } + + // TQ MVA bin conversion LUT + constexpr std::array TrackQuality::mvaPreSigBins() const { + std::array lut = {}; + lut[0] = -16.; + for (int i = 1; i < numBinsMVA_; i++) + lut[i] = invSigmoid(TTTrack_TrackWord::tqMVABins[i]); + return lut; + } + + // + template + int TrackQuality::toBin(const T& bins, double d) const { + int bin = 0; + for (; bin < static_cast(bins.size()) - 1; bin++) + if (d < bins[bin + 1]) + break; + return bin; + } + + // Helper function to convert mvaPreSig to bin + int TrackQuality::toBinMVA(double mva) const { + static const std::array bins = mvaPreSigBins(); + return toBin(bins, mva); + } + + // Helper function to convert chi2B to bin + int TrackQuality::toBinChi2B(double chi2B) const { + static const std::array bins = TTTrack_TrackWord::bendChi2Bins; + return toBin(bins, chi2B); + } + + // Helper function to convert chi2rphi to bin + int TrackQuality::toBinchi2rphi(double chi2rphi) const { + static const std::array bins = TTTrack_TrackWord::chi2RPhiBins; + double chi2 = chi2rphi * chi2rphiConv_; + return toBin(bins, chi2); + } + + // Helper function to convert chi2rz to bin + int TrackQuality::toBinchi2rz(double chi2rz) const { + static const std::array bins = TTTrack_TrackWord::chi2RZBins; + double chi2 = chi2rz * chi2rzConv_; + return toBin(bins, chi2); + } + + TrackQuality::Track::Track(const tt::FrameTrack& frameTrack, const tt::StreamStub& streamStub, const TrackQuality* tq) + : frameTrack_(frameTrack), streamStub_(streamStub) { + static const DataFormats* df = tq->dataFormats(); + static const tt::Setup* setup = df->setup(); + const TrackDR track(frameTrack, df); + double trackchi2rphi(0.); + double trackchi2rz(0.); + TTBV hitPattern(0, streamStub.size()); + std::vector ttStubRefs; + ttStubRefs.reserve(setup->numLayers()); + for (int layer = 0; layer < (int)streamStub.size(); layer++) { + const tt::FrameStub& frameStub = streamStub[layer]; + if (frameStub.first.isNull()) + continue; + const StubKF stub(frameStub, df); + hitPattern.set(layer); + ttStubRefs.push_back(frameStub.first); + const double m20 = tq->format(VariableTQ::m20).digi(std::pow(stub.phi(), 2)); + const double m21 = tq->format(VariableTQ::m21).digi(std::pow(stub.z(), 2)); + const double invV0 = tq->format(VariableTQ::invV0).digi(1. / std::pow(stub.dPhi(), 2)); + const double invV1 = tq->format(VariableTQ::invV1).digi(1. / std::pow(stub.dZ(), 2)); + const double stubchi2rphi = tq->format(VariableTQ::chi2rphi).digi(m20 * invV0); + const double stubchi2rz = tq->format(VariableTQ::chi2rz).digi(m21 * invV1); + trackchi2rphi += stubchi2rphi; + trackchi2rz += stubchi2rz; + } + if (trackchi2rphi > tq->range(VariableTQ::chi2rphi)) + trackchi2rphi = tq->range(VariableTQ::chi2rphi) - tq->base(VariableTQ::chi2rphi) / 2.; + if (trackchi2rz > tq->range(VariableTQ::chi2rz)) + trackchi2rz = tq->range(VariableTQ::chi2rz) - tq->base(VariableTQ::chi2rz) / 2.; + // calc bdt inputs + const double cot = tq->scaleCot(df->format(Variable::cot, Process::dr).integer(track.cot())); + const double z0 = + tq->scaleZ0(df->format(Variable::zT, Process::kf).integer(track.zT() - setup->chosenRofZ() * track.cot())); + const int nstub = hitPattern.count(); + const int n_missint = hitPattern.count(hitPattern.plEncode() + 1, setup->numLayers(), false); + // use simulation for bendchi2 + const TTTrackRef& ttTrackRef = frameTrack.first; + const int region = ttTrackRef->phiSector(); + const double aRinv = -.5 * track.inv2R(); + const double aphi = + tt::deltaPhi(track.phiT() - track.inv2R() * setup->chosenRofPhi() + region * setup->baseRegion()); + const double aTanLambda = track.cot(); + const double az0 = track.zT() - track.cot() * setup->chosenRofZ(); + const double ad0 = ttTrackRef->d0(); + static constexpr double aChi2xyfit = 0.; + static constexpr double aChi2zfit = 0.; + static constexpr double trkMVA1 = 0.; + static constexpr double trkMVA2 = 0.; + static constexpr double trkMVA3 = 0.; + static constexpr unsigned int aHitpattern = 0; + const unsigned int nPar = ttTrackRef->nFitPars(); + static const double Bfield = setup->bField(); + TTTrack ttTrack( + aRinv, aphi, aTanLambda, az0, ad0, aChi2xyfit, aChi2zfit, trkMVA1, trkMVA2, trkMVA3, aHitpattern, nPar, Bfield); + ttTrack.setStubRefs(ttStubRefs); + ttTrack.setStubPtConsistency( + StubPtConsistency::getConsistency(ttTrack, setup->trackerGeometry(), setup->trackerTopology(), Bfield, nPar)); + const int chi2B = tq->toBinChi2B(ttTrack.chi2Bend()); + const int chi2rphi = tq->toBinchi2rphi(trackchi2rphi); + const int chi2rz = tq->toBinchi2rz(trackchi2rz); + // load in bdt + conifer::BDT, ap_fixed<10, 5>> bdt(tq->model().fullPath()); + // collect features and classify using bdt + const std::vector>& output = + bdt.decision_function({cot, z0, chi2B, nstub, n_missint, chi2rphi, chi2rz}); + const float mva = output[0].to_float(); + // fill frame + TTBV ttBV = hitPattern; + ttBV += TTBV(tq->toBinMVA(mva), widthMVA_); + tq->format(VariableTQ::chi2rphi).attach(trackchi2rphi, ttBV); + tq->format(VariableTQ::chi2rz).attach(trackchi2rz, ttBV); + frame_ = ttBV.bs(); + } + + template <> + DataFormat makeDataFormat(const DataFormats* dataFormats, const ConfigTQ& iConfig) { + const DataFormat phi = makeDataFormat(dataFormats->setup()); + const int width = iConfig.widthM20_; + const double base = std::pow(phi.base(), 2) * pow(2., width - phi.width()); + const double range = base * std::pow(2, width); + return DataFormat(false, width, base, range); + } + template <> + DataFormat makeDataFormat(const DataFormats* dataFormats, const ConfigTQ& iConfig) { + const DataFormat z = makeDataFormat(dataFormats->setup()); + const int width = iConfig.widthM21_; + const double base = std::pow(z.base(), 2) * std::pow(2., width - z.width()); + const double range = base * std::pow(2, width); + return DataFormat(false, width, base, range); + } + template <> + DataFormat makeDataFormat(const DataFormats* dataFormats, const ConfigTQ& iConfig) { + const DataFormat dPhi = makeDataFormat(dataFormats->setup()); + const int width = iConfig.widthInvV0_; + const double range = 4.0 / std::pow(dPhi.base(), 2); + const double base = range * std::pow(2, -width); + return DataFormat(false, width, base, range); + } + template <> + DataFormat makeDataFormat(const DataFormats* dataFormats, const ConfigTQ& iConfig) { + const DataFormat dZ = makeDataFormat(dataFormats->setup()); + const int width = iConfig.widthInvV1_; + const double range = 4.0 / std::pow(dZ.base(), 2); + const double base = range * std::pow(2, -width); + return DataFormat(false, width, base, range); + } + template <> + DataFormat makeDataFormat(const DataFormats* dataFormats, const ConfigTQ& iConfig) { + const DataFormat m20 = makeDataFormat(dataFormats, iConfig); + const DataFormat invV0 = makeDataFormat(dataFormats, iConfig); + const int shift = iConfig.baseShiftchi2rphi_; + const int width = iConfig.widthchi2rphi_; + const double base = std::pow(2., shift); + const double range = base * std::pow(2, width); + return DataFormat(false, width, base, range); + } + template <> + DataFormat makeDataFormat(const DataFormats* dataFormats, const ConfigTQ& iConfig) { + const DataFormat m21 = makeDataFormat(dataFormats, iConfig); + const DataFormat invV1 = makeDataFormat(dataFormats, iConfig); + const int shift = iConfig.baseShiftchi2rz_; + const int width = iConfig.widthchi2rz_; + const double base = std::pow(2., shift); + const double range = base * std::pow(2, width); + return DataFormat(false, width, base, range); + } + + // Controls the conversion between TTTrack features and ML model training features + std::vector TrackQuality::featureTransform(TTTrack& aTrack, + std::vector const& featureNames) const { + // List input features for MVA in proper order below, the current features options are + // {"phi", "eta", "z0", "bendchi2_bin", "nstub", "nlaymiss_interior", "chi2rphi_bin", + // "chi2rz_bin"} + // + // To use more features, they must be created here and added to feature_map below + std::vector transformedFeatures; + // Define feature map, filled as features are generated + std::map feature_map; + // -------- calculate feature variables -------- + // calculate number of missed interior layers from hitpattern + int tmp_trk_hitpattern = aTrack.hitPattern(); + int nbits = std::floor(std::log2(tmp_trk_hitpattern)) + 1; + int lay_i = 0; + int tmp_trk_nlaymiss_interior = 0; + bool seq = false; + for (int i = 0; i < nbits; i++) { + lay_i = ((1 << i) & tmp_trk_hitpattern) >> i; //0 or 1 in ith bit (right to left) + + if (lay_i && !seq) + seq = true; //sequence starts when first 1 found + if (!lay_i && seq) + tmp_trk_nlaymiss_interior++; + } + // binned chi2 variables + int tmp_trk_bendchi2_bin = aTrack.getBendChi2Bits(); + int tmp_trk_chi2rphi_bin = aTrack.getChi2RPhiBits(); + int tmp_trk_chi2rz_bin = aTrack.getChi2RZBits(); + // get the nstub + std::vector stubRefs = aTrack.getStubRefs(); + int tmp_trk_nstub = stubRefs.size(); + // get other variables directly from TTTrack + float tmp_trk_z0 = aTrack.z0(); + float tmp_trk_z0_scaled = tmp_trk_z0 / abs(aTrack.minZ0); + float tmp_trk_phi = aTrack.phi(); + float tmp_trk_eta = aTrack.eta(); + float tmp_trk_tanl = aTrack.tanL(); + // -------- fill the feature map --------- + feature_map["nstub"] = float(tmp_trk_nstub); + feature_map["z0"] = tmp_trk_z0; + feature_map["z0_scaled"] = tmp_trk_z0_scaled; + feature_map["phi"] = tmp_trk_phi; + feature_map["eta"] = tmp_trk_eta; + feature_map["nlaymiss_interior"] = float(tmp_trk_nlaymiss_interior); + feature_map["bendchi2_bin"] = tmp_trk_bendchi2_bin; + feature_map["chi2rphi_bin"] = tmp_trk_chi2rphi_bin; + feature_map["chi2rz_bin"] = tmp_trk_chi2rz_bin; + feature_map["tanl"] = tmp_trk_tanl; + // fill tensor with track params + transformedFeatures.reserve(featureNames.size()); + for (const std::string& feature : featureNames) + transformedFeatures.push_back(feature_map[feature]); + return transformedFeatures; + } + + // Passed by reference a track without MVA filled, method fills the track's MVA field + void TrackQuality::setL1TrackQuality(TTTrack& aTrack) const { + // load in bdt + conifer::BDT bdt(this->model_.fullPath()); + // collect features and classify using bdt + std::vector inputs = featureTransform(aTrack, this->featureNames_); + std::vector output = bdt.decision_function(inputs); + aTrack.settrkMVA1(1. / (1. + exp(-output.at(0)))); + } + +} // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/src/ZHoughTransform.cc b/L1Trigger/TrackerTFP/src/ZHoughTransform.cc deleted file mode 100644 index dde6aa0e0bc8e..0000000000000 --- a/L1Trigger/TrackerTFP/src/ZHoughTransform.cc +++ /dev/null @@ -1,322 +0,0 @@ -#include "L1Trigger/TrackerTFP/interface/ZHoughTransform.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace edm; -using namespace tt; - -namespace trackerTFP { - - ZHoughTransform::ZHoughTransform(const ParameterSet& iConfig, - const Setup* setup, - const DataFormats* dataFormats, - int region) - : enableTruncation_(iConfig.getParameter("EnableTruncation")), - setup_(setup), - dataFormats_(dataFormats), - region_(region), - input_(dataFormats->numChannel(Process::mht)), - stage_(0) {} - - // read in and organize input product (fill vector input_) - void ZHoughTransform::consume(const StreamsStub& streams) { - auto valid = [](int sum, const FrameStub& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); }; - const int offset = region_ * dataFormats_->numChannel(Process::mht); - int nStubsMHT(0); - for (int channel = 0; channel < dataFormats_->numChannel(Process::mht); channel++) { - const StreamStub& stream = streams[offset + channel]; - nStubsMHT += accumulate(stream.begin(), stream.end(), 0, valid); - } - stubsZHT_.reserve(nStubsMHT * (setup_->zhtNumCells() * setup_->zhtNumStages())); - for (int channel = 0; channel < dataFormats_->numChannel(Process::mht); channel++) { - const StreamStub& stream = streams[offset + channel]; - vector& stubs = input_[channel]; - stubs.reserve(stream.size()); - // Store input stubs in vector, so rest of ZHT algo can work with pointers to them (saves CPU) - for (const FrameStub& frame : stream) { - StubZHT* stub = nullptr; - if (frame.first.isNonnull()) { - StubMHT stubMHT(frame, dataFormats_); - stubsZHT_.emplace_back(stubMHT); - stub = &stubsZHT_.back(); - } - stubs.push_back(stub); - } - } - } - - // fill output products - void ZHoughTransform::produce(StreamsStub& accepted, StreamsStub& lost) { - vector> streams(dataFormats_->numChannel(Process::mht)); - for (int channel = 0; channel < dataFormats_->numChannel(Process::mht); channel++) - streams[channel] = deque(input_[channel].begin(), input_[channel].end()); - vector> stubsCells(dataFormats_->numChannel(Process::mht) * setup_->zhtNumCells()); - for (stage_ = 0; stage_ < setup_->zhtNumStages(); stage_++) { - // fill ZHT cells - for (int channel = 0; channel < dataFormats_->numChannel(Process::mht); channel++) - fill(channel, streams[channel], stubsCells); - // perform static load balancing - for (int channel = 0; channel < dataFormats_->numChannel(Process::mht); channel++) { - vector> tmp(setup_->zhtNumCells()); - // gather streams to mux together: same ZHT cell of 4 adjacent ZHT input streams - for (int k = 0; k < setup_->zhtNumCells(); k++) - //swap(tmp[k], stubsCells[(channel / setup_->zhtNumCells()) * dataFormats_->numChannel(Process::mht) + channel % setup_->zhtNumCells() + k * setup_->zhtNumCells()]); - swap(tmp[k], stubsCells[channel * setup_->zhtNumCells() + k]); - slb(tmp, streams[channel], lost[channel]); - } - } - // fill output product - for (int channel = 0; channel < dataFormats_->numChannel(Process::mht); channel++) { - deque& stubs = streams[channel]; - StreamStub& stream = accepted[region_ * dataFormats_->numChannel(Process::mht) + channel]; - merge(stubs, stream); - } - } - - // perform finer pattern recognition per track - void ZHoughTransform::fill(int channel, const deque& stubs, vector>& streams) { - if (stubs.empty()) - return; - const double baseZT = - dataFormats_->format(Variable::zT, Process::zht).base() * pow(2, setup_->zhtNumStages() - stage_); - const double baseCot = - dataFormats_->format(Variable::cot, Process::zht).base() * pow(2, setup_->zhtNumStages() - stage_); - int id; - auto different = [&id](StubZHT* stub) { return !stub || id != stub->trackId(); }; - for (auto it = stubs.begin(); it != stubs.end();) { - if (!*it) { - const auto begin = find_if(it, stubs.end(), [](StubZHT* stub) { return stub; }); - const int nGaps = distance(it, begin); - for (deque& stream : streams) - stream.insert(stream.end(), nGaps, nullptr); - it = begin; - continue; - } - const auto start = it; - const double cotGlobal = (*start)->cotf() + setup_->sectorCot((*start)->sectorEta()); - id = (*it)->trackId(); - it = find_if(it, stubs.end(), different); - const int size = distance(start, it); - // create finer track candidates stub container - vector> mhtCells(setup_->zhtNumCells()); - for (vector& mhtCell : mhtCells) - mhtCell.reserve(size); - // fill finer track candidates stub container - for (auto stub = start; stub != it; stub++) { - const double r = (*stub)->r() + setup_->chosenRofPhi() - setup_->chosenRofZ(); - const double chi = (*stub)->chi(); - const double dChi = setup_->dZ((*stub)->ttStubRef(), cotGlobal); - // identify finer track candidates for this stub - // 0 and 1 belong to the ZHT cells with smaller cot; 0 and 2 belong to those with smaller zT - vector cells; - cells.reserve(setup_->zhtNumCells()); - const bool compA = 2. * abs(chi) < baseZT + dChi; - const bool compB = 2. * abs(chi) < abs(r) * baseCot + dChi; - const bool compC = 2. * abs(chi) < dChi; - if (chi >= 0. && r >= 0.) { - cells.push_back(1); - if (compA) - cells.push_back(3); - if (compB) - cells.push_back(0); - if (compC) - cells.push_back(2); - } - if (chi >= 0. && r < 0.) { - cells.push_back(3); - if (compA) - cells.push_back(1); - if (compB) - cells.push_back(2); - if (compC) - cells.push_back(0); - } - if (chi < 0. && r >= 0.) { - cells.push_back(2); - if (compA) - cells.push_back(0); - if (compB) - cells.push_back(3); - if (compC) - cells.push_back(1); - } - if (chi < 0. && r < 0.) { - cells.push_back(0); - if (compA) - cells.push_back(2); - if (compB) - cells.push_back(1); - if (compC) - cells.push_back(3); - } - for (int cell : cells) { - const double cot = (cell / setup_->zhtNumBinsZT() - .5) * baseCot / 2.; - const double zT = (cell % setup_->zhtNumBinsZT() - .5) * baseZT / 2.; - stubsZHT_.emplace_back(**stub, zT, cot, cell); - mhtCells[cell].push_back(&stubsZHT_.back()); - } - } - // perform pattern recognition - for (int sel = 0; sel < setup_->zhtNumCells(); sel++) { - deque& stream = streams[channel * setup_->zhtNumCells() + sel]; - vector& mhtCell = mhtCells[sel]; - set layers; - auto toLayer = [](StubZHT* stub) { return stub->layer(); }; - transform(mhtCell.begin(), mhtCell.end(), inserter(layers, layers.begin()), toLayer); - if ((int)layers.size() < setup_->mhtMinLayers()) - mhtCell.clear(); - for (StubZHT* stub : mhtCell) - stream.push_back(stub); - stream.insert(stream.end(), size - (int)mhtCell.size(), nullptr); - } - } - for (int sel = 0; sel < setup_->zhtNumCells(); sel++) { - deque& stream = streams[channel * setup_->zhtNumCells() + sel]; - // remove all gaps between end and last stub - for (auto it = stream.end(); it != stream.begin();) - it = (*--it) ? stream.begin() : stream.erase(it); - // read out fine track cannot start before rough track has read in completely, add gaps to take this into account - int pos(0); - for (auto it = stream.begin(); it != stream.end();) { - if (!(*it)) { - it = stream.erase(it); - continue; - } - id = (*it)->trackId(); - const int s = distance(it, find_if(it, stream.end(), different)); - const int d = distance(stream.begin(), it); - pos += s; - if (d < pos) { - const int diff = pos - d; - it = stream.insert(it, diff, nullptr); - it = next(it, diff); - } else - it = stream.erase(remove(next(stream.begin(), pos), it, nullptr), it); - it = next(it, s); - } - // adjust stream start so that first output stub is in first place in case of quickest track - if (!stream.empty()) - stream.erase(stream.begin(), next(stream.begin(), setup_->mhtMinLayers())); - } - } - - // Static load balancing of inputs: mux 4 streams to 1 stream - void ZHoughTransform::slb(vector>& inputs, deque& accepted, StreamStub& lost) const { - accepted.clear(); - if (all_of(inputs.begin(), inputs.end(), [](const deque& stubs) { return stubs.empty(); })) - return; - // input fifos - vector> stacks(setup_->zhtNumCells()); - // helper for handshake - TTBV empty(-1, setup_->zhtNumCells(), true); - TTBV enable(0, setup_->zhtNumCells()); - // clock accurate firmware emulation, each while trip describes one clock tick, one stub in and one stub out per tick - while (!all_of(inputs.begin(), inputs.end(), [](const deque& d) { return d.empty(); }) or - !all_of(stacks.begin(), stacks.end(), [](const deque& d) { return d.empty(); })) { - // store stub in fifo - for (int channel = 0; channel < setup_->zhtNumCells(); channel++) { - StubZHT* stub = pop_front(inputs[channel]); - if (stub) - stacks[channel].push_back(stub); - } - // identify empty fifos - for (int channel = 0; channel < setup_->zhtNumCells(); channel++) - empty[channel] = stacks[channel].empty(); - // chose new fifo to read from if current fifo got empty - const int iEnableOld = enable.plEncode(); - if (enable.none() || empty[iEnableOld]) { - enable.reset(); - const int iNotEmpty = empty.plEncode(false); - if (iNotEmpty < setup_->zhtNumCells()) - enable.set(iNotEmpty); - } - // read from chosen fifo - const int iEnable = enable.plEncode(); - if (enable.any()) - accepted.push_back(pop_front(stacks[iEnable])); - else - // gap if no fifo has been chosen - accepted.push_back(nullptr); - } - // perform truncation if desired - if (enableTruncation_ && (int)accepted.size() > setup_->numFrames()) { - const auto limit = next(accepted.begin(), setup_->numFrames()); - auto valid = [](int sum, StubZHT* stub) { return sum + (stub ? 1 : 0); }; - const int nLost = accumulate(limit, accepted.end(), 0, valid); - lost.reserve(nLost); - for (auto it = limit; it != accepted.end(); it++) - if (*it) - lost.emplace_back((*it)->frame()); - accepted.erase(limit, accepted.end()); - } - // cosmetics -- remove gaps at the end of stream - for (auto it = accepted.end(); it != accepted.begin();) - it = (*--it) == nullptr ? accepted.erase(it) : accepted.begin(); - } - - // - void ZHoughTransform::merge(deque& stubs, StreamStub& stream) const { - stubs.erase(remove(stubs.begin(), stubs.end(), nullptr), stubs.end()); - /*stream.reserve(stubs.size()); - transform(stubs.begin(), stubs.end(), back_inserter(stream), [](StubZHT* stub){ return stub->frame(); }); - return;*/ - map>> candidates; - const int weight = setup_->zhtNumCells() * pow(2, setup_->zhtNumStages()); - for (const StubZHT* stub : stubs) - candidates[stub->trackId() / weight].emplace(stub->cot(), stub->zT()); - vector> tracks(candidates.size()); - for (auto it = stubs.begin(); it != stubs.end();) { - const auto start = it; - const int id = (*it)->trackId(); - const int candId = id / weight; - const auto m = candidates.find(candId); - pair cotp(9e9, -9e9); - pair zTp(9e9, -9e9); - for (const pair& para : m->second) { - cotp = {min(cotp.first, para.first), max(cotp.second, para.first)}; - zTp = {min(zTp.first, para.second), max(zTp.second, para.second)}; - } - const int cot = (cotp.first + cotp.second) / 2; - const int zT = (cotp.first + cotp.second) / 2; - const int pos = distance(candidates.begin(), m); - deque& track = tracks[pos]; - auto different = [id](const StubZHT* stub) { return id != stub->trackId(); }; - it = find_if(it, stubs.end(), different); - for (auto s = start; s != it; s++) { - if (find_if(track.begin(), track.end(), [s](const FrameStub& stub) { - return (*s)->ttStubRef() == stub.first; - }) != track.end()) - continue; - const StubZHT stub(**s, cot, zT); - track.push_back(stub.frame()); - } - } - const int size = accumulate(tracks.begin(), tracks.end(), 0, [](int sum, const deque& stubs) { - return sum + (int)stubs.size(); - }); - stream.reserve(size); - for (deque& track : tracks) - for (const FrameStub& stub : track) - stream.push_back(stub); - } - - // remove and return first element of deque, returns nullptr if empty - template - T* ZHoughTransform::pop_front(deque& ts) const { - T* t = nullptr; - if (!ts.empty()) { - t = ts.front(); - ts.pop_front(); - } - return t; - } - -} // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/test/AnalyzerCTB.cc b/L1Trigger/TrackerTFP/test/AnalyzerCTB.cc new file mode 100644 index 0000000000000..e87b2cc467f3f --- /dev/null +++ b/L1Trigger/TrackerTFP/test/AnalyzerCTB.cc @@ -0,0 +1,358 @@ +#include "FWCore/Framework/interface/one/EDAnalyzer.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "CommonTools/UtilAlgos/interface/TFileService.h" +#include "DataFormats/Common/interface/Handle.h" + +#include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" +#include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackerTFP/interface/DataFormats.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace trackerTFP { + + /*! \class trackerTFP::AnalyzerCTB + * \brief Class to analyze hardware like structured TTStub Collection generated by Clean Track Builder + * \author Thomas Schuh + * \date 2020, April + */ + class AnalyzerCTB : public edm::one::EDAnalyzer { + public: + AnalyzerCTB(const edm::ParameterSet& iConfig); + void beginJob() override {} + void beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override; + void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override; + void endRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override {} + void endJob() override; + + private: + // + void formTracks(const tt::StreamsTrack& streamsTrack, + const tt::StreamsStub& streamsStubs, + std::vector>& tracks, + int channel) const; + // + void associate(const std::vector>& tracks, + const tt::StubAssociation* ass, + std::set& tps, + int& sum) const; + // ED input token of stubs + edm::EDGetTokenT edGetTokenStubs_; + // ED input token of tracks + edm::EDGetTokenT edGetTokenTracks_; + // ED input token of TTStubRef to TPPtr association for tracking efficiency + edm::EDGetTokenT edGetTokenSelection_; + // ED input token of TTStubRef to recontructable TPPtr association + edm::EDGetTokenT edGetTokenReconstructable_; + // Setup token + edm::ESGetToken esGetTokenSetup_; + // DataFormats token + edm::ESGetToken esGetTokenDataFormats_; + // stores, calculates and provides run-time constants + const tt::Setup* setup_ = nullptr; + // helper class to extract structured data from tt::Frames + const DataFormats* dataFormats_ = nullptr; + // enables analyze of TPs + bool useMCTruth_; + // + int nEvents_ = 0; + + // Histograms + + TProfile* prof_; + TProfile* profChan_; + TProfile* profStubs_; + TProfile* profTracks_; + TH1F* hisChan_; + TH1F* hisStubs_; + TH1F* hisTracks_; + TH1F* hisLayers_; + TH1F* hisNumLayers_; + TProfile* profNumLayers_; + TH1F* hisEffZT_; + TH1F* hisEffZTTotal_; + TEfficiency* effZT_; + TH1F* hisEffInv2R_; + TH1F* hisEffInv2RTotal_; + TEfficiency* effInv2R_; + + // printout + std::stringstream log_; + }; + + AnalyzerCTB::AnalyzerCTB(const edm::ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { + usesResource("TFileService"); + // book in- and output ED products + const std::string& label = iConfig.getParameter("OutputLabelCTB"); + const std::string& branchStubs = iConfig.getParameter("BranchStubs"); + const std::string& branchTracks = iConfig.getParameter("BranchTracks"); + edGetTokenStubs_ = consumes(edm::InputTag(label, branchStubs)); + edGetTokenTracks_ = consumes(edm::InputTag(label, branchTracks)); + if (useMCTruth_) { + const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); + const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); + edGetTokenSelection_ = consumes(inputTagSelecttion); + edGetTokenReconstructable_ = consumes(inputTagReconstructable); + } + // book ES products + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + // log config + log_.setf(std::ios::fixed, std::ios::floatfield); + log_.precision(4); + } + + void AnalyzerCTB::beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) { + // helper class to store configurations + setup_ = &iSetup.getData(esGetTokenSetup_); + // helper class to extract structured data from tt::Frames + dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); + // book histograms + edm::Service fs; + TFileDirectory dir; + dir = fs->mkdir("CTB"); + prof_ = dir.make("Counts", ";", 9, 0.5, 9.5); + prof_->GetXaxis()->SetBinLabel(1, "Stubs"); + prof_->GetXaxis()->SetBinLabel(2, "Tracks"); + prof_->GetXaxis()->SetBinLabel(4, "Matched Tracks"); + prof_->GetXaxis()->SetBinLabel(5, "All Tracks"); + prof_->GetXaxis()->SetBinLabel(6, "Found TPs"); + prof_->GetXaxis()->SetBinLabel(7, "Found selected TPs"); + prof_->GetXaxis()->SetBinLabel(9, "All TPs"); + // channel occupancy + constexpr int maxOcc = 180; + const int numChannelsTracks = dataFormats_->numChannel(Process::ctb); + const int numChannelsStubs = numChannelsTracks * setup_->numLayers(); + hisChan_ = dir.make("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5); + profChan_ = dir.make("Prof Channel Occupancy", ";", numChannelsTracks, -.5, numChannelsTracks - .5); + // stub occupancy + hisStubs_ = dir.make("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5); + profStubs_ = dir.make("Prof Channel Occupancy", ";", numChannelsStubs, -.5, numChannelsStubs - .5); + // track occupancy + hisTracks_ = dir.make("His Track Occupancy", ";", maxOcc, -.5, maxOcc - .5); + profTracks_ = dir.make("Prof Track Occupancy", ";", numChannelsTracks, -.5, numChannelsTracks - .5); + // layers + hisLayers_ = dir.make("HisLayers", ";", 8, 0, 8); + hisNumLayers_ = dir.make("HisNumLayers", ";", 9, 0, 9); + profNumLayers_ = dir.make("Prof NumLayers", ";", 32, 0, 2.4); + // Efficiencies + const double rangeZT = dataFormats_->format(Variable::zT, Process::dr).range(); + const int zTBins = setup_->gpNumBinsZT(); + hisEffZTTotal_ = dir.make("HisTPZTTotal", ";", zTBins, -rangeZT / 2, rangeZT / 2); + hisEffZT_ = dir.make("HisTPZT", ";", zTBins, -rangeZT / 2, rangeZT / 2); + effZT_ = dir.make("EffZT", ";", zTBins, -rangeZT / 2, rangeZT / 2); + const double rangeInv2R = dataFormats_->format(Variable::inv2R, Process::dr).range(); + const int inv2RBins = (setup_->htNumBinsInv2R() + 2) * 2; + hisEffInv2R_ = dir.make("HisTPInv2R", ";", inv2RBins, -rangeInv2R / 2., rangeInv2R / 2.); + hisEffInv2RTotal_ = dir.make("HisTPInv2RTotal", ";", inv2RBins, -rangeInv2R / 2., rangeInv2R / 2.); + effInv2R_ = dir.make("EffInv2R", ";", inv2RBins, -rangeInv2R / 2., rangeInv2R / 2.); + } + + void AnalyzerCTB::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + auto fill = [this](const TPPtr& tpPtr, TH1F* hisZT, TH1F* hisInv2R) { + const double tpPhi0 = tpPtr->phi(); + const double tpCot = sinh(tpPtr->eta()); + const math::XYZPointD& v = tpPtr->vertex(); + const double tpZ0 = v.z() - tpCot * (v.x() * cos(tpPhi0) + v.y() * sin(tpPhi0)); + const double tpZT = tpZ0 + tpCot * setup_->chosenRofZ(); + const double tpInv2R = tpPtr->charge() / tpPtr->pt() * setup_->invPtToDphi(); + hisZT->Fill(tpZT); + hisInv2R->Fill(tpInv2R); + }; + // read in ht products + edm::Handle handleStubs; + iEvent.getByToken(edGetTokenStubs_, handleStubs); + const tt::StreamsStub& acceptedStubs = *handleStubs; + edm::Handle handleTracks; + iEvent.getByToken(edGetTokenTracks_, handleTracks); + const tt::StreamsTrack& acceptedTracks = *handleTracks; + // read in MCTruth + const tt::StubAssociation* selection = nullptr; + const tt::StubAssociation* reconstructable = nullptr; + if (useMCTruth_) { + edm::Handle handleSelection; + iEvent.getByToken(edGetTokenSelection_, handleSelection); + selection = handleSelection.product(); + prof_->Fill(9, selection->numTPs()); + edm::Handle handleReconstructable; + iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); + reconstructable = handleReconstructable.product(); + for (const auto& p : selection->getTrackingParticleToTTStubsMap()) + fill(p.first, hisEffZTTotal_, hisEffInv2RTotal_); + } + // analyze ht products and associate found tracks with reconstrucable TrackingParticles + std::set tpPtrs; + std::set tpPtrsSelection; + int allMatched(0); + int allTracks(0); + for (int region = 0; region < setup_->numRegions(); region++) { + const int offsetTrack = region * dataFormats_->numChannel(Process::ctb); + int nStubs(0); + int nTracks(0); + for (int channel = 0; channel < dataFormats_->numChannel(Process::ctb); channel++) { + const int indexTrack = offsetTrack + channel; + const int size = acceptedTracks[indexTrack].size(); + hisChan_->Fill(size); + profChan_->Fill(channel, size); + const int offsetStub = indexTrack * setup_->numLayers(); + for (int layer = 0; layer < setup_->numLayers(); layer++) { + const tt::StreamStub& stream = acceptedStubs[offsetStub + layer]; + const int nStubs = std::accumulate(stream.begin(), stream.end(), 0, [](int sum, const tt::FrameStub& frame) { + return sum + (frame.first.isNonnull() ? 1 : 0); + }); + hisStubs_->Fill(nStubs); + profStubs_->Fill(channel * setup_->numLayers() + layer, nStubs); + } + std::vector> tracks; + formTracks(acceptedTracks, acceptedStubs, tracks, indexTrack); + hisTracks_->Fill(tracks.size()); + profTracks_->Fill(channel, tracks.size()); + nTracks += tracks.size(); + nStubs += std::accumulate(tracks.begin(), tracks.end(), 0, [](int sum, const std::vector& track) { + return sum + track.size(); + }); + allTracks += tracks.size(); + if (!useMCTruth_) + continue; + int tmp(0); + associate(tracks, selection, tpPtrsSelection, tmp); + associate(tracks, reconstructable, tpPtrs, allMatched); + } + prof_->Fill(1, nStubs); + prof_->Fill(2, nTracks); + } + for (const TPPtr& tpPtr : tpPtrsSelection) + fill(tpPtr, hisEffZT_, hisEffInv2R_); + prof_->Fill(4, allMatched); + prof_->Fill(5, allTracks); + prof_->Fill(6, tpPtrs.size()); + prof_->Fill(7, tpPtrsSelection.size()); + nEvents_++; + } + + void AnalyzerCTB::endJob() { + if (nEvents_ == 0) + return; + // effi + effZT_->SetPassedHistogram(*hisEffZT_, "f"); + effZT_->SetTotalHistogram(*hisEffZTTotal_, "f"); + effInv2R_->SetPassedHistogram(*hisEffInv2R_, "f"); + effInv2R_->SetTotalHistogram(*hisEffInv2RTotal_, "f"); + // printout TB summary + const double totalTPs = prof_->GetBinContent(9); + const double numStubs = prof_->GetBinContent(1); + const double numTracks = prof_->GetBinContent(2); + const double totalTracks = prof_->GetBinContent(5); + const double numTracksMatched = prof_->GetBinContent(4); + const double numTPsAll = prof_->GetBinContent(6); + const double numTPsEff = prof_->GetBinContent(7); + const double errStubs = prof_->GetBinError(1); + const double errTracks = prof_->GetBinError(2); + const double fracFake = (totalTracks - numTracksMatched) / totalTracks; + const double fracDup = (numTracksMatched - numTPsAll) / totalTracks; + const double eff = numTPsEff / totalTPs; + const double errEff = sqrt(eff * (1. - eff) / totalTPs / nEvents_); + const std::vector nums = {numStubs, numTracks}; + const std::vector errs = {errStubs, errTracks}; + const int wNums = std::ceil(std::log10(*std::max_element(nums.begin(), nums.end()))) + 5; + const int wErrs = std::ceil(std::log10(*std::max_element(errs.begin(), errs.end()))) + 5; + log_ << " CTB SUMMARY " << std::endl; + log_ << "number of stubs per TFP = " << std::setw(wNums) << numStubs << " +- " << std::setw(wErrs) << errStubs + << std::endl; + log_ << "number of tracks per TFP = " << std::setw(wNums) << numTracks << " +- " << std::setw(wErrs) + << errTracks << std::endl; + log_ << " max tracking efficiency = " << std::setw(wNums) << eff << " +- " << std::setw(wErrs) << errEff + << std::endl; + log_ << " fake rate = " << std::setw(wNums) << fracFake << std::endl; + log_ << " duplicate rate = " << std::setw(wNums) << fracDup << std::endl; + log_ << "============================================================="; + edm::LogPrint(moduleDescription().moduleName()) << log_.str(); + } + + // + void AnalyzerCTB::formTracks(const tt::StreamsTrack& streamsTrack, + const tt::StreamsStub& streamsStubs, + std::vector>& tracks, + int channel) const { + const int offset = channel * setup_->numLayers(); + const tt::StreamTrack& streamTrack = streamsTrack[channel]; + const int numTracks = + std::accumulate(streamTrack.begin(), streamTrack.end(), 0, [](int sum, const tt::FrameTrack& frame) { + return sum + (frame.first.isNonnull() ? 1 : 0); + }); + tracks.reserve(numTracks); + for (int frame = 0; frame < static_cast(streamTrack.size()); frame++) { + const tt::FrameTrack& frameTrack = streamTrack[frame]; + if (frameTrack.first.isNull()) + continue; + const auto end = std::find_if(std::next(streamTrack.begin(), frame + 1), + streamTrack.end(), + [](const tt::FrameTrack& frame) { return frame.first.isNonnull(); }); + const int size = std::distance(std::next(streamTrack.begin(), frame), end); + int numStubs(0); + for (int layer = 0; layer < setup_->numLayers(); layer++) { + const tt::StreamStub& stream = streamsStubs[offset + layer]; + numStubs += std::accumulate( + stream.begin() + frame, stream.begin() + frame + size, 0, [](int sum, const tt::FrameStub& frame) { + return sum + (frame.first.isNonnull() ? 1 : 0); + }); + } + std::vector stubs; + stubs.reserve(numStubs); + int numLayers(0); + for (int layer = 0; layer < setup_->numLayers(); layer++) { + bool any(false); + for (int f = frame; f < frame + size; f++) { + const tt::FrameStub& stub = streamsStubs[offset + layer][f]; + if (stub.first.isNonnull()) { + any = true; + stubs.push_back(stub.first); + } + } + if (any) { + hisLayers_->Fill(layer); + numLayers++; + } + } + const double cot = TrackCTB(frameTrack, dataFormats_).zT() / setup_->chosenRofZ(); + hisNumLayers_->Fill(numLayers); + profNumLayers_->Fill(abs(sinh(cot)), numLayers); + tracks.push_back(stubs); + } + } + + // + void AnalyzerCTB::associate(const std::vector>& tracks, + const tt::StubAssociation* ass, + std::set& tps, + int& sum) const { + for (const std::vector& ttStubRefs : tracks) { + const std::vector& tpPtrs = ass->associate(ttStubRefs); + if (tpPtrs.empty()) + continue; + sum++; + std::copy(tpPtrs.begin(), tpPtrs.end(), std::inserter(tps, tps.begin())); + } + } + +} // namespace trackerTFP + +DEFINE_FWK_MODULE(trackerTFP::AnalyzerCTB); diff --git a/L1Trigger/TrackerTFP/test/AnalyzerDR.cc b/L1Trigger/TrackerTFP/test/AnalyzerDR.cc new file mode 100644 index 0000000000000..33e7a983f3973 --- /dev/null +++ b/L1Trigger/TrackerTFP/test/AnalyzerDR.cc @@ -0,0 +1,284 @@ +#include "FWCore/Framework/interface/one/EDAnalyzer.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "CommonTools/UtilAlgos/interface/TFileService.h" +#include "DataFormats/Common/interface/Handle.h" + +#include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" +#include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackerTFP/interface/DataFormats.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace trackerTFP { + + /*! \class trackerTFP::AnalyzerDR + * \brief Class to analyze hardware like structured track Collection generated by Duplicate Removal + * \author Thomas Schuh + * \date 2023, Feb + */ + class AnalyzerDR : public edm::one::EDAnalyzer { + public: + AnalyzerDR(const edm::ParameterSet& iConfig); + void beginJob() override {} + void beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override; + void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override; + void endRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override {} + void endJob() override; + + private: + // + void formTracks(const tt::StreamsTrack& streamsTrack, + const tt::StreamsStub& streamsStubs, + std::vector>& tracks, + int channel) const; + // + void associate(const std::vector>& tracks, + const tt::StubAssociation* ass, + std::set& tps, + int& sum, + bool perfect = true) const; + // ED input token of stubs + edm::EDGetTokenT edGetTokenStubs_; + // ED input token of tracks + edm::EDGetTokenT edGetTokenTracks_; + // ED input token of TTStubRef to TPPtr association for tracking efficiency + edm::EDGetTokenT edGetTokenSelection_; + // ED input token of TTStubRef to recontructable TPPtr association + edm::EDGetTokenT edGetTokenReconstructable_; + // Setup token + edm::ESGetToken esGetTokenSetup_; + // DataFormats token + edm::ESGetToken esGetTokenDataFormats_; + // stores, calculates and provides run-time constants + const tt::Setup* setup_ = nullptr; + // helper class to extract structured data from tt::Frames + const DataFormats* dataFormats_ = nullptr; + // enables analyze of TPs + bool useMCTruth_; + // + int nEvents_ = 0; + + // Histograms + + TProfile* prof_; + TProfile* profChannel_; + TProfile* profTracks_; + TH1F* hisChannel_; + TH1F* hisTracks_; + + // printout + std::stringstream log_; + }; + + AnalyzerDR::AnalyzerDR(const edm::ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { + usesResource("TFileService"); + // book in- and output ED products + const std::string& label = iConfig.getParameter("OutputLabelDR"); + const std::string& branchStubs = iConfig.getParameter("BranchStubs"); + const std::string& branchTracks = iConfig.getParameter("BranchTracks"); + edGetTokenStubs_ = consumes(edm::InputTag(label, branchStubs)); + edGetTokenTracks_ = consumes(edm::InputTag(label, branchTracks)); + if (useMCTruth_) { + const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); + const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); + edGetTokenSelection_ = consumes(inputTagSelecttion); + edGetTokenReconstructable_ = consumes(inputTagReconstructable); + } + // book ES products + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + // log config + log_.setf(std::ios::fixed, std::ios::floatfield); + log_.precision(4); + } + + void AnalyzerDR::beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) { + // helper class to store configurations + setup_ = &iSetup.getData(esGetTokenSetup_); + // helper class to extract structured data from tt::Frames + dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); + // book histograms + edm::Service fs; + TFileDirectory dir; + dir = fs->mkdir("DR"); + prof_ = dir.make("Counts", ";", 12, 0.5, 12.5); + prof_->GetXaxis()->SetBinLabel(1, "Stubs"); + prof_->GetXaxis()->SetBinLabel(2, "Tracks"); + prof_->GetXaxis()->SetBinLabel(4, "Matched Tracks"); + prof_->GetXaxis()->SetBinLabel(5, "All Tracks"); + prof_->GetXaxis()->SetBinLabel(6, "Found TPs"); + prof_->GetXaxis()->SetBinLabel(7, "Found selected TPs"); + prof_->GetXaxis()->SetBinLabel(9, "All TPs"); + prof_->GetXaxis()->SetBinLabel(10, "states"); + prof_->GetXaxis()->SetBinLabel(12, "max tp"); + // channel occupancy + constexpr int maxOcc = 180; + const int numChannels = dataFormats_->numChannel(Process::dr); + hisChannel_ = dir.make("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5); + profChannel_ = dir.make("Prof Channel Occupancy", ";", numChannels, -.5, numChannels - .5); + // track occupancy + hisTracks_ = dir.make("His Track Occupancy", ";", maxOcc, -.5, maxOcc - .5); + profTracks_ = dir.make("Prof Track Occupancy", ";", numChannels, -.5, numChannels - .5); + } + + void AnalyzerDR::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + // read in ht products + edm::Handle handleStubs; + iEvent.getByToken(edGetTokenStubs_, handleStubs); + const tt::StreamsStub& acceptedStubs = *handleStubs; + edm::Handle handleTracks; + iEvent.getByToken(edGetTokenTracks_, handleTracks); + const tt::StreamsTrack& acceptedTracks = *handleTracks; + // read in MCTruth + const tt::StubAssociation* selection = nullptr; + const tt::StubAssociation* reconstructable = nullptr; + if (useMCTruth_) { + edm::Handle handleSelection; + iEvent.getByToken(edGetTokenSelection_, handleSelection); + selection = handleSelection.product(); + prof_->Fill(9, selection->numTPs()); + edm::Handle handleReconstructable; + iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); + reconstructable = handleReconstructable.product(); + } + // analyze ht products and associate found tracks with reconstrucable TrackingParticles + std::set tpPtrs; + std::set tpPtrsSelection; + std::set tpPtrsMax; + int allMatched(0); + int allTracks(0); + for (int region = 0; region < setup_->numRegions(); region++) { + const int offset = region * dataFormats_->numChannel(Process::dr); + int nStubs(0); + int nTracks(0); + for (int channel = 0; channel < dataFormats_->numChannel(Process::dr); channel++) { + std::vector> tracks; + formTracks(acceptedTracks, acceptedStubs, tracks, offset + channel); + hisTracks_->Fill(tracks.size()); + profTracks_->Fill(channel, tracks.size()); + nTracks += tracks.size(); + nStubs += std::accumulate(tracks.begin(), tracks.end(), 0, [](int sum, const std::vector& track) { + return sum + track.size(); + }); + allTracks += tracks.size(); + if (!useMCTruth_) + continue; + int tmp(0); + associate(tracks, selection, tpPtrsSelection, tmp); + associate(tracks, reconstructable, tpPtrs, allMatched, false); + associate(tracks, selection, tpPtrsMax, tmp, false); + const int size = acceptedTracks[offset + channel].size(); + hisChannel_->Fill(size); + profChannel_->Fill(channel, size); + } + prof_->Fill(1, nStubs); + prof_->Fill(2, nTracks); + } + prof_->Fill(4, allMatched); + prof_->Fill(5, allTracks); + prof_->Fill(6, tpPtrs.size()); + prof_->Fill(7, tpPtrsSelection.size()); + prof_->Fill(12, tpPtrsMax.size()); + nEvents_++; + } + + void AnalyzerDR::endJob() { + if (nEvents_ == 0) + return; + // printout DR summary + const double totalTPs = prof_->GetBinContent(9); + const double numStubs = prof_->GetBinContent(1); + const double numTracks = prof_->GetBinContent(2); + const double totalTracks = prof_->GetBinContent(5); + const double numTracksMatched = prof_->GetBinContent(4); + const double numTPsAll = prof_->GetBinContent(6); + const double numTPsEff = prof_->GetBinContent(7); + const double numTPsEffMax = prof_->GetBinContent(12); + const double errStubs = prof_->GetBinError(1); + const double errTracks = prof_->GetBinError(2); + const double fracFake = (totalTracks - numTracksMatched) / totalTracks; + const double fracDup = (numTracksMatched - numTPsAll) / totalTracks; + const double eff = numTPsEff / totalTPs; + const double errEff = std::sqrt(eff * (1. - eff) / totalTPs / nEvents_); + const double effMax = numTPsEffMax / totalTPs; + const double errEffMax = std::sqrt(effMax * (1. - effMax) / totalTPs / nEvents_); + const std::vector nums = {numStubs, numTracks}; + const std::vector errs = {errStubs, errTracks}; + const int wNums = std::ceil(std::log10(*std::max_element(nums.begin(), nums.end()))) + 5; + const int wErrs = std::ceil(std::log10(*std::max_element(errs.begin(), errs.end()))) + 5; + log_ << " DR SUMMARY " << std::endl; + log_ << "number of stubs per TFP = " << std::setw(wNums) << numStubs << " +- " << std::setw(wErrs) << errStubs + << std::endl; + log_ << "number of tracks per TFP = " << std::setw(wNums) << numTracks << " +- " << std::setw(wErrs) + << errTracks << std::endl; + log_ << " tracking efficiency = " << std::setw(wNums) << eff << " +- " << std::setw(wErrs) << errEff + << std::endl; + log_ << " max tracking efficiency = " << std::setw(wNums) << effMax << " +- " << std::setw(wErrs) << errEffMax + << std::endl; + log_ << " fake rate = " << std::setw(wNums) << fracFake << std::endl; + log_ << " duplicate rate = " << std::setw(wNums) << fracDup << std::endl; + log_ << "============================================================="; + edm::LogPrint(moduleDescription().moduleName()) << log_.str(); + } + + // + void AnalyzerDR::formTracks(const tt::StreamsTrack& streamsTrack, + const tt::StreamsStub& streamsStubs, + std::vector>& tracks, + int channel) const { + const int offset = channel * setup_->numLayers(); + const tt::StreamTrack& streamTrack = streamsTrack[channel]; + const int numTracks = + std::accumulate(streamTrack.begin(), streamTrack.end(), 0, [](int sum, const tt::FrameTrack& frame) { + return sum + (frame.first.isNonnull() ? 1 : 0); + }); + tracks.reserve(numTracks); + for (int frame = 0; frame < static_cast(streamTrack.size()); frame++) { + const tt::FrameTrack& frameTrack = streamTrack[frame]; + if (frameTrack.first.isNull()) + continue; + std::deque stubs; + for (int layer = 0; layer < setup_->numLayers(); layer++) { + const tt::FrameStub& stub = streamsStubs[offset + layer][frame]; + if (stub.first.isNonnull()) + stubs.push_back(stub.first); + } + tracks.emplace_back(stubs.begin(), stubs.end()); + } + } + + // + void AnalyzerDR::associate(const std::vector>& tracks, + const tt::StubAssociation* ass, + std::set& tps, + int& sum, + bool perfect) const { + for (const std::vector& ttStubRefs : tracks) { + const std::vector& tpPtrs = perfect ? ass->associateFinal(ttStubRefs) : ass->associate(ttStubRefs); + if (tpPtrs.empty()) + continue; + sum++; + std::copy(tpPtrs.begin(), tpPtrs.end(), std::inserter(tps, tps.begin())); + } + } + +} // namespace trackerTFP + +DEFINE_FWK_MODULE(trackerTFP::AnalyzerDR); diff --git a/L1Trigger/TrackerTFP/test/AnalyzerDemonstrator.cc b/L1Trigger/TrackerTFP/test/AnalyzerDemonstrator.cc index 6b65410d03e0f..e7e807037742e 100644 --- a/L1Trigger/TrackerTFP/test/AnalyzerDemonstrator.cc +++ b/L1Trigger/TrackerTFP/test/AnalyzerDemonstrator.cc @@ -14,79 +14,78 @@ #include -using namespace std; -using namespace edm; -using namespace tt; - namespace trackerTFP { /*! \class trackerTFP::AnalyzerDemonstrator - * \brief Class to demontrate correctness of track trigger emulators - * by comparing FW with SW + * \brief calls questasim to simulate the f/w and compares the results with clock-and-bit-accurate emulation. + * A single bit error interrupts the run. * \author Thomas Schuh * \date 2020, Nov */ - class AnalyzerDemonstrator : public one::EDAnalyzer { + class AnalyzerDemonstrator : public edm::one::EDAnalyzer { public: - AnalyzerDemonstrator(const ParameterSet& iConfig); + AnalyzerDemonstrator(const edm::ParameterSet& iConfig); void beginJob() override {} - void beginRun(const Run& iEvent, const EventSetup& iSetup) override; - void analyze(const Event& iEvent, const EventSetup& iSetup) override; - void endRun(const Run& iEvent, const EventSetup& iSetup) override {} + void beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override; + void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override; + void endRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override {} void endJob() override {} private: // - void convert(const Event& iEvent, - const EDGetTokenT& tokenTracks, - const EDGetTokenT& tokenStubs, - vector>& bits) const; + void convert(const edm::Event& iEvent, + const edm::EDGetTokenT& tokenTracks, + const edm::EDGetTokenT& tokenStubs, + std::vector>& bits) const; // template - void convert(const T& collection, vector>& bits) const; + void convert(const T& collection, std::vector>& bits) const; // ED input token of Tracks - EDGetTokenT edGetTokenStubsIn_; - EDGetTokenT edGetTokenStubsOut_; + edm::EDGetTokenT edGetTokenStubsIn_; + edm::EDGetTokenT edGetTokenStubsOut_; // ED input token of Stubs - EDGetTokenT edGetTokenTracksIn_; - EDGetTokenT edGetTokenTracksOut_; + edm::EDGetTokenT edGetTokenTracksIn_; + edm::EDGetTokenT edGetTokenTracksOut_; // Setup token - ESGetToken esGetTokenSetup_; + edm::ESGetToken esGetTokenSetup_; // Demonstrator token - ESGetToken esGetTokenDemonstrator_; + edm::ESGetToken esGetTokenDemonstrator_; // - const Setup* setup_ = nullptr; + const tt::Setup* setup_ = nullptr; // const Demonstrator* demonstrator_ = nullptr; }; - AnalyzerDemonstrator::AnalyzerDemonstrator(const ParameterSet& iConfig) { + AnalyzerDemonstrator::AnalyzerDemonstrator(const edm::ParameterSet& iConfig) { // book in- and output ED products - const string& labelIn = iConfig.getParameter("LabelIn"); - const string& labelOut = iConfig.getParameter("LabelOut"); - const string& branchStubs = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchTracks = iConfig.getParameter("BranchAcceptedTracks"); - edGetTokenStubsIn_ = consumes(InputTag(labelIn, branchStubs)); - edGetTokenStubsOut_ = consumes(InputTag(labelOut, branchStubs)); - if (labelIn == "TrackerTFPProducerKFin" || labelIn == "TrackerTFPProducerKF") - edGetTokenTracksIn_ = consumes(InputTag(labelIn, branchTracks)); - if (labelOut == "TrackerTFPProducerKF" || labelOut == "TrackerTFPProducerDR") - edGetTokenTracksOut_ = consumes(InputTag(labelOut, branchTracks)); + const std::string& labelIn = iConfig.getParameter("LabelIn"); + const std::string& labelOut = iConfig.getParameter("LabelOut"); + const std::string& branchStubs = iConfig.getParameter("BranchStubs"); + const std::string& branchTracks = iConfig.getParameter("BranchTracks"); + edGetTokenStubsIn_ = consumes(edm::InputTag(labelIn, branchStubs)); + if (labelOut != "ProducerTFP") + edGetTokenStubsOut_ = consumes(edm::InputTag(labelOut, branchStubs)); + if (labelIn == "ProducerCTB" || labelIn == "ProducerKF" || labelIn == "ProducerDR") + edGetTokenTracksIn_ = consumes(edm::InputTag(labelIn, branchTracks)); + if (labelOut == "ProducerCTB" || labelOut == "ProducerKF" || labelOut == "ProducerDR" || labelOut == "ProducerTFP") + edGetTokenTracksOut_ = consumes(edm::InputTag(labelOut, branchTracks)); // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDemonstrator_ = esConsumes(); + esGetTokenSetup_ = esConsumes(); + esGetTokenDemonstrator_ = esConsumes(); } - void AnalyzerDemonstrator::beginRun(const Run& iEvent, const EventSetup& iSetup) { + void AnalyzerDemonstrator::beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) { // setup_ = &iSetup.getData(esGetTokenSetup_); // demonstrator_ = &iSetup.getData(esGetTokenDemonstrator_); } - void AnalyzerDemonstrator::analyze(const Event& iEvent, const EventSetup& iSetup) { - vector> input; - vector> output; + void AnalyzerDemonstrator::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + edm::Handle handle; + iEvent.getByToken(edGetTokenStubsIn_, handle); + std::vector> input; + std::vector> output; convert(iEvent, edGetTokenTracksIn_, edGetTokenStubsIn_, input); convert(iEvent, edGetTokenTracksOut_, edGetTokenStubsOut_, output); if (!demonstrator_->analyze(input, output)) { @@ -98,22 +97,22 @@ namespace trackerTFP { } // - void AnalyzerDemonstrator::convert(const Event& iEvent, - const EDGetTokenT& tokenTracks, - const EDGetTokenT& tokenStubs, - vector>& bits) const { + void AnalyzerDemonstrator::convert(const edm::Event& iEvent, + const edm::EDGetTokenT& tokenTracks, + const edm::EDGetTokenT& tokenStubs, + std::vector>& bits) const { const bool tracks = !tokenTracks.isUninitialized(); const bool stubs = !tokenStubs.isUninitialized(); - Handle handleStubs; - Handle handleTracks; + edm::Handle handleStubs; + edm::Handle handleTracks; int numChannelStubs(0); if (stubs) { - iEvent.getByToken(tokenStubs, handleStubs); + iEvent.getByToken(tokenStubs, handleStubs); numChannelStubs = handleStubs->size(); } int numChannelTracks(0); if (tracks) { - iEvent.getByToken(tokenTracks, handleTracks); + iEvent.getByToken(tokenTracks, handleTracks); numChannelTracks = handleTracks->size(); } numChannelTracks /= setup_->numRegions(); @@ -141,11 +140,12 @@ namespace trackerTFP { // template - void AnalyzerDemonstrator::convert(const T& collection, vector>& bits) const { + void AnalyzerDemonstrator::convert(const T& collection, std::vector>& bits) const { bits.emplace_back(); - vector& bvs = bits.back(); + std::vector& bvs = bits.back(); bvs.reserve(collection.size()); - transform(collection.begin(), collection.end(), back_inserter(bvs), [](const auto& frame) { return frame.second; }); + std::transform( + collection.begin(), collection.end(), std::back_inserter(bvs), [](const auto& frame) { return frame.second; }); } } // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/test/AnalyzerGP.cc b/L1Trigger/TrackerTFP/test/AnalyzerGP.cc index 7a38af978a155..509d4814d1f45 100644 --- a/L1Trigger/TrackerTFP/test/AnalyzerGP.cc +++ b/L1Trigger/TrackerTFP/test/AnalyzerGP.cc @@ -14,19 +14,17 @@ #include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" #include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackerTFP/interface/DataFormats.h" #include #include +#include #include #include #include #include -using namespace std; -using namespace edm; -using namespace tt; - namespace trackerTFP { /*! \class trackerTFP::AnalyzerGP @@ -34,26 +32,28 @@ namespace trackerTFP { * \author Thomas Schuh * \date 2020, Apr */ - class AnalyzerGP : public one::EDAnalyzer { + class AnalyzerGP : public edm::one::EDAnalyzer { public: - AnalyzerGP(const ParameterSet& iConfig); + AnalyzerGP(const edm::ParameterSet& iConfig); void beginJob() override {} - void beginRun(const Run& iEvent, const EventSetup& iSetup) override; - void analyze(const Event& iEvent, const EventSetup& iSetup) override; - void endRun(const Run& iEvent, const EventSetup& iSetup) override {} + void beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override; + void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override; + void endRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override {} void endJob() override; private: // ED input token of stubs - EDGetTokenT edGetTokenAccepted_; - // ED input token of lost stubs - EDGetTokenT edGetTokenLost_; + edm::EDGetTokenT edGetToken_; // ED input token of TTStubRef to TPPtr association for tracking efficiency - EDGetTokenT edGetTokenAss_; + edm::EDGetTokenT edGetTokenAss_; // Setup token - ESGetToken esGetToken_; + edm::ESGetToken esGetTokenSetup_; + // DataFormats token + edm::ESGetToken esGetTokenDataFormats_; // stores, calculates and provides run-time constants - const Setup* setup_ = nullptr; + const tt::Setup* setup_ = nullptr; + // helper class to extract structured data from tt::Frames + const DataFormats* dataFormats_ = nullptr; // enables analyze of TPs bool useMCTruth_; // @@ -64,42 +64,70 @@ namespace trackerTFP { TProfile* prof_; TProfile* profChannel_; TH1F* hisChannel_; + TH1F* hisEffEta_; + TH1F* hisEffEtaTotal_; + TEfficiency* effEta_; + TH1F* hisEffZT_; + TH1F* hisEffZTTotal_; + TEfficiency* effZT_; + TH1F* hisEffInv2R_; + TH1F* hisEffInv2RTotal_; + TEfficiency* effInv2R_; + TH1F* hisEffPT_; + TH1F* hisEffPTTotal_; + TEfficiency* effPT_; // printout - stringstream log_; + std::stringstream log_; }; - AnalyzerGP::AnalyzerGP(const ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { + AnalyzerGP::AnalyzerGP(const edm::ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { usesResource("TFileService"); // book in- and output ED products - const string& label = iConfig.getParameter("LabelGP"); - const string& branchAccepted = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchLost = iConfig.getParameter("BranchLostStubs"); - edGetTokenAccepted_ = consumes(InputTag(label, branchAccepted)); - edGetTokenLost_ = consumes(InputTag(label, branchLost)); + const std::string& label = iConfig.getParameter("OutputLabelGP"); + const std::string& branch = iConfig.getParameter("BranchStubs"); + edGetToken_ = consumes(edm::InputTag(label, branch)); if (useMCTruth_) { - const auto& inputTagAss = iConfig.getParameter("InputTagSelection"); - edGetTokenAss_ = consumes(inputTagAss); + const auto& inputTagAss = iConfig.getParameter("InputTagSelection"); + edGetTokenAss_ = consumes(inputTagAss); } - // book ES product - esGetToken_ = esConsumes(); + // book ES products + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); // log config - log_.setf(ios::fixed, ios::floatfield); + log_.setf(std::ios::fixed, std::ios::floatfield); log_.precision(4); } - void AnalyzerGP::beginRun(const Run& iEvent, const EventSetup& iSetup) { + void AnalyzerGP::beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) { // helper class to store configurations - setup_ = &iSetup.getData(esGetToken_); + setup_ = &iSetup.getData(esGetTokenSetup_); + // helper class to extract structured data from tt::Frames + dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); // book histograms - Service fs; + edm::Service fs; TFileDirectory dir; dir = fs->mkdir("GP"); prof_ = dir.make("Counts", ";", 4, 0.5, 4.5); - prof_->GetXaxis()->SetBinLabel(1, "Stubs"); - prof_->GetXaxis()->SetBinLabel(2, "Lost Stubs"); + prof_->GetXaxis()->SetBinLabel(1, "Accepted Stubs"); + prof_->GetXaxis()->SetBinLabel(2, "Truncated Stubs"); prof_->GetXaxis()->SetBinLabel(3, "Found TPs"); prof_->GetXaxis()->SetBinLabel(4, "Selected TPs"); + // Efficiencies + hisEffEtaTotal_ = dir.make("HisTPEtaTotal", ";", 48, -2.4, 2.4); + hisEffEta_ = dir.make("HisTPEta", ";", 48, -2.4, 2.4); + effEta_ = dir.make("EffEta", ";", 48, -2.4, 2.4); + const int zTBins = setup_->gpNumBinsZT(); + hisEffZTTotal_ = dir.make("HisTPZTTotal", ";", zTBins, -zTBins / 2, zTBins / 2); + hisEffZT_ = dir.make("HisTPZT", ";", zTBins, -zTBins / 2, zTBins / 2); + effZT_ = dir.make("EffZT", ";", zTBins, -zTBins / 2, zTBins / 2); + const double rangeInv2R = dataFormats_->format(Variable::inv2R, Process::dr).range(); + hisEffInv2R_ = dir.make("HisTPInv2R", ";", 32, -rangeInv2R / 2., rangeInv2R / 2.); + hisEffInv2RTotal_ = dir.make("HisTPInv2RTotal", ";", 32, -rangeInv2R / 2., rangeInv2R / 2.); + effInv2R_ = dir.make("EffInv2R", ";", 32, -rangeInv2R / 2., rangeInv2R / 2.); + hisEffPT_ = dir.make("HisTPPT", ";", 100, 0, 100); + hisEffPTTotal_ = dir.make("HisTPPTTotal", ";", 100, 0, 100); + effPT_ = dir.make("EffPT", ";", 100, 0, 100); // channel occupancy constexpr int maxOcc = 180; const int numChannels = setup_->numSectors(); @@ -107,55 +135,65 @@ namespace trackerTFP { profChannel_ = dir.make("Prof Channel Occupancy", ";", numChannels, -.5, numChannels - .5); } - void AnalyzerGP::analyze(const Event& iEvent, const EventSetup& iSetup) { + void AnalyzerGP::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + auto fill = [this](const TPPtr& tpPtr, TH1F* hisEta, TH1F* hisZT, TH1F* hisInv2R, TH1F* hisPT) { + const double tpPhi0 = tpPtr->phi(); + const double tpCot = sinh(tpPtr->eta()); + const math::XYZPointD& v = tpPtr->vertex(); + const double tpZ0 = v.z() - tpCot * (v.x() * cos(tpPhi0) + v.y() * sin(tpPhi0)); + const double tpZT = tpZ0 + tpCot * setup_->chosenRofZ(); + hisEta->Fill(tpPtr->eta()); + hisZT->Fill(dataFormats_->format(Variable::zT, Process::gp).integer(tpZT)); + hisInv2R->Fill(tpPtr->charge() / tpPtr->pt() * setup_->invPtToDphi()); + hisPT->Fill(tpPtr->pt()); + }; // read in gp products - Handle handleAccepted; - iEvent.getByToken(edGetTokenAccepted_, handleAccepted); - Handle handleLost; - iEvent.getByToken(edGetTokenLost_, handleLost); + edm::Handle handleStubs; + iEvent.getByToken(edGetToken_, handleStubs); // read in MCTruth - const StubAssociation* stubAssociation = nullptr; + const tt::StubAssociation* stubAssociation = nullptr; if (useMCTruth_) { - Handle handleAss; - iEvent.getByToken(edGetTokenAss_, handleAss); + edm::Handle handleAss; + iEvent.getByToken(edGetTokenAss_, handleAss); stubAssociation = handleAss.product(); prof_->Fill(4, stubAssociation->numTPs()); + for (const auto& p : stubAssociation->getTrackingParticleToTTStubsMap()) + fill(p.first, hisEffEtaTotal_, hisEffZTTotal_, hisEffInv2RTotal_, hisEffPTTotal_); } // analyze gp products and find still reconstrucable TrackingParticles - set setTPPtr; + std::set setTPPtr; for (int region = 0; region < setup_->numRegions(); region++) { int nStubs(0); - int nLost(0); - map> mapTPsTTStubs; + std::map> mapTPsTTStubs; for (int channel = 0; channel < setup_->numSectors(); channel++) { const int index = region * setup_->numSectors() + channel; - const StreamStub& accepted = handleAccepted->at(index); + const tt::StreamStub& accepted = handleStubs->at(index); hisChannel_->Fill(accepted.size()); profChannel_->Fill(channel, accepted.size()); - for (const FrameStub& frame : accepted) { + for (const tt::FrameStub& frame : accepted) { if (frame.first.isNull()) continue; nStubs++; if (!useMCTruth_) continue; - const vector& tpPtrs = stubAssociation->findTrackingParticlePtrs(frame.first); + const std::vector& tpPtrs = stubAssociation->findTrackingParticlePtrs(frame.first); for (const TPPtr& tpPtr : tpPtrs) { auto it = mapTPsTTStubs.find(tpPtr); if (it == mapTPsTTStubs.end()) { - it = mapTPsTTStubs.emplace(tpPtr, vector()).first; + it = mapTPsTTStubs.emplace(tpPtr, std::vector()).first; it->second.reserve(stubAssociation->findTTStubRefs(tpPtr).size()); } it->second.push_back(frame.first); } } - nLost += handleLost->at(index).size(); } for (const auto& p : mapTPsTTStubs) if (setup_->reconstructable(p.second)) setTPPtr.insert(p.first); prof_->Fill(1, nStubs); - prof_->Fill(2, nLost); } + for (const TPPtr& tpPtr : setTPPtr) + fill(tpPtr, hisEffEta_, hisEffZT_, hisEffInv2R_, hisEffPT_); prof_->Fill(3, setTPPtr.size()); nEvents_++; } @@ -163,26 +201,33 @@ namespace trackerTFP { void AnalyzerGP::endJob() { if (nEvents_ == 0) return; + // effi + effEta_->SetPassedHistogram(*hisEffEta_, "f"); + effEta_->SetTotalHistogram(*hisEffEtaTotal_, "f"); + effZT_->SetPassedHistogram(*hisEffZT_, "f"); + effZT_->SetTotalHistogram(*hisEffZTTotal_, "f"); + effInv2R_->SetPassedHistogram(*hisEffInv2R_, "f"); + effInv2R_->SetTotalHistogram(*hisEffInv2RTotal_, "f"); + effPT_->SetPassedHistogram(*hisEffPT_, "f"); + effPT_->SetTotalHistogram(*hisEffPTTotal_, "f"); // printout GP summary const double numStubs = prof_->GetBinContent(1); - const double numStubsLost = prof_->GetBinContent(2); const double errStubs = prof_->GetBinError(1); - const double errStubsLost = prof_->GetBinError(2); const double numTPs = prof_->GetBinContent(3); const double totalTPs = prof_->GetBinContent(4); const double eff = numTPs / totalTPs; const double errEff = sqrt(eff * (1. - eff) / totalTPs / nEvents_); - const vector nums = {numStubs, numStubsLost}; - const vector errs = {errStubs, errStubsLost}; - const int wNums = ceil(log10(*max_element(nums.begin(), nums.end()))) + 5; - const int wErrs = ceil(log10(*max_element(errs.begin(), errs.end()))) + 5; - log_ << " GP SUMMARY " << endl; - log_ << "number of stubs per TFP = " << setw(wNums) << numStubs << " +- " << setw(wErrs) << errStubs << endl; - log_ << "number of lost stubs per TFP = " << setw(wNums) << numStubsLost << " +- " << setw(wErrs) << errStubsLost - << endl; - log_ << " max tracking efficiency = " << setw(wNums) << eff << " +- " << setw(wErrs) << errEff << endl; + const std::vector nums = {numStubs}; + const std::vector errs = {errStubs}; + const int wNums = std::ceil(std::log10(*std::max_element(nums.begin(), nums.end()))) + 5; + const int wErrs = std::ceil(std::log10(*std::max_element(errs.begin(), errs.end()))) + 5; + log_ << " GP SUMMARY " << std::endl; + log_ << "number of stubs per TFP = " << std::setw(wNums) << numStubs << " +- " << std::setw(wErrs) << errStubs + << std::endl; + log_ << " max tracking efficiency = " << std::setw(wNums) << eff << " +- " << std::setw(wErrs) << errEff + << std::endl; log_ << "============================================================="; - LogPrint("L1Trigger/TrackerTFP") << log_.str(); + edm::LogPrint(moduleDescription().moduleName()) << log_.str(); } } // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/test/AnalyzerHT.cc b/L1Trigger/TrackerTFP/test/AnalyzerHT.cc index 62b14e8f5aab8..240b9f33bcc4a 100644 --- a/L1Trigger/TrackerTFP/test/AnalyzerHT.cc +++ b/L1Trigger/TrackerTFP/test/AnalyzerHT.cc @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -26,10 +27,6 @@ #include #include -using namespace std; -using namespace edm; -using namespace tt; - namespace trackerTFP { /*! \class trackerTFP::AnalyzerHT @@ -37,35 +34,36 @@ namespace trackerTFP { * \author Thomas Schuh * \date 2020, Apr */ - class AnalyzerHT : public one::EDAnalyzer { + class AnalyzerHT : public edm::one::EDAnalyzer { public: - AnalyzerHT(const ParameterSet& iConfig); + AnalyzerHT(const edm::ParameterSet& iConfig); void beginJob() override {} - void beginRun(const Run& iEvent, const EventSetup& iSetup) override; - void analyze(const Event& iEvent, const EventSetup& iSetup) override; - void endRun(const Run& iEvent, const EventSetup& iSetup) override {} + void beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override; + void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override; + void endRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override {} void endJob() override; private: // - void formTracks(const StreamStub& stream, vector>& tracks, int qOverPt) const; + void formTracks(const tt::StreamStub& stream, std::vector>& tracks) const; // - void associate(const vector>& tracks, const StubAssociation* ass, set& tps, int& sum) const; + void associate(const std::vector>& tracks, + const tt::StubAssociation* ass, + std::set& tps, + int& sum) const; // ED input token of stubs - EDGetTokenT edGetTokenAccepted_; - // ED input token of lost stubs - EDGetTokenT edGetTokenLost_; + edm::EDGetTokenT edGetToken_; // ED input token of TTStubRef to TPPtr association for tracking efficiency - EDGetTokenT edGetTokenSelection_; + edm::EDGetTokenT edGetTokenSelection_; // ED input token of TTStubRef to recontructable TPPtr association - EDGetTokenT edGetTokenReconstructable_; + edm::EDGetTokenT edGetTokenReconstructable_; // Setup token - ESGetToken esGetTokenSetup_; + edm::ESGetToken esGetTokenSetup_; // DataFormats token - ESGetToken esGetTokenDataFormats_; + edm::ESGetToken esGetTokenDataFormats_; // stores, calculates and provides run-time constants - const Setup* setup_ = nullptr; + const tt::Setup* setup_ = nullptr; // helper class to extract structured data from tt::Frames const DataFormats* dataFormats_ = nullptr; // enables analyze of TPs @@ -78,194 +76,244 @@ namespace trackerTFP { TProfile* prof_; TProfile* profChannel_; TH1F* hisChannel_; + TH1F* hisLayers_; + TH1F* hisNumLayers_; + TProfile* profNumLayers_; + TH1F* hisEffEta_; + TH1F* hisEffEtaTotal_; + TEfficiency* effEta_; + TH1F* hisEffZT_; + TH1F* hisEffZTTotal_; + TEfficiency* effZT_; + TH1F* hisEffInv2R_; + TH1F* hisEffInv2RTotal_; + TEfficiency* effInv2R_; + TH1F* hisEffPT_; + TH1F* hisEffPTTotal_; + TEfficiency* effPT_; // printout - stringstream log_; + std::stringstream log_; }; - AnalyzerHT::AnalyzerHT(const ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { + AnalyzerHT::AnalyzerHT(const edm::ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { usesResource("TFileService"); // book in- and output ED products - const string& label = iConfig.getParameter("LabelHT"); - const string& branchAccepted = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchLost = iConfig.getParameter("BranchLostStubs"); - edGetTokenAccepted_ = consumes(InputTag(label, branchAccepted)); - edGetTokenLost_ = consumes(InputTag(label, branchLost)); + const std::string& label = iConfig.getParameter("OutputLabelHT"); + const std::string& branch = iConfig.getParameter("BranchStubs"); + edGetToken_ = consumes(edm::InputTag(label, branch)); if (useMCTruth_) { - const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); - const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); - edGetTokenSelection_ = consumes(inputTagSelecttion); - edGetTokenReconstructable_ = consumes(inputTagReconstructable); + const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); + const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); + edGetTokenSelection_ = consumes(inputTagSelecttion); + edGetTokenReconstructable_ = consumes(inputTagReconstructable); } // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); // log config - log_.setf(ios::fixed, ios::floatfield); + log_.setf(std::ios::fixed, std::ios::floatfield); log_.precision(4); } - void AnalyzerHT::beginRun(const Run& iEvent, const EventSetup& iSetup) { + void AnalyzerHT::beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) { // helper class to store configurations setup_ = &iSetup.getData(esGetTokenSetup_); // helper class to extract structured data from tt::Frames dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); // book histograms - Service fs; + edm::Service fs; TFileDirectory dir; dir = fs->mkdir("HT"); prof_ = dir.make("Counts", ";", 9, 0.5, 9.5); prof_->GetXaxis()->SetBinLabel(1, "Stubs"); prof_->GetXaxis()->SetBinLabel(2, "Tracks"); - prof_->GetXaxis()->SetBinLabel(3, "Lost Tracks"); + prof_->GetXaxis()->SetBinLabel(3, "Truncated Tracks"); prof_->GetXaxis()->SetBinLabel(4, "Matched Tracks"); prof_->GetXaxis()->SetBinLabel(5, "All Tracks"); prof_->GetXaxis()->SetBinLabel(6, "Found TPs"); prof_->GetXaxis()->SetBinLabel(7, "Found selected TPs"); - prof_->GetXaxis()->SetBinLabel(8, "Lost TPs"); + prof_->GetXaxis()->SetBinLabel(8, "Truncated TPs"); prof_->GetXaxis()->SetBinLabel(9, "All TPs"); + // Efficiencies + hisEffEtaTotal_ = dir.make("HisTPEtaTotal", ";", 48, -2.4, 2.4); + hisEffEta_ = dir.make("HisTPEta", ";", 48, -2.4, 2.4); + effEta_ = dir.make("EffEta", ";", 48, -2.4, 2.4); + const double rangeZT = dataFormats_->format(Variable::zT, Process::dr).range(); + const int zTBins = setup_->gpNumBinsZT(); + hisEffZTTotal_ = dir.make("HisTPZTTotal", ";", zTBins, -rangeZT / 2, rangeZT / 2); + hisEffZT_ = dir.make("HisTPZT", ";", zTBins, -rangeZT / 2, rangeZT / 2); + effZT_ = dir.make("EffZT", ";", zTBins, -rangeZT / 2, rangeZT / 2); + const double rangeInv2R = dataFormats_->format(Variable::inv2R, Process::dr).range(); + const int inv2RBins = (setup_->htNumBinsInv2R() + 2) * 2; + hisEffInv2R_ = dir.make("HisTPInv2R", ";", inv2RBins, -rangeInv2R / 2., rangeInv2R / 2.); + hisEffInv2RTotal_ = dir.make("HisTPInv2RTotal", ";", inv2RBins, -rangeInv2R / 2., rangeInv2R / 2.); + effInv2R_ = dir.make("EffInv2R", ";", inv2RBins, -rangeInv2R / 2., rangeInv2R / 2.); + hisEffPT_ = dir.make("HisTPPT", ";", 100, 0, 100); + hisEffPTTotal_ = dir.make("HisTPPTTotal", ";", 100, 0, 100); + effPT_ = dir.make("EffPT", ";", 100, 0, 100); // binInv2R occupancy constexpr int maxOcc = 180; const int numChannel = dataFormats_->numChannel(Process::ht); hisChannel_ = dir.make("His binInv2R Occupancy", ";", maxOcc, -.5, maxOcc - .5); profChannel_ = dir.make("Prof binInv2R Occupancy", ";", numChannel, -.5, numChannel - .5); + // layers + hisLayers_ = dir.make("HisLayers", ";", 8, 0, 8); + hisNumLayers_ = dir.make("HisNumLayers", ";", 9, 0, 9); + profNumLayers_ = dir.make("Prof NumLayers", ";", 32, 0, 2.4); } - void AnalyzerHT::analyze(const Event& iEvent, const EventSetup& iSetup) { + void AnalyzerHT::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + auto fill = [this](const TPPtr& tpPtr, TH1F* hisEta, TH1F* hisZT, TH1F* hisInv2R, TH1F* hisPT) { + const double tpPhi0 = tpPtr->phi(); + const double tpCot = sinh(tpPtr->eta()); + const math::XYZPointD& v = tpPtr->vertex(); + const double tpZ0 = v.z() - tpCot * (v.x() * cos(tpPhi0) + v.y() * sin(tpPhi0)); + const double tpZT = tpZ0 + tpCot * setup_->chosenRofZ(); + hisEta->Fill(tpPtr->eta()); + hisZT->Fill(tpZT); + hisInv2R->Fill(tpPtr->charge() / tpPtr->pt() * setup_->invPtToDphi()); + hisPT->Fill(tpPtr->pt()); + }; // read in ht products - Handle handleAccepted; - iEvent.getByToken(edGetTokenAccepted_, handleAccepted); - Handle handleLost; - iEvent.getByToken(edGetTokenLost_, handleLost); + edm::Handle handleStubs; + iEvent.getByToken(edGetToken_, handleStubs); // read in MCTruth - const StubAssociation* selection = nullptr; - const StubAssociation* reconstructable = nullptr; + const tt::StubAssociation* selection = nullptr; + const tt::StubAssociation* reconstructable = nullptr; if (useMCTruth_) { - Handle handleSelection; - iEvent.getByToken(edGetTokenSelection_, handleSelection); + edm::Handle handleSelection; + iEvent.getByToken(edGetTokenSelection_, handleSelection); selection = handleSelection.product(); prof_->Fill(9, selection->numTPs()); - Handle handleReconstructable; - iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); + edm::Handle handleReconstructable; + iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); reconstructable = handleReconstructable.product(); + for (const auto& p : selection->getTrackingParticleToTTStubsMap()) + fill(p.first, hisEffEtaTotal_, hisEffZTTotal_, hisEffInv2RTotal_, hisEffPTTotal_); } // analyze ht products and associate found tracks with reconstrucable TrackingParticles - set tpPtrs; - set tpPtrsSelection; - set tpPtrsLost; + std::set tpPtrs; + std::set tpPtrsSelection; int allMatched(0); int allTracks(0); for (int region = 0; region < setup_->numRegions(); region++) { int nStubs(0); int nTracks(0); - int nLost(0); for (int channel = 0; channel < dataFormats_->numChannel(Process::ht); channel++) { - const int inv2R = dataFormats_->format(Variable::inv2R, Process::ht).toSigned(channel); const int index = region * dataFormats_->numChannel(Process::ht) + channel; - const StreamStub& accepted = handleAccepted->at(index); + const tt::StreamStub& accepted = handleStubs->at(index); hisChannel_->Fill(accepted.size()); profChannel_->Fill(channel, accepted.size()); nStubs += accepted.size(); - vector> tracks; - vector> lost; - formTracks(accepted, tracks, inv2R); - formTracks(handleLost->at(index), lost, inv2R); + std::vector> tracks; + formTracks(accepted, tracks); nTracks += tracks.size(); allTracks += tracks.size(); - nLost += lost.size(); if (!useMCTruth_) continue; int tmp(0); associate(tracks, selection, tpPtrsSelection, tmp); - associate(lost, selection, tpPtrsLost, tmp); associate(tracks, reconstructable, tpPtrs, allMatched); } prof_->Fill(1, nStubs); prof_->Fill(2, nTracks); - prof_->Fill(3, nLost); } - vector recovered; - recovered.reserve(tpPtrsLost.size()); - set_intersection(tpPtrsLost.begin(), tpPtrsLost.end(), tpPtrs.begin(), tpPtrs.end(), back_inserter(recovered)); - for (const TPPtr& tpPtr : recovered) - tpPtrsLost.erase(tpPtr); + for (const TPPtr& tpPtr : tpPtrsSelection) + fill(tpPtr, hisEffEta_, hisEffZT_, hisEffInv2R_, hisEffPT_); prof_->Fill(4, allMatched); prof_->Fill(5, allTracks); prof_->Fill(6, tpPtrs.size()); prof_->Fill(7, tpPtrsSelection.size()); - prof_->Fill(8, tpPtrsLost.size()); nEvents_++; } void AnalyzerHT::endJob() { if (nEvents_ == 0) return; + // effi + effEta_->SetPassedHistogram(*hisEffEta_, "f"); + effEta_->SetTotalHistogram(*hisEffEtaTotal_, "f"); + effZT_->SetPassedHistogram(*hisEffZT_, "f"); + effZT_->SetTotalHistogram(*hisEffZTTotal_, "f"); + effInv2R_->SetPassedHistogram(*hisEffInv2R_, "f"); + effInv2R_->SetTotalHistogram(*hisEffInv2RTotal_, "f"); + effPT_->SetPassedHistogram(*hisEffPT_, "f"); + effPT_->SetTotalHistogram(*hisEffPTTotal_, "f"); // printout HT summary const double totalTPs = prof_->GetBinContent(9); const double numStubs = prof_->GetBinContent(1); const double numTracks = prof_->GetBinContent(2); - const double numTracksLost = prof_->GetBinContent(3); const double totalTracks = prof_->GetBinContent(5); const double numTracksMatched = prof_->GetBinContent(4); const double numTPsAll = prof_->GetBinContent(6); const double numTPsEff = prof_->GetBinContent(7); - const double numTPsLost = prof_->GetBinContent(8); const double errStubs = prof_->GetBinError(1); const double errTracks = prof_->GetBinError(2); - const double errTracksLost = prof_->GetBinError(3); const double fracFake = (totalTracks - numTracksMatched) / totalTracks; const double fracDup = (numTracksMatched - numTPsAll) / totalTracks; const double eff = numTPsEff / totalTPs; const double errEff = sqrt(eff * (1. - eff) / totalTPs / nEvents_); - const double effLoss = numTPsLost / totalTPs; - const double errEffLoss = sqrt(effLoss * (1. - effLoss) / totalTPs / nEvents_); - const vector nums = {numStubs, numTracks, numTracksLost}; - const vector errs = {errStubs, errTracks, errTracksLost}; - const int wNums = ceil(log10(*max_element(nums.begin(), nums.end()))) + 5; - const int wErrs = ceil(log10(*max_element(errs.begin(), errs.end()))) + 5; - log_ << " HT SUMMARY " << endl; - log_ << "number of stubs per TFP = " << setw(wNums) << numStubs << " +- " << setw(wErrs) << errStubs << endl; - log_ << "number of tracks per TFP = " << setw(wNums) << numTracks << " +- " << setw(wErrs) << errTracks - << endl; - log_ << "number of lost tracks per TFP = " << setw(wNums) << numTracksLost << " +- " << setw(wErrs) << errTracksLost - << endl; - log_ << " max tracking efficiency = " << setw(wNums) << eff << " +- " << setw(wErrs) << errEff << endl; - log_ << " lost tracking efficiency = " << setw(wNums) << effLoss << " +- " << setw(wErrs) << errEffLoss << endl; - log_ << " fake rate = " << setw(wNums) << fracFake << endl; - log_ << " duplicate rate = " << setw(wNums) << fracDup << endl; + const std::vector nums = {numStubs, numTracks}; + const std::vector errs = {errStubs, errTracks}; + const int wNums = std::ceil(std::log10(*std::max_element(nums.begin(), nums.end()))) + 5; + const int wErrs = std::ceil(std::log10(*std::max_element(errs.begin(), errs.end()))) + 5; + log_ << " HT SUMMARY " << std::endl; + log_ << "number of stubs per TFP = " << std::setw(wNums) << numStubs << " +- " << std::setw(wErrs) << errStubs + << std::endl; + log_ << "number of tracks per TFP = " << std::setw(wNums) << numTracks << " +- " << std::setw(wErrs) + << errTracks << std::endl; + log_ << " max tracking efficiency = " << std::setw(wNums) << eff << " +- " << std::setw(wErrs) << errEff + << std::endl; + log_ << " fake rate = " << std::setw(wNums) << fracFake << std::endl; + log_ << " duplicate rate = " << std::setw(wNums) << fracDup << std::endl; log_ << "============================================================="; - LogPrint("L1Trigger/TrackerTFP") << log_.str(); + edm::LogPrint(moduleDescription().moduleName()) << log_.str(); } // - void AnalyzerHT::formTracks(const StreamStub& stream, vector>& tracks, int inv2R) const { - vector stubs; + void AnalyzerHT::formTracks(const tt::StreamStub& stream, std::vector>& tracks) const { + static const DataFormat& layer = dataFormats_->format(Variable::layer, Process::ctb); + auto toTrkId = [this](const StubHT& stub) { + static const DataFormat& phiT = dataFormats_->format(Variable::phiT, Process::ht); + static const DataFormat& zT = dataFormats_->format(Variable::zT, Process::ht); + return (phiT.ttBV(stub.phiT()) + zT.ttBV(stub.zT())).val(); + }; + std::vector stubs; stubs.reserve(stream.size()); - for (const FrameStub& frame : stream) - stubs.emplace_back(frame, dataFormats_, inv2R); + for (const tt::FrameStub& frame : stream) + stubs.emplace_back(frame, dataFormats_); for (auto it = stubs.begin(); it != stubs.end();) { const auto start = it; - const int id = it->trackId(); - auto different = [id](const StubHT& stub) { return id != stub.trackId(); }; - it = find_if(it, stubs.end(), different); - vector ttStubRefs; - ttStubRefs.reserve(distance(start, it)); - transform(start, it, back_inserter(ttStubRefs), [](const StubHT& stub) { return stub.ttStubRef(); }); + const int id = toTrkId(*it); + auto different = [id, toTrkId](const StubHT& stub) { return id != toTrkId(stub); }; + it = std::find_if(it, stubs.end(), different); + std::vector ttStubRefs; + ttStubRefs.reserve(std::distance(start, it)); + std::transform(start, it, std::back_inserter(ttStubRefs), [](const StubHT& stub) { return stub.frame().first; }); tracks.push_back(ttStubRefs); + TTBV hitPattern(0, setup_->numLayers()); + for (auto iter = start; iter != it; iter++) + hitPattern.set(iter->layer().val(layer.width())); + const double cot = dataFormats_->format(Variable::zT, Process::ht).floating(start->zT()) / setup_->chosenRofZ(); + hisNumLayers_->Fill(hitPattern.count()); + profNumLayers_->Fill(abs(sinh(cot)), hitPattern.count()); + for (int layer : hitPattern.ids()) + hisLayers_->Fill(layer); } } // - void AnalyzerHT::associate(const vector>& tracks, - const StubAssociation* ass, - set& tps, + void AnalyzerHT::associate(const std::vector>& tracks, + const tt::StubAssociation* ass, + std::set& tps, int& sum) const { - for (const vector& ttStubRefs : tracks) { - const vector& tpPtrs = ass->associate(ttStubRefs); + for (const std::vector& ttStubRefs : tracks) { + const std::vector& tpPtrs = ass->associate(ttStubRefs); if (tpPtrs.empty()) continue; sum++; - copy(tpPtrs.begin(), tpPtrs.end(), inserter(tps, tps.begin())); + std::copy(tpPtrs.begin(), tpPtrs.end(), std::inserter(tps, tps.begin())); } } diff --git a/L1Trigger/TrackerTFP/test/AnalyzerKF.cc b/L1Trigger/TrackerTFP/test/AnalyzerKF.cc index 3f0b215080aca..763fe8bc6fa13 100644 --- a/L1Trigger/TrackerTFP/test/AnalyzerKF.cc +++ b/L1Trigger/TrackerTFP/test/AnalyzerKF.cc @@ -15,7 +15,6 @@ #include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" #include "L1Trigger/TrackTrigger/interface/Setup.h" #include "L1Trigger/TrackerTFP/interface/DataFormats.h" -#include "L1Trigger/TrackerTFP/interface/LayerEncoding.h" #include "L1Trigger/TrackerTFP/interface/KalmanFilterFormats.h" #include @@ -28,10 +27,7 @@ #include #include #include - -using namespace std; -using namespace edm; -using namespace tt; +#include namespace trackerTFP { @@ -40,52 +36,48 @@ namespace trackerTFP { * \author Thomas Schuh * \date 2020, Sep */ - class AnalyzerKF : public one::EDAnalyzer { + class AnalyzerKF : public edm::one::EDAnalyzer { public: - AnalyzerKF(const ParameterSet& iConfig); + AnalyzerKF(const edm::ParameterSet& iConfig); void beginJob() override {} - void beginRun(const Run& iEvent, const EventSetup& iSetup) override; - void analyze(const Event& iEvent, const EventSetup& iSetup) override; - void endRun(const Run& iEvent, const EventSetup& iSetup) override {} + void beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override; + void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override; + void endRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override {} void endJob() override; private: // - void associate(const TTTracks& ttTracks, - const StubAssociation* ass, - set& tps, + void associate(const std::vector& tracks, + const std::vector>& stubs, + int region, + const tt::StubAssociation* ass, + std::set& tps, int& sum, - const vector& his, - TProfile* prof) const; - + const std::vector& his, + const std::vector& prof, + bool perfect = true) const; // ED input token of accepted Tracks - EDGetTokenT edGetTokenAcceptedStubs_; + edm::EDGetTokenT edGetTokenStubs_; // ED input token of accepted Stubs - EDGetTokenT edGetTokenAcceptedTracks_; - // ED input token of lost Stubs - EDGetTokenT edGetTokenLostStubs_; - // ED input token of lost Tracks - EDGetTokenT edGetTokenLostTracks_; + edm::EDGetTokenT edGetTokenTracks_; // ED input token for number of accepted States - EDGetTokenT edGetTokenNumAcceptedStates_; + edm::EDGetTokenT edGetTokenNumStatesAccepted_; // ED input token for number of lost States - EDGetTokenT edGetTokenNumLostStates_; + edm::EDGetTokenT edGetTokenNumStatesTruncated_; + // ED input token for r-phi and r-z plane chi2s + edm::EDGetTokenT>> edGetTokenChi2s_; // ED input token of TTStubRef to TPPtr association for tracking efficiency - EDGetTokenT edGetTokenSelection_; + edm::EDGetTokenT edGetTokenSelection_; // ED input token of TTStubRef to recontructable TPPtr association - EDGetTokenT edGetTokenReconstructable_; + edm::EDGetTokenT edGetTokenReconstructable_; // Setup token - ESGetToken esGetTokenSetup_; + edm::ESGetToken esGetTokenSetup_; // DataFormats token - ESGetToken esGetTokenDataFormats_; - // LayerEncoding token - ESGetToken esGetTokenLayerEncoding_; + edm::ESGetToken esGetTokenDataFormats_; // stores, calculates and provides run-time constants - const Setup* setup_ = nullptr; + const tt::Setup* setup_ = nullptr; // const DataFormats* dataFormats_ = nullptr; - // - const LayerEncoding* layerEncoding_ = nullptr; // enables analyze of TPs bool useMCTruth_; // @@ -96,209 +88,239 @@ namespace trackerTFP { TProfile* prof_; TProfile* profChannel_; TH1F* hisChannel_; - vector hisRes_; - TProfile* profResZ0_; + std::vector hisRes_; + std::vector profRes_; TH1F* hisEffEta_; TH1F* hisEffEtaTotal_; TEfficiency* effEta_; + TH1F* hisEffZT_; + TH1F* hisEffZTTotal_; + TEfficiency* effZT_; TH1F* hisEffInv2R_; TH1F* hisEffInv2RTotal_; TEfficiency* effInv2R_; - TH1F* hisChi2_; - TH1F* hisPhi_; + TH1F* hisEffPT_; + TH1F* hisEffPTTotal_; + TEfficiency* effPT_; + TH1F* hisChi20s_; + TH1F* hisChi21s_; + TH1F* hisChi2s_; + TH1F* hisTracks_; + TH1F* hisLayers_; + TH1F* hisNumLayers_; + TProfile* profNumLayers_; // printout - stringstream log_; + std::stringstream log_; }; - AnalyzerKF::AnalyzerKF(const ParameterSet& iConfig) - : useMCTruth_(iConfig.getParameter("UseMCTruth")), hisRes_(4) { + AnalyzerKF::AnalyzerKF(const edm::ParameterSet& iConfig) + : useMCTruth_(iConfig.getParameter("UseMCTruth")), nEvents_(0), hisRes_(4), profRes_(4) { usesResource("TFileService"); // book in- and output ED products - const string& label = iConfig.getParameter("LabelKF"); - const string& branchAcceptedStubs = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchAcceptedTracks = iConfig.getParameter("BranchAcceptedTracks"); - const string& branchLostStubs = iConfig.getParameter("BranchLostStubs"); - const string& branchLostTracks = iConfig.getParameter("BranchLostTracks"); - edGetTokenAcceptedStubs_ = consumes(InputTag(label, branchAcceptedStubs)); - edGetTokenAcceptedTracks_ = consumes(InputTag(label, branchAcceptedTracks)); - edGetTokenLostStubs_ = consumes(InputTag(label, branchLostStubs)); - edGetTokenLostTracks_ = consumes(InputTag(label, branchLostTracks)); - edGetTokenNumAcceptedStates_ = consumes(InputTag(label, branchAcceptedTracks)); - ; - edGetTokenNumLostStates_ = consumes(InputTag(label, branchLostTracks)); - ; + const std::string& label = iConfig.getParameter("OutputLabelKF"); + const std::string& branchStubs = iConfig.getParameter("BranchStubs"); + const std::string& branchTracks = iConfig.getParameter("BranchTracks"); + const std::string& branchTruncated = iConfig.getParameter("BranchTruncated"); + edGetTokenStubs_ = consumes(edm::InputTag(label, branchStubs)); + edGetTokenTracks_ = consumes(edm::InputTag(label, branchTracks)); + edGetTokenNumStatesAccepted_ = consumes(edm::InputTag(label, branchTracks)); + edGetTokenNumStatesTruncated_ = consumes(edm::InputTag(label, branchTruncated)); + edGetTokenChi2s_ = consumes>>(edm::InputTag(label, branchTracks)); if (useMCTruth_) { - const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); - const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); - edGetTokenSelection_ = consumes(inputTagSelecttion); - edGetTokenReconstructable_ = consumes(inputTagReconstructable); + const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); + const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); + edGetTokenSelection_ = consumes(inputTagSelecttion); + edGetTokenReconstructable_ = consumes(inputTagReconstructable); } // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); - esGetTokenLayerEncoding_ = esConsumes(); + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); // log config - log_.setf(ios::fixed, ios::floatfield); + log_.setf(std::ios::fixed, std::ios::floatfield); log_.precision(4); } - void AnalyzerKF::beginRun(const Run& iEvent, const EventSetup& iSetup) { + void AnalyzerKF::beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) { // helper class to store configurations setup_ = &iSetup.getData(esGetTokenSetup_); dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); - layerEncoding_ = &iSetup.getData(esGetTokenLayerEncoding_); // book histograms - Service fs; + edm::Service fs; TFileDirectory dir; dir = fs->mkdir("KF"); - prof_ = dir.make("Counts", ";", 11, 0.5, 11.5); + prof_ = dir.make("Counts", ";", 12, 0.5, 12.5); prof_->GetXaxis()->SetBinLabel(1, "Stubs"); prof_->GetXaxis()->SetBinLabel(2, "Tracks"); - prof_->GetXaxis()->SetBinLabel(3, "Lost Tracks"); prof_->GetXaxis()->SetBinLabel(4, "Matched Tracks"); prof_->GetXaxis()->SetBinLabel(5, "All Tracks"); prof_->GetXaxis()->SetBinLabel(6, "Found TPs"); prof_->GetXaxis()->SetBinLabel(7, "Found selected TPs"); - prof_->GetXaxis()->SetBinLabel(8, "Lost TPs"); prof_->GetXaxis()->SetBinLabel(9, "All TPs"); prof_->GetXaxis()->SetBinLabel(10, "states"); - prof_->GetXaxis()->SetBinLabel(11, "lost states"); + prof_->GetXaxis()->SetBinLabel(12, "max tp"); // channel occupancy constexpr int maxOcc = 180; const int numChannels = dataFormats_->numChannel(Process::kf); hisChannel_ = dir.make("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5); profChannel_ = dir.make("Prof Channel Occupancy", ";", numChannels, -.5, numChannels - .5); // resoultions - static const vector names = {"phiT", "inv2R", "zT", "cot"}; - static const vector ranges = {.01, .1, 5, .1}; + static const std::vector names = {"phi0", "inv2R", "z0", "cot"}; + static const std::vector ranges = {.01, .004, 20., .4}; for (int i = 0; i < 4; i++) { const double range = ranges[i]; hisRes_[i] = dir.make(("HisRes" + names[i]).c_str(), ";", 100, -range, range); + profRes_[i] = dir.make(("ProfRes" + names[i]).c_str(), ";", 32, 0, 2.4); } - profResZ0_ = dir.make("ProfResZ0", ";", 32, 0, 2.5); // Efficiencies - hisEffEtaTotal_ = dir.make("HisTPEtaTotal", ";", 128, -2.5, 2.5); - hisEffEta_ = dir.make("HisTPEta", ";", 128, -2.5, 2.5); - effEta_ = dir.make("EffEta", ";", 128, -2.5, 2.5); + hisEffEtaTotal_ = dir.make("HisTPEtaTotal", ";", 48, -2.4, 2.4); + hisEffEta_ = dir.make("HisTPEta", ";", 48, -2.4, 2.4); + effEta_ = dir.make("EffEta", ";", 48, -2.4, 2.4); + const int zTBins = setup_->gpNumBinsZT(); + hisEffZTTotal_ = dir.make("HisTPZTTotal", ";", zTBins, -zTBins / 2, zTBins / 2); + hisEffZT_ = dir.make("HisTPZT", ";", zTBins, -zTBins / 2, zTBins / 2); + effZT_ = dir.make("EffZT", ";", zTBins, -zTBins / 2, zTBins / 2); const double rangeInv2R = dataFormats_->format(Variable::inv2R, Process::dr).range(); hisEffInv2R_ = dir.make("HisTPInv2R", ";", 32, -rangeInv2R / 2., rangeInv2R / 2.); hisEffInv2RTotal_ = dir.make("HisTPInv2RTotal", ";", 32, -rangeInv2R / 2., rangeInv2R / 2.); effInv2R_ = dir.make("EffInv2R", ";", 32, -rangeInv2R / 2., rangeInv2R / 2.); - // chi2 - hisChi2_ = dir.make("HisChi2", ";", 100, -.5, 99.5); - const double rangePhi = dataFormats_->format(Variable::phi0, Process::dr).range(); - hisPhi_ = dir.make("HisPhi", ";", 100, -rangePhi, rangePhi); + hisEffPT_ = dir.make("HisTPPT", ";", 100, 0, 100); + hisEffPTTotal_ = dir.make("HisTPPTTotal", ";", 100, 0, 100); + effPT_ = dir.make("EffPT", ";", 100, 0, 100); + // chi2s + hisChi20s_ = dir.make("HisChi20", ";", 128, 0., 10); + hisChi21s_ = dir.make("HisChi21", ";", 128, 0., 10); + hisChi2s_ = dir.make("HisChi2", ";", 128, 0., 10); + // tracks + hisTracks_ = dir.make("HisTracks", ";", 40, 0., 400); + // layers + hisLayers_ = dir.make("HisLayers", ";", 8, 0, 8); + hisNumLayers_ = dir.make("HisNumLayers", ";", 9, 0, 9); + profNumLayers_ = dir.make("Prof NumLayers", ";", 32, 0, 2.4); } - void AnalyzerKF::analyze(const Event& iEvent, const EventSetup& iSetup) { - auto fill = [this](const TPPtr& tpPtr, TH1F* hisEta, TH1F* hisInv2R) { + void AnalyzerKF::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + static const int numChannel = dataFormats_->numChannel(Process::kf); + static const int numLayers = setup_->numLayers(); + auto fill = [this](const TPPtr& tpPtr, TH1F* hisEta, TH1F* hisZT, TH1F* hisInv2R, TH1F* hisPT) { + const double tpPhi0 = tpPtr->phi(); + const double tpCot = sinh(tpPtr->eta()); + const math::XYZPointD& v = tpPtr->vertex(); + const double tpZ0 = v.z() - tpCot * (v.x() * cos(tpPhi0) + v.y() * sin(tpPhi0)); + const double tpZT = tpZ0 + tpCot * setup_->chosenRofZ(); hisEta->Fill(tpPtr->eta()); + hisZT->Fill(dataFormats_->format(Variable::zT, Process::gp).integer(tpZT)); hisInv2R->Fill(tpPtr->charge() / tpPtr->pt() * setup_->invPtToDphi()); + hisPT->Fill(tpPtr->pt()); }; // read in kf products - Handle handleAcceptedStubs; - iEvent.getByToken(edGetTokenAcceptedStubs_, handleAcceptedStubs); - const StreamsStub& acceptedStubs = *handleAcceptedStubs; - Handle handleAcceptedTracks; - iEvent.getByToken(edGetTokenAcceptedTracks_, handleAcceptedTracks); - Handle handleLostStubs; - iEvent.getByToken(edGetTokenLostStubs_, handleLostStubs); - const StreamsStub& lostStubs = *handleLostStubs; - Handle handleLostTracks; - iEvent.getByToken(edGetTokenLostTracks_, handleLostTracks); - Handle handleNumAcceptedStates; - iEvent.getByToken(edGetTokenNumAcceptedStates_, handleNumAcceptedStates); - Handle handleNumLostStates; - iEvent.getByToken(edGetTokenNumLostStates_, handleNumLostStates); + edm::Handle handleStubs; + iEvent.getByToken(edGetTokenStubs_, handleStubs); + const tt::StreamsStub& allStubs = *handleStubs; + edm::Handle handleTracks; + iEvent.getByToken(edGetTokenTracks_, handleTracks); + const tt::StreamsTrack& allTracks = *handleTracks; + edm::Handle handleNumStatesAccepted; + iEvent.getByToken(edGetTokenNumStatesAccepted_, handleNumStatesAccepted); + edm::Handle handleNumStatesTruncated; + iEvent.getByToken(edGetTokenNumStatesTruncated_, handleNumStatesTruncated); + edm::Handle>> handleChi2s; + iEvent.getByToken>>(edGetTokenChi2s_, handleChi2s); // read in MCTruth - const StubAssociation* selection = nullptr; - const StubAssociation* reconstructable = nullptr; + const tt::StubAssociation* selection = nullptr; + const tt::StubAssociation* reconstructable = nullptr; if (useMCTruth_) { - Handle handleSelection; - iEvent.getByToken(edGetTokenSelection_, handleSelection); + edm::Handle handleSelection; + iEvent.getByToken(edGetTokenSelection_, handleSelection); selection = handleSelection.product(); prof_->Fill(9, selection->numTPs()); - Handle handleReconstructable; - iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); + edm::Handle handleReconstructable; + iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); reconstructable = handleReconstructable.product(); for (const auto& p : selection->getTrackingParticleToTTStubsMap()) - fill(p.first, hisEffEtaTotal_, hisEffInv2RTotal_); + fill(p.first, hisEffEtaTotal_, hisEffZTTotal_, hisEffInv2RTotal_, hisEffPTTotal_); + } + // chi2s + for (const std::pair& chi2s : *handleChi2s) { + hisChi20s_->Fill(chi2s.first * 2.); + hisChi21s_->Fill(chi2s.second * 2.); + hisChi2s_->Fill(chi2s.first + chi2s.second); } // analyze kf products and associate found tracks with reconstrucable TrackingParticles - set tpPtrs; - set tpPtrsSelection; - set tpPtrsLost; - int allMatched(0); - int allTracks(0); - auto consume = [this](const StreamTrack& tracks, const StreamsStub& streams, int channel, TTTracks& ttTracks) { - const int offset = channel * setup_->numLayers(); - int pos(0); - for (const FrameTrack& frameTrack : tracks) { - vector stubs; - stubs.reserve(setup_->numLayers()); - for (int layer = 0; layer < setup_->numLayers(); layer++) { - const FrameStub& frameStub = streams[offset + layer][pos]; - if (frameStub.first.isNonnull()) - stubs.emplace_back(frameStub, dataFormats_, layer); - } - TrackKF track(frameTrack, dataFormats_); - ttTracks.emplace_back(track.ttTrack(stubs)); - pos++; - } - }; + std::set tpPtrs; + std::set tpPtrsSelection; + std::set tpPtrsMax; + int numMatched(0); + int numTracks(0); for (int region = 0; region < setup_->numRegions(); region++) { - int nStubsRegion(0); - int nTracksRegion(0); - int nLostRegion(0); - for (int channel = 0; channel < dataFormats_->numChannel(Process::kf); channel++) { - const int index = region * dataFormats_->numChannel(Process::kf) + channel; - const StreamTrack& accepted = handleAcceptedTracks->at(index); - const StreamTrack& lost = handleLostTracks->at(index); - hisChannel_->Fill(accepted.size()); - profChannel_->Fill(channel, accepted.size()); - TTTracks tracks; - const int nTracks = accumulate(accepted.begin(), accepted.end(), 0, [](int sum, const FrameTrack& frame) { - return sum + (frame.first.isNonnull() ? 1 : 0); - }); - nTracksRegion += nTracks; - tracks.reserve(nTracks); - consume(accepted, acceptedStubs, index, tracks); - for (const TTTrack& ttTrack : tracks) - hisPhi_->Fill(ttTrack.momentum().phi()); - nStubsRegion += accumulate(tracks.begin(), tracks.end(), 0, [](int sum, const auto& ttTrack) { - return sum + (int)ttTrack.getStubRefs().size(); - }); - TTTracks tracksLost; - const int nLost = accumulate(lost.begin(), lost.end(), 0, [](int sum, const FrameTrack& frame) { - return sum + (frame.first.isNonnull() ? 1 : 0); - }); - nLostRegion += nLost; - tracksLost.reserve(nLost); - consume(lost, lostStubs, index, tracksLost); - allTracks += nTracks; + int nRegionStubs(0); + int nRegionTracks(0); + for (int channel = 0; channel < numChannel; channel++) { + const int index = region * numChannel + channel; + const int offset = index * numLayers; + const tt::StreamTrack& channelTracks = allTracks[index]; + hisChannel_->Fill(channelTracks.size()); + profChannel_->Fill(channel, channelTracks.size()); + std::vector tracks; + std::vector stubs; + std::vector> tracksStubs(channelTracks.size(), std::vector(numLayers, nullptr)); + tracks.reserve(channelTracks.size()); + stubs.reserve(channelTracks.size() * numLayers); + for (int frame = 0; frame < static_cast(channelTracks.size()); frame++) { + tracks.emplace_back(channelTracks[frame], dataFormats_); + const double cot = tracks.back().zT() / setup_->chosenRofZ(); + int nLs(0); + for (int layer = 0; layer < numLayers; layer++) { + const tt::FrameStub& fs = allStubs[offset + layer][frame]; + if (fs.first.isNull()) + continue; + stubs.emplace_back(fs, dataFormats_); + tracksStubs[frame][layer] = &stubs.back(); + hisLayers_->Fill(layer); + nLs++; + } + hisNumLayers_->Fill(nLs); + profNumLayers_->Fill(abs(sinh(cot)), nLs); + } + nRegionStubs += stubs.size(); + nRegionTracks += tracks.size(); if (!useMCTruth_) continue; int tmp(0); - associate(tracks, selection, tpPtrsSelection, tmp, hisRes_, profResZ0_); - associate(tracksLost, selection, tpPtrsLost, tmp, vector(), nullptr); - associate(tracks, reconstructable, tpPtrs, allMatched, vector(), nullptr); + associate(tracks, tracksStubs, region, selection, tpPtrsSelection, tmp, hisRes_, profRes_); + associate(tracks, + tracksStubs, + region, + reconstructable, + tpPtrs, + numMatched, + std::vector(), + std::vector(), + false); + associate(tracks, + tracksStubs, + region, + selection, + tpPtrsMax, + tmp, + std::vector(), + std::vector(), + false); } - prof_->Fill(1, nStubsRegion); - prof_->Fill(2, nTracksRegion); - prof_->Fill(3, nLostRegion); + numTracks += nRegionTracks; + prof_->Fill(1, nRegionStubs); + prof_->Fill(2, nRegionTracks); } for (const TPPtr& tpPtr : tpPtrsSelection) - fill(tpPtr, hisEffEta_, hisEffInv2R_); - deque tpPtrsRealLost; - set_difference(tpPtrsLost.begin(), tpPtrsLost.end(), tpPtrs.begin(), tpPtrs.end(), back_inserter(tpPtrsRealLost)); - prof_->Fill(4, allMatched); - prof_->Fill(5, allTracks); + fill(tpPtr, hisEffEta_, hisEffZT_, hisEffInv2R_, hisEffPT_); + prof_->Fill(4, numMatched); + prof_->Fill(5, numTracks); prof_->Fill(6, tpPtrs.size()); prof_->Fill(7, tpPtrsSelection.size()); - prof_->Fill(8, tpPtrsRealLost.size()); - prof_->Fill(10, *handleNumAcceptedStates); - prof_->Fill(11, *handleNumLostStates); + prof_->Fill(10, *handleNumStatesAccepted); + prof_->Fill(11, *handleNumStatesTruncated); + prof_->Fill(12, tpPtrsMax.size()); + hisTracks_->Fill(numTracks); nEvents_++; } @@ -308,79 +330,106 @@ namespace trackerTFP { // effi effEta_->SetPassedHistogram(*hisEffEta_, "f"); effEta_->SetTotalHistogram(*hisEffEtaTotal_, "f"); + effZT_->SetPassedHistogram(*hisEffZT_, "f"); + effZT_->SetTotalHistogram(*hisEffZTTotal_, "f"); effInv2R_->SetPassedHistogram(*hisEffInv2R_, "f"); effInv2R_->SetTotalHistogram(*hisEffInv2RTotal_, "f"); + effPT_->SetPassedHistogram(*hisEffPT_, "f"); + effPT_->SetTotalHistogram(*hisEffPTTotal_, "f"); // printout SF summary const double totalTPs = prof_->GetBinContent(9); const double numStubs = prof_->GetBinContent(1); const double numTracks = prof_->GetBinContent(2); - const double numTracksLost = prof_->GetBinContent(3); const double totalTracks = prof_->GetBinContent(5); const double numTracksMatched = prof_->GetBinContent(4); const double numTPsAll = prof_->GetBinContent(6); const double numTPsEff = prof_->GetBinContent(7); - const double numTPsLost = prof_->GetBinContent(8); + const double numTPsEffMax = prof_->GetBinContent(12); const double errStubs = prof_->GetBinError(1); const double errTracks = prof_->GetBinError(2); - const double errTracksLost = prof_->GetBinError(3); const double fracFake = (totalTracks - numTracksMatched) / totalTracks; const double fracDup = (numTracksMatched - numTPsAll) / totalTracks; const double eff = numTPsEff / totalTPs; const double errEff = sqrt(eff * (1. - eff) / totalTPs / nEvents_); - const double effLoss = numTPsLost / totalTPs; - const double errEffLoss = sqrt(effLoss * (1. - effLoss) / totalTPs / nEvents_); + const double effMax = numTPsEffMax / totalTPs; + const double errEffMax = sqrt(effMax * (1. - effMax) / totalTPs / nEvents_); const int numStates = prof_->GetBinContent(10); const int numStatesLost = prof_->GetBinContent(11); const double fracSatest = numStates / (double)(numStates + numStatesLost); - const vector nums = {numStubs, numTracks, numTracksLost}; - const vector errs = {errStubs, errTracks, errTracksLost}; - const int wNums = ceil(log10(*max_element(nums.begin(), nums.end()))) + 5; - const int wErrs = ceil(log10(*max_element(errs.begin(), errs.end()))) + 5; - log_ << " KF SUMMARY " << endl; - log_ << "number of stubs per TFP = " << setw(wNums) << numStubs << " +- " << setw(wErrs) << errStubs << endl; - log_ << "number of tracks per TFP = " << setw(wNums) << numTracks << " +- " << setw(wErrs) << errTracks - << endl; - log_ << "number of lost tracks per TFP = " << setw(wNums) << numTracksLost << " +- " << setw(wErrs) << errTracksLost - << endl; - log_ << " tracking efficiency = " << setw(wNums) << eff << " +- " << setw(wErrs) << errEff << endl; - log_ << " lost tracking efficiency = " << setw(wNums) << effLoss << " +- " << setw(wErrs) << errEffLoss << endl; - log_ << " fake rate = " << setw(wNums) << fracFake << endl; - log_ << " duplicate rate = " << setw(wNums) << fracDup << endl; - log_ << " state assessment fraction = " << setw(wNums) << fracSatest << endl; + const std::vector nums = {numStubs, numTracks}; + const std::vector errs = {errStubs, errTracks}; + const int wNums = std::ceil(std::log10(*std::max_element(nums.begin(), nums.end()))) + 5; + const int wErrs = std::ceil(std::log10(*std::max_element(errs.begin(), errs.end()))) + 5; + log_ << " KF SUMMARY " << std::endl; + log_ << "number of stubs per TFP = " << std::setw(wNums) << numStubs << " +- " << std::setw(wErrs) << errStubs + << std::endl; + log_ << "number of tracks per TFP = " << std::setw(wNums) << numTracks << " +- " << std::setw(wErrs) + << errTracks << std::endl; + log_ << " tracking efficiency = " << std::setw(wNums) << eff << " +- " << std::setw(wErrs) << errEff + << std::endl; + log_ << " max tracking efficiency = " << std::setw(wNums) << effMax << " +- " << std::setw(wErrs) << errEffMax + << std::endl; + log_ << " fake rate = " << std::setw(wNums) << fracFake << std::endl; + log_ << " duplicate rate = " << std::setw(wNums) << fracDup << std::endl; + log_ << " state assessment fraction = " << std::setw(wNums) << fracSatest << std::endl; + log_ << " number of states per TFP = " << std::setw(wNums) << (numStates + numStatesLost) / setup_->numRegions() + << std::endl; log_ << "============================================================="; - LogPrint("L1Trigger/TrackerTFP") << log_.str(); + edm::LogPrint(moduleDescription().moduleName()) << log_.str(); } // - void AnalyzerKF::associate(const TTTracks& ttTracks, - const StubAssociation* ass, - set& tps, + void AnalyzerKF::associate(const std::vector& tracks, + const std::vector>& tracksStubs, + int region, + const tt::StubAssociation* ass, + std::set& tps, int& sum, - const vector& his, - TProfile* prof) const { - for (const TTTrack& ttTrack : ttTracks) { - const vector& ttStubRefs = ttTrack.getStubRefs(); - const vector& tpPtrs = ass->associateFinal(ttStubRefs); + const std::vector& his, + const std::vector& prof, + bool perfect) const { + for (int frame = 0; frame < static_cast(tracks.size()); frame++) { + const TrackKF& track = tracks[frame]; + const std::vector& stubs = tracksStubs[frame]; + std::vector ttStubRefs; + ttStubRefs.reserve(stubs.size()); + TTBV hitPattern(0, setup_->numLayers()); + int layer(-1); + for (StubKF* stub : stubs) { + layer++; + if (!stub) + continue; + hitPattern.set(layer); + ttStubRefs.push_back(stub->frame().first); + } + const std::vector& tpPtrs = perfect ? ass->associateFinal(ttStubRefs) : ass->associate(ttStubRefs); if (tpPtrs.empty()) continue; sum++; - copy(tpPtrs.begin(), tpPtrs.end(), inserter(tps, tps.begin())); + std::copy(tpPtrs.begin(), tpPtrs.end(), std::inserter(tps, tps.begin())); if (his.empty()) continue; + const double zT = dataFormats_->format(Variable::zT, Process::gp).digi(track.zT()); + const double cot = zT / setup_->chosenRofZ() + track.cot(); + const double z0 = track.zT() - setup_->chosenRofZ() * cot; + const double inv2R = track.inv2R(); + const double phi0 = tt::deltaPhi(track.phiT() - setup_->chosenRofPhi() * inv2R + + region * dataFormats_->format(Variable::phiT, Process::kf).range()); for (const TPPtr& tpPtr : tpPtrs) { - const double phi0 = tpPtr->phi(); - const double cot = sinh(tpPtr->eta()); - const double inv2R = setup_->invPtToDphi() * tpPtr->charge() / tpPtr->pt(); + const double tpPhi0 = tpPtr->phi(); + const double tpCot = std::sinh(tpPtr->eta()); + const double tpInv2R = -setup_->invPtToDphi() * tpPtr->charge() / tpPtr->pt(); const math::XYZPointD& v = tpPtr->vertex(); - const double z0 = v.z() - cot * (v.x() * cos(phi0) + v.y() * sin(phi0)); - const double dCot = cot - ttTrack.tanL(); - const double dZ0 = z0 - ttTrack.z0(); - const double dInv2R = inv2R - ttTrack.rInv(); - const double dPhi0 = deltaPhi(phi0 - ttTrack.phi()); - const vector ds = {dPhi0, dInv2R, dZ0, dCot}; - for (int i = 0; i < (int)ds.size(); i++) + const double tpZ0 = v.z() - tpCot * (v.x() * cos(tpPhi0) + v.y() * sin(tpPhi0)); + const double dCot = tpCot - cot; + const double dZ0 = tpZ0 - z0; + const double dInv2R = tpInv2R - inv2R; + const double dPhi0 = tt::deltaPhi(tpPhi0 - phi0); + const std::vector ds = {dPhi0, dInv2R / setup_->invPtToDphi(), dZ0, dCot}; + for (int i = 0; i < static_cast(ds.size()); i++) { his[i]->Fill(ds[i]); - prof->Fill(abs(tpPtr->eta()), abs(dZ0)); + prof[i]->Fill(abs(tpPtr->eta()), abs(ds[i])); + } } } } diff --git a/L1Trigger/TrackerTFP/test/AnalyzerKFin.cc b/L1Trigger/TrackerTFP/test/AnalyzerKFin.cc deleted file mode 100644 index 14a821ff226fc..0000000000000 --- a/L1Trigger/TrackerTFP/test/AnalyzerKFin.cc +++ /dev/null @@ -1,314 +0,0 @@ -#include "FWCore/Framework/interface/one/EDAnalyzer.h" -#include "FWCore/Framework/interface/Run.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/ServiceRegistry/interface/Service.h" -#include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "FWCore/Utilities/interface/EDGetToken.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/Utilities/interface/Exception.h" -#include "CommonTools/UtilAlgos/interface/TFileService.h" -#include "DataFormats/Common/interface/Handle.h" - -#include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" -#include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" - -#include -#include - -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace edm; -using namespace trackerTFP; -using namespace tt; - -namespace trackerTFP { - - /*! \class trackerTFP::AnalyzerKFin - * \brief Class to analyze hardware like structured TTStub Collection generated by Seed Filter - * \author Thomas Schuh - * \date 2020, April - */ - class AnalyzerKFin : public one::EDAnalyzer { - public: - AnalyzerKFin(const ParameterSet& iConfig); - void beginJob() override {} - void beginRun(const Run& iEvent, const EventSetup& iSetup) override; - void analyze(const Event& iEvent, const EventSetup& iSetup) override; - void endRun(const Run& iEvent, const EventSetup& iSetup) override {} - void endJob() override; - - private: - // - void formTracks(const StreamsTrack& streamsTrack, - const StreamsStub& streamsStubs, - vector>& tracks, - int channel) const; - // - void associate(const vector>& tracks, const StubAssociation* ass, set& tps, int& sum) const; - - // ED input token of stubs - EDGetTokenT edGetTokenAcceptedStubs_; - // ED input token of tracks - EDGetTokenT edGetTokenAcceptedTracks_; - // ED input token of lost stubs - EDGetTokenT edGetTokenLostStubs_; - // ED input token of lost tracks - EDGetTokenT edGetTokenLostTracks_; - // ED input token of TTStubRef to TPPtr association for tracking efficiency - EDGetTokenT edGetTokenSelection_; - // ED input token of TTStubRef to recontructable TPPtr association - EDGetTokenT edGetTokenReconstructable_; - // Setup token - ESGetToken esGetTokenSetup_; - // DataFormats token - ESGetToken esGetTokenDataFormats_; - // stores, calculates and provides run-time constants - const Setup* setup_ = nullptr; - // helper class to extract structured data from tt::Frames - const DataFormats* dataFormats_ = nullptr; - // enables analyze of TPs - bool useMCTruth_; - // - int nEvents_ = 0; - - // Histograms - - TProfile* prof_; - TProfile* profChannel_; - TH1F* hisChannel_; - - // printout - stringstream log_; - }; - - AnalyzerKFin::AnalyzerKFin(const ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { - usesResource("TFileService"); - // book in- and output ED products - const string& label = iConfig.getParameter("LabelKFin"); - const string& branchAcceptedStubs = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchAcceptedTracks = iConfig.getParameter("BranchAcceptedTracks"); - const string& branchLostStubs = iConfig.getParameter("BranchLostStubs"); - const string& branchLostTracks = iConfig.getParameter("BranchLostTracks"); - edGetTokenAcceptedStubs_ = consumes(InputTag(label, branchAcceptedStubs)); - edGetTokenAcceptedTracks_ = consumes(InputTag(label, branchAcceptedTracks)); - edGetTokenLostStubs_ = consumes(InputTag(label, branchLostStubs)); - edGetTokenLostTracks_ = consumes(InputTag(label, branchLostTracks)); - if (useMCTruth_) { - const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); - const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); - edGetTokenSelection_ = consumes(inputTagSelecttion); - edGetTokenReconstructable_ = consumes(inputTagReconstructable); - } - // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); - // log config - log_.setf(ios::fixed, ios::floatfield); - log_.precision(4); - } - - void AnalyzerKFin::beginRun(const Run& iEvent, const EventSetup& iSetup) { - // helper class to store configurations - setup_ = &iSetup.getData(esGetTokenSetup_); - // helper class to extract structured data from tt::Frames - dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); - // book histograms - Service fs; - TFileDirectory dir; - dir = fs->mkdir("KFin"); - prof_ = dir.make("Counts", ";", 9, 0.5, 9.5); - prof_->GetXaxis()->SetBinLabel(1, "Stubs"); - prof_->GetXaxis()->SetBinLabel(2, "Tracks"); - prof_->GetXaxis()->SetBinLabel(3, "Lost Tracks"); - prof_->GetXaxis()->SetBinLabel(4, "Matched Tracks"); - prof_->GetXaxis()->SetBinLabel(5, "All Tracks"); - prof_->GetXaxis()->SetBinLabel(6, "Found TPs"); - prof_->GetXaxis()->SetBinLabel(7, "Found selected TPs"); - prof_->GetXaxis()->SetBinLabel(8, "Lost TPs"); - prof_->GetXaxis()->SetBinLabel(9, "All TPs"); - // channel occupancy - constexpr int maxOcc = 180; - const int numChannels = dataFormats_->numChannel(Process::kfin); - hisChannel_ = dir.make("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5); - profChannel_ = dir.make("Prof Channel Occupancy", ";", numChannels, -.5, numChannels - .5); - } - - void AnalyzerKFin::analyze(const Event& iEvent, const EventSetup& iSetup) { - // read in ht products - Handle handleAcceptedStubs; - iEvent.getByToken(edGetTokenAcceptedStubs_, handleAcceptedStubs); - const StreamsStub& acceptedStubs = *handleAcceptedStubs; - Handle handleAcceptedTracks; - iEvent.getByToken(edGetTokenAcceptedTracks_, handleAcceptedTracks); - const StreamsTrack& acceptedTracks = *handleAcceptedTracks; - Handle handleLostStubs; - iEvent.getByToken(edGetTokenLostStubs_, handleLostStubs); - const StreamsStub& lostStubs = *handleLostStubs; - Handle handleLostTracks; - iEvent.getByToken(edGetTokenLostTracks_, handleLostTracks); - const StreamsTrack& lostTracks = *handleLostTracks; - // read in MCTruth - const StubAssociation* selection = nullptr; - const StubAssociation* reconstructable = nullptr; - if (useMCTruth_) { - Handle handleSelection; - iEvent.getByToken(edGetTokenSelection_, handleSelection); - selection = handleSelection.product(); - prof_->Fill(9, selection->numTPs()); - Handle handleReconstructable; - iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); - reconstructable = handleReconstructable.product(); - } - // analyze ht products and associate found tracks with reconstrucable TrackingParticles - set tpPtrs; - set tpPtrsSelection; - set tpPtrsLost; - int allMatched(0); - int allTracks(0); - for (int region = 0; region < setup_->numRegions(); region++) { - const int offset = region * dataFormats_->numChannel(Process::kf); - int nStubs(0); - int nTracks(0); - int nLost(0); - for (int channel = 0; channel < dataFormats_->numChannel(Process::kf); channel++) { - vector> tracks; - formTracks(acceptedTracks, acceptedStubs, tracks, offset + channel); - vector> lost; - formTracks(lostTracks, lostStubs, lost, offset + channel); - nTracks += tracks.size(); - nStubs += accumulate(tracks.begin(), tracks.end(), 0, [](int sum, const vector& track) { - return sum + (int)track.size(); - }); - nLost += lost.size(); - allTracks += tracks.size(); - if (!useMCTruth_) - continue; - int tmp(0); - associate(tracks, selection, tpPtrsSelection, tmp); - associate(lost, selection, tpPtrsLost, tmp); - associate(tracks, reconstructable, tpPtrs, allMatched); - } - prof_->Fill(1, nStubs); - prof_->Fill(2, nTracks); - prof_->Fill(3, nLost); - } - vector recovered; - recovered.reserve(tpPtrsLost.size()); - set_intersection(tpPtrsLost.begin(), tpPtrsLost.end(), tpPtrs.begin(), tpPtrs.end(), back_inserter(recovered)); - for (const TPPtr& tpPtr : recovered) - tpPtrsLost.erase(tpPtr); - prof_->Fill(4, allMatched); - prof_->Fill(5, allTracks); - prof_->Fill(6, tpPtrs.size()); - prof_->Fill(7, tpPtrsSelection.size()); - prof_->Fill(8, tpPtrsLost.size()); - nEvents_++; - } - - void AnalyzerKFin::endJob() { - if (nEvents_ == 0) - return; - // printout SF summary - const double totalTPs = prof_->GetBinContent(9); - const double numStubs = prof_->GetBinContent(1); - const double numTracks = prof_->GetBinContent(2); - const double numTracksLost = prof_->GetBinContent(3); - const double totalTracks = prof_->GetBinContent(5); - const double numTracksMatched = prof_->GetBinContent(4); - const double numTPsAll = prof_->GetBinContent(6); - const double numTPsEff = prof_->GetBinContent(7); - const double numTPsLost = prof_->GetBinContent(8); - const double errStubs = prof_->GetBinError(1); - const double errTracks = prof_->GetBinError(2); - const double errTracksLost = prof_->GetBinError(3); - const double fracFake = (totalTracks - numTracksMatched) / totalTracks; - const double fracDup = (numTracksMatched - numTPsAll) / totalTracks; - const double eff = numTPsEff / totalTPs; - const double errEff = sqrt(eff * (1. - eff) / totalTPs / nEvents_); - const double effLoss = numTPsLost / totalTPs; - const double errEffLoss = sqrt(effLoss * (1. - effLoss) / totalTPs / nEvents_); - const vector nums = {numStubs, numTracks, numTracksLost}; - const vector errs = {errStubs, errTracks, errTracksLost}; - const int wNums = ceil(log10(*max_element(nums.begin(), nums.end()))) + 5; - const int wErrs = ceil(log10(*max_element(errs.begin(), errs.end()))) + 5; - log_ << " KFin SUMMARY " << endl; - log_ << "number of stubs per TFP = " << setw(wNums) << numStubs << " +- " << setw(wErrs) << errStubs << endl; - log_ << "number of tracks per TFP = " << setw(wNums) << numTracks << " +- " << setw(wErrs) << errTracks - << endl; - log_ << "number of lost tracks per TFP = " << setw(wNums) << numTracksLost << " +- " << setw(wErrs) << errTracksLost - << endl; - log_ << " max tracking efficiency = " << setw(wNums) << eff << " +- " << setw(wErrs) << errEff << endl; - log_ << " lost tracking efficiency = " << setw(wNums) << effLoss << " +- " << setw(wErrs) << errEffLoss << endl; - log_ << " fake rate = " << setw(wNums) << fracFake << endl; - log_ << " duplicate rate = " << setw(wNums) << fracDup << endl; - log_ << "============================================================="; - LogPrint("L1Trigger/TrackerTFP") << log_.str(); - } - - // - void AnalyzerKFin::formTracks(const StreamsTrack& streamsTrack, - const StreamsStub& streamsStubs, - vector>& tracks, - int channel) const { - const int offset = channel * setup_->numLayers(); - const StreamTrack& streamTrack = streamsTrack[channel]; - const int numTracks = accumulate(streamTrack.begin(), streamTrack.end(), 0, [](int sum, const FrameTrack& frame) { - return sum + (frame.first.isNonnull() ? 1 : 0); - }); - tracks.reserve(numTracks); - for (int frame = 0; frame < (int)streamTrack.size(); frame++) { - const FrameTrack& frameTrack = streamTrack[frame]; - if (frameTrack.first.isNull()) - continue; - const auto end = find_if(next(streamTrack.begin(), frame + 1), streamTrack.end(), [](const FrameTrack& frame) { - return frame.first.isNonnull(); - }); - const int size = distance(next(streamTrack.begin(), frame), end); - int numStubs(0); - for (int layer = 0; layer < setup_->numLayers(); layer++) { - const StreamStub& stream = streamsStubs[offset + layer]; - numStubs += - accumulate(stream.begin() + frame, stream.begin() + frame + size, 0, [](int sum, const FrameStub& frame) { - return sum + (frame.first.isNonnull() ? 1 : 0); - }); - } - vector stubs; - stubs.reserve(numStubs); - for (int layer = 0; layer < setup_->numLayers(); layer++) { - for (int f = frame; f < frame + size; f++) { - const FrameStub& stub = streamsStubs[offset + layer][f]; - if (stub.first.isNonnull()) - stubs.push_back(stub.first); - } - } - tracks.push_back(stubs); - } - } - - // - void AnalyzerKFin::associate(const vector>& tracks, - const StubAssociation* ass, - set& tps, - int& sum) const { - for (const vector& ttStubRefs : tracks) { - const vector& tpPtrs = ass->associate(ttStubRefs); - if (tpPtrs.empty()) - continue; - sum++; - copy(tpPtrs.begin(), tpPtrs.end(), inserter(tps, tps.begin())); - } - } - -} // namespace trackerTFP - -DEFINE_FWK_MODULE(trackerTFP::AnalyzerKFin); diff --git a/L1Trigger/TrackerTFP/test/AnalyzerMHT.cc b/L1Trigger/TrackerTFP/test/AnalyzerMHT.cc deleted file mode 100644 index 530e7f59bcc16..0000000000000 --- a/L1Trigger/TrackerTFP/test/AnalyzerMHT.cc +++ /dev/null @@ -1,292 +0,0 @@ -#include "FWCore/Framework/interface/one/EDAnalyzer.h" -#include "FWCore/Framework/interface/Run.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/ServiceRegistry/interface/Service.h" -#include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "FWCore/Utilities/interface/EDGetToken.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/Utilities/interface/Exception.h" -#include "CommonTools/UtilAlgos/interface/TFileService.h" -#include "DataFormats/Common/interface/Handle.h" - -#include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" -#include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace edm; -using namespace tt; - -namespace trackerTFP { - - /*! \class trackerTFP::AnalyzerMHT - * \brief Class to analyze hardware like structured TTStub Collection generated by Mini Hough Transform - * \author Thomas Schuh - * \date 2020, Apr - */ - class AnalyzerMHT : public one::EDAnalyzer { - public: - AnalyzerMHT(const ParameterSet& iConfig); - void beginJob() override {} - void beginRun(const Run& iEvent, const EventSetup& iSetup) override; - void analyze(const Event& iEvent, const EventSetup& iSetup) override; - void endRun(const Run& iEvent, const EventSetup& iSetup) override {} - void endJob() override; - - private: - // - void formTracks(const StreamStub& stream, vector>& tracks) const; - // - void associate(const vector>& tracks, const StubAssociation* ass, set& tps, int& sum) const; - - // ED input token of stubs - EDGetTokenT edGetTokenAccepted_; - // ED input token of lost stubs - EDGetTokenT edGetTokenLost_; - // ED input token of TTStubRef to TPPtr association for tracking efficiency - EDGetTokenT edGetTokenSelection_; - // ED input token of TTStubRef to recontructable TPPtr association - EDGetTokenT edGetTokenReconstructable_; - // Setup token - ESGetToken esGetTokenSetup_; - // DataFormats token - ESGetToken esGetTokenDataFormats_; - // stores, calculates and provides run-time constants - const Setup* setup_ = nullptr; - // helper class to extract structured data from tt::Frames - const DataFormats* dataFormats_ = nullptr; - // enables analyze of TPs - bool useMCTruth_; - // - int nEvents_ = 0; - - // Histograms - - TProfile* prof_; - TProfile* profChannel_; - TH1F* hisChannel_; - TH1F* hisEff_; - TH1F* hisEffTotal_; - TEfficiency* eff_; - - // printout - stringstream log_; - }; - - AnalyzerMHT::AnalyzerMHT(const ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { - usesResource("TFileService"); - // book in- and output ED products - const string& label = iConfig.getParameter("LabelMHT"); - const string& branchAccepted = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchLost = iConfig.getParameter("BranchLostStubs"); - edGetTokenAccepted_ = consumes(InputTag(label, branchAccepted)); - edGetTokenLost_ = consumes(InputTag(label, branchLost)); - if (useMCTruth_) { - const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); - const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); - edGetTokenSelection_ = consumes(inputTagSelecttion); - edGetTokenReconstructable_ = consumes(inputTagReconstructable); - } - // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); - // log config - log_.setf(ios::fixed, ios::floatfield); - log_.precision(4); - } - - void AnalyzerMHT::beginRun(const Run& iEvent, const EventSetup& iSetup) { - // helper class to store configurations - setup_ = &iSetup.getData(esGetTokenSetup_); - // helper class to extract structured data from tt::Frames - dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); - // book histograms - Service fs; - TFileDirectory dir; - dir = fs->mkdir("MHT"); - prof_ = dir.make("Counts", ";", 9, 0.5, 9.5); - prof_->GetXaxis()->SetBinLabel(1, "Stubs"); - prof_->GetXaxis()->SetBinLabel(2, "Tracks"); - prof_->GetXaxis()->SetBinLabel(3, "Lost Tracks"); - prof_->GetXaxis()->SetBinLabel(4, "Matched Tracks"); - prof_->GetXaxis()->SetBinLabel(5, "All Tracks"); - prof_->GetXaxis()->SetBinLabel(6, "Found TPs"); - prof_->GetXaxis()->SetBinLabel(7, "Found selected TPs"); - prof_->GetXaxis()->SetBinLabel(8, "Lost TPs"); - prof_->GetXaxis()->SetBinLabel(9, "All TPs"); - // channel occupancy - constexpr int maxOcc = 180; - const int numChannels = dataFormats_->numChannel(Process::mht); - hisChannel_ = dir.make("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5); - profChannel_ = dir.make("Prof Channel Occupancy", ";", numChannels, -.5, numChannels - .5); - // Efficiencies - hisEffTotal_ = dir.make("HisTPEtaTotal", ";", 128, -2.5, 2.5); - hisEff_ = dir.make("HisTPEta", ";", 128, -2.5, 2.5); - eff_ = dir.make("EffEta", ";", 128, -2.5, 2.5); - } - - void AnalyzerMHT::analyze(const Event& iEvent, const EventSetup& iSetup) { - auto fill = [](const TPPtr& tpPtr, TH1F* his) { his->Fill(tpPtr->eta()); }; - // read in ht products - Handle handleAccepted; - iEvent.getByToken(edGetTokenAccepted_, handleAccepted); - Handle handleLost; - iEvent.getByToken(edGetTokenLost_, handleLost); - // read in MCTruth - const StubAssociation* selection = nullptr; - const StubAssociation* reconstructable = nullptr; - if (useMCTruth_) { - Handle handleSelection; - iEvent.getByToken(edGetTokenSelection_, handleSelection); - selection = handleSelection.product(); - prof_->Fill(9, selection->numTPs()); - Handle handleReconstructable; - iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); - reconstructable = handleReconstructable.product(); - for (const auto& p : selection->getTrackingParticleToTTStubsMap()) - fill(p.first, hisEffTotal_); - } - // analyze ht products and associate found tracks with reconstrucable TrackingParticles - set tpPtrs; - set tpPtrsSelection; - set tpPtrsLost; - int allMatched(0); - int allTracks(0); - for (int region = 0; region < setup_->numRegions(); region++) { - int nStubs(0); - int nTracks(0); - int nLost(0); - for (int channel = 0; channel < dataFormats_->numChannel(Process::mht); channel++) { - const int index = region * dataFormats_->numChannel(Process::mht) + channel; - const StreamStub& accepted = handleAccepted->at(index); - hisChannel_->Fill(accepted.size()); - profChannel_->Fill(channel, accepted.size()); - nStubs += accumulate(accepted.begin(), accepted.end(), 0, [](int sum, const FrameStub& frame) { - return sum + (frame.first.isNonnull() ? 1 : 0); - }); - vector> tracks; - vector> lost; - formTracks(accepted, tracks); - formTracks(handleLost->at(index), lost); - nTracks += tracks.size(); - allTracks += tracks.size(); - nLost += lost.size(); - if (!useMCTruth_) - continue; - int tmp(0); - associate(tracks, selection, tpPtrsSelection, tmp); - associate(lost, selection, tpPtrsLost, tmp); - associate(tracks, reconstructable, tpPtrs, allMatched); - } - prof_->Fill(1, nStubs); - prof_->Fill(2, nTracks); - prof_->Fill(3, nLost); - } - for (const TPPtr& tpPtr : tpPtrsSelection) - fill(tpPtr, hisEff_); - vector recovered; - recovered.reserve(tpPtrsLost.size()); - set_intersection(tpPtrsLost.begin(), tpPtrsLost.end(), tpPtrs.begin(), tpPtrs.end(), back_inserter(recovered)); - for (const TPPtr& tpPtr : recovered) - tpPtrsLost.erase(tpPtr); - prof_->Fill(4, allMatched); - prof_->Fill(5, allTracks); - prof_->Fill(6, tpPtrs.size()); - prof_->Fill(7, tpPtrsSelection.size()); - prof_->Fill(8, tpPtrsLost.size()); - nEvents_++; - } - - void AnalyzerMHT::endJob() { - if (nEvents_ == 0) - return; - // effi - eff_->SetPassedHistogram(*hisEff_, "f"); - eff_->SetTotalHistogram(*hisEffTotal_, "f"); - // printout MHT summary - const double totalTPs = prof_->GetBinContent(9); - const double numStubs = prof_->GetBinContent(1); - const double numTracks = prof_->GetBinContent(2); - const double numTracksLost = prof_->GetBinContent(3); - const double totalTracks = prof_->GetBinContent(5); - const double numTracksMatched = prof_->GetBinContent(4); - const double numTPsAll = prof_->GetBinContent(6); - const double numTPsEff = prof_->GetBinContent(7); - const double numTPsLost = prof_->GetBinContent(8); - const double errStubs = prof_->GetBinError(1); - const double errTracks = prof_->GetBinError(2); - const double errTracksLost = prof_->GetBinError(3); - const double fracFake = (totalTracks - numTracksMatched) / totalTracks; - const double fracDup = (numTracksMatched - numTPsAll) / totalTracks; - const double eff = numTPsEff / totalTPs; - const double errEff = sqrt(eff * (1. - eff) / totalTPs / nEvents_); - const double effLoss = numTPsLost / totalTPs; - const double errEffLoss = sqrt(effLoss * (1. - effLoss) / totalTPs / nEvents_); - const vector nums = {numStubs, numTracks, numTracksLost}; - const vector errs = {errStubs, errTracks, errTracksLost}; - const int wNums = ceil(log10(*max_element(nums.begin(), nums.end()))) + 5; - const int wErrs = ceil(log10(*max_element(errs.begin(), errs.end()))) + 5; - log_ << " MHT SUMMARY " << endl; - log_ << "number of stubs per TFP = " << setw(wNums) << numStubs << " +- " << setw(wErrs) << errStubs << endl; - log_ << "number of tracks per TFP = " << setw(wNums) << numTracks << " +- " << setw(wErrs) << errTracks - << endl; - log_ << "number of lost tracks per TFP = " << setw(wNums) << numTracksLost << " +- " << setw(wErrs) << errTracksLost - << endl; - log_ << " max tracking efficiency = " << setw(wNums) << eff << " +- " << setw(wErrs) << errEff << endl; - log_ << " lost tracking efficiency = " << setw(wNums) << effLoss << " +- " << setw(wErrs) << errEffLoss << endl; - log_ << " fake rate = " << setw(wNums) << fracFake << endl; - log_ << " duplicate rate = " << setw(wNums) << fracDup << endl; - log_ << "============================================================="; - LogPrint("L1Trigger/TrackerTFP") << log_.str(); - } - - // - void AnalyzerMHT::formTracks(const StreamStub& stream, vector>& tracks) const { - vector stubs; - stubs.reserve(stream.size()); - for (const FrameStub& frame : stream) - if (frame.first.isNonnull()) - stubs.emplace_back(frame, dataFormats_); - for (auto it = stubs.begin(); it != stubs.end();) { - const auto start = it; - const int id = it->trackId(); - auto different = [id](const StubMHT& stub) { return id != stub.trackId(); }; - it = find_if(it, stubs.end(), different); - vector ttStubRefs; - ttStubRefs.reserve(distance(start, it)); - transform(start, it, back_inserter(ttStubRefs), [](const StubMHT& stub) { return stub.ttStubRef(); }); - tracks.push_back(ttStubRefs); - } - } - - // - void AnalyzerMHT::associate(const vector>& tracks, - const StubAssociation* ass, - set& tps, - int& sum) const { - for (const vector& ttStubRefs : tracks) { - const vector& tpPtrs = ass->associate(ttStubRefs); - if (tpPtrs.empty()) - continue; - sum++; - copy(tpPtrs.begin(), tpPtrs.end(), inserter(tps, tps.begin())); - } - } - -} // namespace trackerTFP - -DEFINE_FWK_MODULE(trackerTFP::AnalyzerMHT); diff --git a/L1Trigger/TrackerTFP/test/AnalyzerTFP.cc b/L1Trigger/TrackerTFP/test/AnalyzerTFP.cc new file mode 100644 index 0000000000000..15c0a463b7b28 --- /dev/null +++ b/L1Trigger/TrackerTFP/test/AnalyzerTFP.cc @@ -0,0 +1,264 @@ +#include "FWCore/Framework/interface/one/EDAnalyzer.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "CommonTools/UtilAlgos/interface/TFileService.h" +#include "DataFormats/Common/interface/Handle.h" + +#include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" +#include "L1Trigger/TrackTrigger/interface/Setup.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace trackerTFP { + + /*! \class trackerTFP::AnalyzerTFP + * \brief Class to analyze TTTracks found by tfp + * \author Thomas Schuh + * \date 20204 Aug + */ + class AnalyzerTFP : public edm::one::EDAnalyzer { + public: + AnalyzerTFP(const edm::ParameterSet& iConfig); + void beginJob() override {} + void beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override; + void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override; + void endRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override {} + void endJob() override; + + private: + // gets all TPs associated too any of the tracks & number of tracks matching at least one TP + void associate(const std::vector>& tracks, + const tt::StubAssociation* ass, + std::set& tps, + int& nMatchTrk, + bool perfect = false) const; + + // ED input token of tracks + edm::EDGetTokenT edGetToken_; + // ED input token of TTStubRef to TPPtr association for tracking efficiency + edm::EDGetTokenT edGetTokenSelection_; + // ED input token of TTStubRef to recontructable TPPtr association + edm::EDGetTokenT edGetTokenReconstructable_; + // Setup token + edm::ESGetToken esGetTokenSetup_; + // stores, calculates and provides run-time constants + const tt::Setup* setup_ = nullptr; + // enables analyze of TPs + bool useMCTruth_; + // + int nEvents_ = 0; + + // Histograms + + // counts per TFP (processing nonant and event) + TProfile* prof_; + // no. of tracks per nonant + TProfile* profChannel_; + TH1F* hisChannel_; + TH1F* hisEff_; + TH1F* hisEffTotal_; + TEfficiency* eff_; + + // printout + std::stringstream log_; + }; + + AnalyzerTFP::AnalyzerTFP(const edm::ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { + usesResource("TFileService"); + // book in- and output ED products + const std::string& label = iConfig.getParameter("OutputLabelTFP"); + const std::string& branch = iConfig.getParameter("BranchTTTracks"); + edGetToken_ = consumes(edm::InputTag(label, branch)); + if (useMCTruth_) { + const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); + const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); + edGetTokenSelection_ = consumes(inputTagSelecttion); + edGetTokenReconstructable_ = consumes(inputTagReconstructable); + } + // book ES products + esGetTokenSetup_ = esConsumes(); + // log config + log_.setf(std::ios::fixed, std::ios::floatfield); + log_.precision(4); + } + + void AnalyzerTFP::beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) { + // helper class to store configurations + setup_ = &iSetup.getData(esGetTokenSetup_); + // book histograms + edm::Service fs; + TFileDirectory dir; + dir = fs->mkdir("TFP"); + prof_ = dir.make("Counts", ";", 10, 0.5, 10.5); + prof_->GetXaxis()->SetBinLabel(1, "Stubs"); + prof_->GetXaxis()->SetBinLabel(2, "Tracks"); + prof_->GetXaxis()->SetBinLabel(3, "Lost Tracks"); + prof_->GetXaxis()->SetBinLabel(4, "Matched Tracks"); + prof_->GetXaxis()->SetBinLabel(5, "All Tracks"); + prof_->GetXaxis()->SetBinLabel(6, "Found TPs"); + prof_->GetXaxis()->SetBinLabel(7, "Found selected TPs"); + prof_->GetXaxis()->SetBinLabel(8, "Lost TPs"); + prof_->GetXaxis()->SetBinLabel(9, "All TPs"); + prof_->GetXaxis()->SetBinLabel(10, "Perfectly Found selected TPs"); + // channel occupancy + constexpr int maxOcc = 180; + const int numChannels = setup_->numRegions(); + hisChannel_ = dir.make("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5); + profChannel_ = dir.make("Prof Channel Occupancy", ";", numChannels, -.5, numChannels - .5); + // Efficiencies + hisEffTotal_ = dir.make("HisTPEtaTotal", ";", 128, -2.5, 2.5); + hisEff_ = dir.make("HisTPEta", ";", 128, -2.5, 2.5); + eff_ = dir.make("EffEta", ";", 128, -2.5, 2.5); + } + + void AnalyzerTFP::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + auto fill = [](const TPPtr& tpPtr, TH1F* his) { his->Fill(tpPtr->eta()); }; + // read in tracklet products + edm::Handle handle; + iEvent.getByToken(edGetToken_, handle); + // read in MCTruth + const tt::StubAssociation* selection = nullptr; + const tt::StubAssociation* reconstructable = nullptr; + if (useMCTruth_) { + edm::Handle handleSelection; + iEvent.getByToken(edGetTokenSelection_, handleSelection); + selection = handleSelection.product(); + prof_->Fill(9, selection->numTPs()); + edm::Handle handleReconstructable; + iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); + reconstructable = handleReconstructable.product(); + for (const auto& p : selection->getTrackingParticleToTTStubsMap()) + fill(p.first, hisEffTotal_); + } + // + const tt::TTTracks& ttTracks = *handle.product(); + std::vector> ttTrackRefsRegions(setup_->numRegions()); + std::vector nTTTracksRegions(setup_->numRegions(), 0); + for (const TTTrack& ttTrack : ttTracks) + nTTTracksRegions[ttTrack.phiSector()]++; + for (int region = 0; region < setup_->numRegions(); region++) + ttTrackRefsRegions[region].reserve(nTTTracksRegions[region]); + int i(0); + for (const TTTrack& ttTrack : ttTracks) + ttTrackRefsRegions[ttTrack.phiSector()].emplace_back(TTTrackRef(handle, i++)); + for (int region = 0; region < setup_->numRegions(); region++) { + const std::vector& ttTrackRefs = ttTrackRefsRegions[region]; + const int nStubs = + std::accumulate(ttTrackRefs.begin(), ttTrackRefs.end(), 0, [](int sum, const TTTrackRef& ttTrackRef) { + return sum + ttTrackRef->getStubRefs().size(); + }); + const int nTracks = ttTrackRefs.size(); + prof_->Fill(1, nStubs); + prof_->Fill(2, nTracks); + // no access to lost tracks + prof_->Fill(3, 0); + hisChannel_->Fill(nTracks); + profChannel_->Fill(region, nTracks); + } + // analyze tracklet products and associate found tracks with reconstrucable TrackingParticles + std::set tpPtrs; + std::set tpPtrsSelection; + std::set tpPtrsPerfect; + int nAllMatched(0); + // convert vector of tracks to vector of vector of associated stubs + std::vector> tracks; + tracks.reserve(ttTracks.size()); + std::transform(ttTracks.begin(), + ttTracks.end(), + std::back_inserter(tracks), + [](const TTTrack& ttTrack) { return ttTrack.getStubRefs(); }); + if (useMCTruth_) { + int tmp(0); + associate(tracks, selection, tpPtrsSelection, tmp); + associate(tracks, selection, tpPtrsPerfect, tmp, true); + associate(tracks, reconstructable, tpPtrs, nAllMatched); + } + for (const TPPtr& tpPtr : tpPtrsSelection) + fill(tpPtr, hisEff_); + prof_->Fill(4, nAllMatched); + prof_->Fill(5, ttTracks.size()); + prof_->Fill(6, tpPtrs.size()); + prof_->Fill(7, tpPtrsSelection.size()); + // no access to lost tp + prof_->Fill(8, 0); + prof_->Fill(10, tpPtrsPerfect.size()); + nEvents_++; + } + + void AnalyzerTFP::endJob() { + if (nEvents_ == 0) + return; + // effi + eff_->SetPassedHistogram(*hisEff_, "f"); + eff_->SetTotalHistogram(*hisEffTotal_, "f"); + // printout SF summary + const double totalTPs = prof_->GetBinContent(9); + const double numStubs = prof_->GetBinContent(1); + const double numTracks = prof_->GetBinContent(2); + const double totalTracks = prof_->GetBinContent(5); + const double numTracksMatched = prof_->GetBinContent(4); + const double numTPsAll = prof_->GetBinContent(6); + const double numTPsEff = prof_->GetBinContent(7); + const double numTPsEffPerfect = prof_->GetBinContent(10); + const double errStubs = prof_->GetBinError(1); + const double errTracks = prof_->GetBinError(2); + const double fracFake = (totalTracks - numTracksMatched) / totalTracks; + const double fracDup = (numTracksMatched - numTPsAll) / totalTracks; + const double eff = numTPsEff / totalTPs; + const double errEff = sqrt(eff * (1. - eff) / totalTPs / nEvents_); + const double effPerfect = numTPsEffPerfect / totalTPs; + const double errEffPerfect = sqrt(effPerfect * (1. - effPerfect) / totalTPs / nEvents_); + const std::vector nums = {numStubs, numTracks}; + const std::vector errs = {errStubs, errTracks}; + const int wNums = std::ceil(std::log10(*std::max_element(nums.begin(), nums.end()))) + 5; + const int wErrs = std::ceil(std::log10(*std::max_element(errs.begin(), errs.end()))) + 5; + log_ << " TFP SUMMARY " << std::endl; + log_ << "number of stubs per TFP = " << std::setw(wNums) << numStubs << " +- " << std::setw(wErrs) << errStubs + << std::endl; + log_ << "number of tracks per TFP = " << std::setw(wNums) << numTracks << " +- " << std::setw(wErrs) << errTracks + << std::endl; + log_ << "current tracking efficiency = " << std::setw(wNums) << effPerfect << " +- " << std::setw(wErrs) + << errEffPerfect << std::endl; + log_ << "max tracking efficiency = " << std::setw(wNums) << eff << " +- " << std::setw(wErrs) << errEff + << std::endl; + log_ << " fake rate = " << std::setw(wNums) << fracFake << std::endl; + log_ << " duplicate rate = " << std::setw(wNums) << fracDup << std::endl; + log_ << "============================================================="; + edm::LogPrint(moduleDescription().moduleName()) << log_.str(); + } + + // gets all TPs associated too any of the tracks & number of tracks matching at least one TP + void AnalyzerTFP::associate(const std::vector>& tracks, + const tt::StubAssociation* ass, + std::set& tps, + int& nMatchTrk, + bool perfect) const { + for (const std::vector& ttStubRefs : tracks) { + const std::vector& tpPtrs = perfect ? ass->associateFinal(ttStubRefs) : ass->associate(ttStubRefs); + if (tpPtrs.empty()) + continue; + nMatchTrk++; + std::copy(tpPtrs.begin(), tpPtrs.end(), std::inserter(tps, tps.begin())); + } + } + +} // namespace trackerTFP + +DEFINE_FWK_MODULE(trackerTFP::AnalyzerTFP); diff --git a/L1Trigger/TrackerTFP/test/AnalyzerTQ.cc b/L1Trigger/TrackerTFP/test/AnalyzerTQ.cc new file mode 100644 index 0000000000000..bc358b105bca6 --- /dev/null +++ b/L1Trigger/TrackerTFP/test/AnalyzerTQ.cc @@ -0,0 +1,280 @@ +#include "FWCore/Framework/interface/one/EDAnalyzer.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "CommonTools/UtilAlgos/interface/TFileService.h" +#include "DataFormats/Common/interface/Handle.h" + +#include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" +#include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackerTFP/interface/DataFormats.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace trackerTFP { + + /*! \class trackerTFP::AnalyzerTQ + * \brief Class to analyze hardware like structured track Collection generated by Duplicate Removal + * \author Thomas Schuh + * \date 2023, Feb + */ + class AnalyzerTQ : public edm::one::EDAnalyzer { + public: + AnalyzerTQ(const edm::ParameterSet& iConfig); + void beginJob() override {} + void beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override; + void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override; + void endRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override {} + void endJob() override; + + private: + // + void formTracks(const tt::StreamsTrack& streamsTrack, + const tt::StreamsStub& streamsStubs, + std::vector>& tracks, + int channel) const; + // + void associate(const std::vector>& tracks, + const tt::StubAssociation* ass, + std::set& tps, + int& sum, + bool perfect = true) const; + // ED input token of stubs + edm::EDGetTokenT edGetTokenStubs_; + // ED input token of tracks + edm::EDGetTokenT edGetTokenTracks_; + // ED input token of TTStubRef to TPPtr association for tracking efficiency + edm::EDGetTokenT edGetTokenSelection_; + // ED input token of TTStubRef to recontructable TPPtr association + edm::EDGetTokenT edGetTokenReconstructable_; + // Setup token + edm::ESGetToken esGetTokenSetup_; + // DataFormats token + edm::ESGetToken esGetTokenDataFormats_; + // stores, calculates and provides run-time constants + const tt::Setup* setup_ = nullptr; + // helper class to extract structured data from tt::Frames + const DataFormats* dataFormats_ = nullptr; + // enables analyze of TPs + bool useMCTruth_; + // + int nEvents_ = 0; + + // Histograms + + TProfile* prof_; + TProfile* profChannel_; + TProfile* profTracks_; + TH1F* hisChannel_; + TH1F* hisTracks_; + + // printout + std::stringstream log_; + }; + + AnalyzerTQ::AnalyzerTQ(const edm::ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { + usesResource("TFileService"); + // book in- and output ED products + const std::string& label = iConfig.getParameter("OutputLabelTQ"); + const std::string& branchStubs = iConfig.getParameter("BranchStubs"); + const std::string& branchTracks = iConfig.getParameter("BranchTracks"); + edGetTokenStubs_ = consumes(edm::InputTag(label, branchStubs)); + edGetTokenTracks_ = consumes(edm::InputTag(label, branchTracks)); + if (useMCTruth_) { + const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); + const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); + edGetTokenSelection_ = consumes(inputTagSelecttion); + edGetTokenReconstructable_ = consumes(inputTagReconstructable); + } + // book ES products + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + // log config + log_.setf(std::ios::fixed, std::ios::floatfield); + log_.precision(4); + } + + void AnalyzerTQ::beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) { + // helper class to store configurations + setup_ = &iSetup.getData(esGetTokenSetup_); + // helper class to extract structured data from tt::Frames + dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); + // book histograms + edm::Service fs; + TFileDirectory dir; + dir = fs->mkdir("TQ"); + prof_ = dir.make("Counts", ";", 12, 0.5, 12.5); + prof_->GetXaxis()->SetBinLabel(1, "Stubs"); + prof_->GetXaxis()->SetBinLabel(2, "Tracks"); + prof_->GetXaxis()->SetBinLabel(4, "Matched Tracks"); + prof_->GetXaxis()->SetBinLabel(5, "All Tracks"); + prof_->GetXaxis()->SetBinLabel(6, "Found TPs"); + prof_->GetXaxis()->SetBinLabel(7, "Found selected TPs"); + prof_->GetXaxis()->SetBinLabel(9, "All TPs"); + prof_->GetXaxis()->SetBinLabel(10, "states"); + prof_->GetXaxis()->SetBinLabel(12, "max tp"); + // channel occupancy + constexpr int maxOcc = 180; + const int numChannels = dataFormats_->numChannel(Process::dr); + hisChannel_ = dir.make("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5); + profChannel_ = dir.make("Prof Channel Occupancy", ";", numChannels, -.5, numChannels - .5); + // track occupancy + hisTracks_ = dir.make("His Track Occupancy", ";", maxOcc, -.5, maxOcc - .5); + profTracks_ = dir.make("Prof Track Occupancy", ";", numChannels, -.5, numChannels - .5); + } + + void AnalyzerTQ::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + // read in ht products + edm::Handle handleStubs; + iEvent.getByToken(edGetTokenStubs_, handleStubs); + const tt::StreamsStub& acceptedStubs = *handleStubs; + edm::Handle handleTracks; + iEvent.getByToken(edGetTokenTracks_, handleTracks); + const tt::StreamsTrack& acceptedTracks = *handleTracks; + // read in MCTruth + const tt::StubAssociation* selection = nullptr; + const tt::StubAssociation* reconstructable = nullptr; + if (useMCTruth_) { + edm::Handle handleSelection; + iEvent.getByToken(edGetTokenSelection_, handleSelection); + selection = handleSelection.product(); + prof_->Fill(9, selection->numTPs()); + edm::Handle handleReconstructable; + iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); + reconstructable = handleReconstructable.product(); + } + // analyze ht products and associate found tracks with reconstrucable TrackingParticles + std::set tpPtrs; + std::set tpPtrsSelection; + std::set tpPtrsMax; + int allMatched(0); + int allTracks(0); + for (int region = 0; region < setup_->numRegions(); region++) { + std::vector> tracks; + formTracks(acceptedTracks, acceptedStubs, tracks, region); + hisTracks_->Fill(tracks.size()); + profTracks_->Fill(region, tracks.size()); + const int nTracks = tracks.size(); + const int nStubs = + std::accumulate(tracks.begin(), tracks.end(), 0, [](int sum, const std::vector& track) { + return sum + static_cast(track.size()); + }); + allTracks += tracks.size(); + if (!useMCTruth_) + continue; + int tmp(0); + associate(tracks, selection, tpPtrsSelection, tmp); + associate(tracks, reconstructable, tpPtrs, allMatched, false); + associate(tracks, selection, tpPtrsMax, tmp, false); + const int size = acceptedTracks[region].size(); + hisChannel_->Fill(size); + profChannel_->Fill(region, size); + prof_->Fill(1, nStubs); + prof_->Fill(2, nTracks); + } + prof_->Fill(4, allMatched); + prof_->Fill(5, allTracks); + prof_->Fill(6, tpPtrs.size()); + prof_->Fill(7, tpPtrsSelection.size()); + prof_->Fill(12, tpPtrsMax.size()); + nEvents_++; + } + + void AnalyzerTQ::endJob() { + if (nEvents_ == 0) + return; + // printout DR summary + const double totalTPs = prof_->GetBinContent(9); + const double numStubs = prof_->GetBinContent(1); + const double numTracks = prof_->GetBinContent(2); + const double totalTracks = prof_->GetBinContent(5); + const double numTracksMatched = prof_->GetBinContent(4); + const double numTPsAll = prof_->GetBinContent(6); + const double numTPsEff = prof_->GetBinContent(7); + const double numTPsEffMax = prof_->GetBinContent(12); + const double errStubs = prof_->GetBinError(1); + const double errTracks = prof_->GetBinError(2); + const double fracFake = (totalTracks - numTracksMatched) / totalTracks; + const double fracDup = (numTracksMatched - numTPsAll) / totalTracks; + const double eff = numTPsEff / totalTPs; + const double errEff = std::sqrt(eff * (1. - eff) / totalTPs / nEvents_); + const double effMax = numTPsEffMax / totalTPs; + const double errEffMax = std::sqrt(effMax * (1. - effMax) / totalTPs / nEvents_); + const std::vector nums = {numStubs, numTracks}; + const std::vector errs = {errStubs, errTracks}; + const int wNums = std::ceil(std::log10(*std::max_element(nums.begin(), nums.end()))) + 5; + const int wErrs = std::ceil(std::log10(*std::max_element(errs.begin(), errs.end()))) + 5; + log_ << " TQ SUMMARY " << std::endl; + log_ << "number of stubs per TFP = " << std::setw(wNums) << numStubs << " +- " << std::setw(wErrs) << errStubs + << std::endl; + log_ << "number of tracks per TFP = " << std::setw(wNums) << numTracks << " +- " << std::setw(wErrs) + << errTracks << std::endl; + log_ << " tracking efficiency = " << std::setw(wNums) << eff << " +- " << std::setw(wErrs) << errEff + << std::endl; + log_ << " max tracking efficiency = " << std::setw(wNums) << effMax << " +- " << std::setw(wErrs) << errEffMax + << std::endl; + log_ << " fake rate = " << std::setw(wNums) << fracFake << std::endl; + log_ << " duplicate rate = " << std::setw(wNums) << fracDup << std::endl; + log_ << "============================================================="; + edm::LogPrint(moduleDescription().moduleName()) << log_.str(); + } + + // + void AnalyzerTQ::formTracks(const tt::StreamsTrack& streamsTrack, + const tt::StreamsStub& streamsStubs, + std::vector>& tracks, + int region) const { + const int offset = region * setup_->numLayers(); + const tt::StreamTrack& streamTrack = streamsTrack[region]; + const int numTracks = + std::accumulate(streamTrack.begin(), streamTrack.end(), 0, [](int sum, const tt::FrameTrack& frame) { + return sum + (frame.first.isNonnull() ? 1 : 0); + }); + tracks.reserve(numTracks); + for (int frame = 0; frame < static_cast(streamTrack.size()); frame++) { + const tt::FrameTrack& frameTrack = streamTrack[frame]; + if (frameTrack.first.isNull()) + continue; + std::deque stubs; + for (int layer = 0; layer < setup_->numLayers(); layer++) { + const tt::FrameStub& stub = streamsStubs[offset + layer][frame]; + if (stub.first.isNonnull()) + stubs.push_back(stub.first); + } + tracks.emplace_back(stubs.begin(), stubs.end()); + } + } + + // + void AnalyzerTQ::associate(const std::vector>& tracks, + const tt::StubAssociation* ass, + std::set& tps, + int& sum, + bool perfect) const { + for (const std::vector& ttStubRefs : tracks) { + const std::vector& tpPtrs = perfect ? ass->associateFinal(ttStubRefs) : ass->associate(ttStubRefs); + if (tpPtrs.empty()) + continue; + sum++; + std::copy(tpPtrs.begin(), tpPtrs.end(), std::inserter(tps, tps.begin())); + } + } + +} // namespace trackerTFP + +DEFINE_FWK_MODULE(trackerTFP::AnalyzerTQ); diff --git a/L1Trigger/TrackerTFP/test/AnalyzerTT.cc b/L1Trigger/TrackerTFP/test/AnalyzerTT.cc deleted file mode 100644 index 7104041824574..0000000000000 --- a/L1Trigger/TrackerTFP/test/AnalyzerTT.cc +++ /dev/null @@ -1,131 +0,0 @@ -#include "FWCore/Framework/interface/one/EDAnalyzer.h" -#include "FWCore/Framework/interface/Run.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/Utilities/interface/EDGetToken.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/Utilities/interface/Exception.h" -#include "DataFormats/Common/interface/Handle.h" - -#include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" -#include "L1Trigger/TrackTrigger/interface/Setup.h" - -using namespace std; -using namespace edm; -using namespace tt; - -namespace trackerTFP { - - /*! \class trackerTFP::AnalyzerTT - * \brief Class to analyze TTTracks - * \author Thomas Schuh - * \date 2020, Oct - */ - class AnalyzerTT : public one::EDAnalyzer { - public: - AnalyzerTT(const ParameterSet& iConfig); - void beginJob() override {} - void beginRun(const Run& iEvent, const EventSetup& iSetup) override; - void analyze(const Event& iEvent, const EventSetup& iSetup) override; - void endRun(const Run& iEvent, const EventSetup& iSetup) override {} - void endJob() override {} - - private: - // ED input token of tt::TTTrackRefMap - EDGetTokenT edGetTokenTTTrackMap_; - // ED input token of TTStubRef to TPPtr association for tracking efficiency - EDGetTokenT edGetTokenStubAssociation_; - // Setup token - ESGetToken esGetTokenSetup_; - // stores, calculates and provides run-time constants - const Setup* setup_ = nullptr; - }; - - AnalyzerTT::AnalyzerTT(const ParameterSet& iConfig) { - // book in- and output ED products - const auto& label = iConfig.getParameter("LabelAS"); - const auto& branch = iConfig.getParameter("BranchAcceptedTracks"); - const auto& inputTag = iConfig.getParameter("InputTagSelection"); - edGetTokenTTTrackMap_ = consumes(InputTag(label, branch)); - edGetTokenStubAssociation_ = consumes(inputTag); - // book ES products - esGetTokenSetup_ = esConsumes(); - } - - void AnalyzerTT::beginRun(const Run& iEvent, const EventSetup& iSetup) { - // helper class to store configurations - setup_ = &iSetup.getData(esGetTokenSetup_); - } - - void AnalyzerTT::analyze(const Event& iEvent, const EventSetup& iSetup) { - Handle handleTTTrackMap; - iEvent.getByToken(edGetTokenTTTrackMap_, handleTTTrackMap); - Handle handleStubAssociation; - iEvent.getByToken(edGetTokenStubAssociation_, handleStubAssociation); - if (false) - return; - for (const auto& p : *handleTTTrackMap) { - const TTTrackRef& found = p.second; - const TTTrackRef& fitted = p.first; - const vector& ttStubRefsFound = found->getStubRefs(); - const vector& tpPtrsFound = handleStubAssociation->associate(ttStubRefsFound); - if (tpPtrsFound.empty()) - continue; - const vector& ttStubRefsFitted = fitted->getStubRefs(); - const vector& tpPtrsFitted = handleStubAssociation->associate(ttStubRefsFitted); - if (!tpPtrsFitted.empty()) - continue; - const TPPtr& tpPtr = tpPtrsFound.front(); - const double off = (found->phiSector() - .5) * 2. * M_PI / setup_->numRegions() / setup_->numSectorsPhi(); - cout << setprecision(8); - cout << found->phiSector() << " " << found->etaSector() << " " << endl; - cout << "Found" << endl; - for (const TTStubRef& ttStubRef : ttStubRefsFound) { - const GlobalPoint& gp = setup_->stubPos(ttStubRef); - cout << gp.perp() << " " << gp.phi() << " " << gp.z() << " " << setup_->layerId(ttStubRef) << endl; - } - cout << "Fitted" << endl; - for (const TTStubRef& ttStubRef : ttStubRefsFitted) { - const GlobalPoint& gp = setup_->stubPos(ttStubRef); - cout << gp.perp() << " " << gp.phi() << " " << gp.z() << " " << setup_->layerId(ttStubRef) << endl; - } - cout << "TP" << endl; - for (const TTStubRef& ttStubRef : handleStubAssociation->findTTStubRefs(tpPtr)) { - const GlobalPoint& gp = setup_->stubPos(ttStubRef); - cout << gp.perp() << " " << gp.phi() << " " << gp.z() << " " << setup_->layerId(ttStubRef) << endl; - } - cout << found->hitPattern() << " " << found->trackSeedType() << endl; - cout << "m0SF = " - << " " << -found->rInv() << endl; - cout << "c0SF = " - << " " << deltaPhi(found->phi() + found->rInv() * setup_->chosenRofPhi() + off) << endl; - cout << "m1SF = " - << " " << found->tanL() + setup_->sectorCot(found->etaSector()) << endl; - cout << "c1SF = " - << " " << found->z0() - found->tanL() * setup_->chosenRofZ() << endl; - cout << "m0KF = " - << " " << -fitted->rInv() * setup_->invPtToDphi() << endl; - cout << "c0KF = " - << " " << fitted->phi() << endl; - cout << "m1KF = " - << " " << fitted->tanL() << endl; - cout << "c1KF = " - << " " << fitted->z0() << endl; - cout << "m0TP = " - << " " << -tpPtr->charge() / tpPtr->pt() * setup_->invPtToDphi() << endl; - cout << "c0TP = " - << " " << tpPtr->phi() << endl; - cout << "m1TP = " - << " " << sinh(tpPtr->eta()) << endl; - const math::XYZPointD& v = tpPtr->vertex(); - cout << "c1TP = " - << " " << v.z() - sinh(tpPtr->eta()) * (v.x() * cos(tpPtr->phi()) + v.y() * sin(tpPtr->phi())) << endl; - throw cms::Exception("..."); - } - } - -} // namespace trackerTFP - -DEFINE_FWK_MODULE(trackerTFP::AnalyzerTT); diff --git a/L1Trigger/TrackerTFP/test/AnalyzerZHT.cc b/L1Trigger/TrackerTFP/test/AnalyzerZHT.cc deleted file mode 100644 index 6dc5c5a556a29..0000000000000 --- a/L1Trigger/TrackerTFP/test/AnalyzerZHT.cc +++ /dev/null @@ -1,294 +0,0 @@ -#include "FWCore/Framework/interface/one/EDAnalyzer.h" -#include "FWCore/Framework/interface/Run.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/ServiceRegistry/interface/Service.h" -#include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "FWCore/Utilities/interface/EDGetToken.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/Utilities/interface/Exception.h" -#include "CommonTools/UtilAlgos/interface/TFileService.h" -#include "DataFormats/Common/interface/Handle.h" - -#include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" -#include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace edm; -using namespace tt; - -namespace trackerTFP { - - /*! \class trackerTFP::AnalyzerZHT - * \brief Class to analyze hardware like structured TTStub Collection generated by Z Hough Transform - * \author Thomas Schuh - * \date 2021, May - */ - class AnalyzerZHT : public one::EDAnalyzer { - public: - AnalyzerZHT(const ParameterSet& iConfig); - void beginJob() override {} - void beginRun(const Run& iEvent, const EventSetup& iSetup) override; - void analyze(const Event& iEvent, const EventSetup& iSetup) override; - void endRun(const Run& iEvent, const EventSetup& iSetup) override {} - void endJob() override; - - private: - // - void formTracks(const StreamStub& stream, vector>& tracks) const; - // - void associate(const vector>& tracks, const StubAssociation* ass, set& tps, int& sum) const; - - // ED input token of stubs - EDGetTokenT edGetTokenAccepted_; - // ED input token of lost stubs - EDGetTokenT edGetTokenLost_; - // ED input token of TTStubRef to TPPtr association for tracking efficiency - EDGetTokenT edGetTokenSelection_; - // ED input token of TTStubRef to recontructable TPPtr association - EDGetTokenT edGetTokenReconstructable_; - // Setup token - ESGetToken esGetTokenSetup_; - // DataFormats token - ESGetToken esGetTokenDataFormats_; - // stores, calculates and provides run-time constants - const Setup* setup_ = nullptr; - // helper class to extract structured data from tt::Frames - const DataFormats* dataFormats_ = nullptr; - // enables analyze of TPs - bool useMCTruth_; - // - int nEvents_ = 0; - - // Histograms - - TProfile* prof_; - TProfile* profChannel_; - TH1F* hisChannel_; - TH1F* hisEff_; - TH1F* hisEffTotal_; - TEfficiency* eff_; - - // printout - stringstream log_; - }; - - AnalyzerZHT::AnalyzerZHT(const ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { - usesResource("TFileService"); - // book in- and output ED products - const string& label = iConfig.getParameter("LabelZHT"); - const string& branchAccepted = iConfig.getParameter("BranchAcceptedStubs"); - const string& branchLost = iConfig.getParameter("BranchLostStubs"); - edGetTokenAccepted_ = consumes(InputTag(label, branchAccepted)); - edGetTokenLost_ = consumes(InputTag(label, branchLost)); - if (useMCTruth_) { - const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); - const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); - edGetTokenSelection_ = consumes(inputTagSelecttion); - edGetTokenReconstructable_ = consumes(inputTagReconstructable); - } - // book ES products - esGetTokenSetup_ = esConsumes(); - esGetTokenDataFormats_ = esConsumes(); - // log config - log_.setf(ios::fixed, ios::floatfield); - log_.precision(4); - } - - void AnalyzerZHT::beginRun(const Run& iEvent, const EventSetup& iSetup) { - // helper class to store configurations - setup_ = &iSetup.getData(esGetTokenSetup_); - // helper class to extract structured data from tt::Frames - dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); - // book histograms - Service fs; - TFileDirectory dir; - dir = fs->mkdir("ZHT"); - prof_ = dir.make("Counts", ";", 9, 0.5, 9.5); - prof_->GetXaxis()->SetBinLabel(1, "Stubs"); - prof_->GetXaxis()->SetBinLabel(2, "Tracks"); - prof_->GetXaxis()->SetBinLabel(3, "Lost Tracks"); - prof_->GetXaxis()->SetBinLabel(4, "Matched Tracks"); - prof_->GetXaxis()->SetBinLabel(5, "All Tracks"); - prof_->GetXaxis()->SetBinLabel(6, "Found TPs"); - prof_->GetXaxis()->SetBinLabel(7, "Found selected TPs"); - prof_->GetXaxis()->SetBinLabel(8, "Lost TPs"); - prof_->GetXaxis()->SetBinLabel(9, "All TPs"); - // channel occupancy - constexpr int maxOcc = 180; - const int numChannels = dataFormats_->numChannel(Process::zht); - hisChannel_ = dir.make("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5); - profChannel_ = dir.make("Prof Channel Occupancy", ";", numChannels, -.5, numChannels - .5); - // Efficiencies - hisEffTotal_ = dir.make("HisTPEtaTotal", ";", 128, -2.5, 2.5); - hisEff_ = dir.make("HisTPEta", ";", 128, -2.5, 2.5); - eff_ = dir.make("EffEta", ";", 128, -2.5, 2.5); - } - - void AnalyzerZHT::analyze(const Event& iEvent, const EventSetup& iSetup) { - auto fill = [](const TPPtr& tpPtr, TH1F* his) { his->Fill(tpPtr->eta()); }; - // read in ht products - Handle handleAccepted; - iEvent.getByToken(edGetTokenAccepted_, handleAccepted); - Handle handleLost; - iEvent.getByToken(edGetTokenLost_, handleLost); - // read in MCTruth - const StubAssociation* selection = nullptr; - const StubAssociation* reconstructable = nullptr; - if (useMCTruth_) { - Handle handleSelection; - iEvent.getByToken(edGetTokenSelection_, handleSelection); - selection = handleSelection.product(); - prof_->Fill(9, selection->numTPs()); - Handle handleReconstructable; - iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); - reconstructable = handleReconstructable.product(); - for (const auto& p : selection->getTrackingParticleToTTStubsMap()) - fill(p.first, hisEffTotal_); - } - // analyze ht products and associate found tracks with reconstrucable TrackingParticles - set tpPtrs; - set tpPtrsSelection; - set tpPtrsLost; - int allMatched(0); - int allTracks(0); - for (int region = 0; region < setup_->numRegions(); region++) { - int nStubs(0); - int nTracks(0); - int nLost(0); - for (int channel = 0; channel < dataFormats_->numChannel(Process::mht); channel++) { - const int index = region * dataFormats_->numChannel(Process::mht) + channel; - const StreamStub& accepted = handleAccepted->at(index); - hisChannel_->Fill(accepted.size()); - profChannel_->Fill(channel, accepted.size()); - nStubs += accumulate(accepted.begin(), accepted.end(), 0, [](int sum, const FrameStub& frame) { - return sum + (frame.first.isNonnull() ? 1 : 0); - }); - vector> tracks; - vector> lost; - formTracks(accepted, tracks); - formTracks(handleLost->at(index), lost); - nTracks += tracks.size(); - allTracks += tracks.size(); - nLost += lost.size(); - if (!useMCTruth_) - continue; - int tmp(0); - associate(tracks, selection, tpPtrsSelection, tmp); - associate(lost, selection, tpPtrsLost, tmp); - associate(tracks, reconstructable, tpPtrs, allMatched); - } - prof_->Fill(1, nStubs); - prof_->Fill(2, nTracks); - prof_->Fill(3, nLost); - } - for (const TPPtr& tpPtr : tpPtrsSelection) - fill(tpPtr, hisEff_); - vector recovered; - recovered.reserve(tpPtrsLost.size()); - set_intersection(tpPtrsLost.begin(), tpPtrsLost.end(), tpPtrs.begin(), tpPtrs.end(), back_inserter(recovered)); - for (const TPPtr& tpPtr : recovered) - tpPtrsLost.erase(tpPtr); - prof_->Fill(4, allMatched); - prof_->Fill(5, allTracks); - prof_->Fill(6, tpPtrs.size()); - prof_->Fill(7, tpPtrsSelection.size()); - prof_->Fill(8, tpPtrsLost.size()); - nEvents_++; - //if ((int)tpPtrsSelection.size() != selection->numTPs()) - //throw cms::Exception("..."); - } - - void AnalyzerZHT::endJob() { - if (nEvents_ == 0) - return; - // effi - eff_->SetPassedHistogram(*hisEff_, "f"); - eff_->SetTotalHistogram(*hisEffTotal_, "f"); - // printout SF summary - const double totalTPs = prof_->GetBinContent(9); - const double numStubs = prof_->GetBinContent(1); - const double numTracks = prof_->GetBinContent(2); - const double numTracksLost = prof_->GetBinContent(3); - const double totalTracks = prof_->GetBinContent(5); - const double numTracksMatched = prof_->GetBinContent(4); - const double numTPsAll = prof_->GetBinContent(6); - const double numTPsEff = prof_->GetBinContent(7); - const double numTPsLost = prof_->GetBinContent(8); - const double errStubs = prof_->GetBinError(1); - const double errTracks = prof_->GetBinError(2); - const double errTracksLost = prof_->GetBinError(3); - const double fracFake = (totalTracks - numTracksMatched) / totalTracks; - const double fracDup = (numTracksMatched - numTPsAll) / totalTracks; - const double eff = numTPsEff / totalTPs; - const double errEff = sqrt(eff * (1. - eff) / totalTPs / nEvents_); - const double effLoss = numTPsLost / totalTPs; - const double errEffLoss = sqrt(effLoss * (1. - effLoss) / totalTPs / nEvents_); - const vector nums = {numStubs, numTracks, numTracksLost}; - const vector errs = {errStubs, errTracks, errTracksLost}; - const int wNums = ceil(log10(*max_element(nums.begin(), nums.end()))) + 5; - const int wErrs = ceil(log10(*max_element(errs.begin(), errs.end()))) + 5; - log_ << " ZHT SUMMARY " << endl; - log_ << "number of stubs per TFP = " << setw(wNums) << numStubs << " +- " << setw(wErrs) << errStubs << endl; - log_ << "number of tracks per TFP = " << setw(wNums) << numTracks << " +- " << setw(wErrs) << errTracks - << endl; - log_ << "number of lost tracks per TFP = " << setw(wNums) << numTracksLost << " +- " << setw(wErrs) << errTracksLost - << endl; - log_ << " max tracking efficiency = " << setw(wNums) << eff << " +- " << setw(wErrs) << errEff << endl; - log_ << " lost tracking efficiency = " << setw(wNums) << effLoss << " +- " << setw(wErrs) << errEffLoss << endl; - log_ << " fake rate = " << setw(wNums) << fracFake << endl; - log_ << " duplicate rate = " << setw(wNums) << fracDup << endl; - log_ << "============================================================="; - LogPrint("L1Trigger/TrackerTFP") << log_.str(); - } - - // - void AnalyzerZHT::formTracks(const StreamStub& stream, vector>& tracks) const { - vector stubs; - stubs.reserve(stream.size()); - for (const FrameStub& frame : stream) - if (frame.first.isNonnull()) - stubs.emplace_back(frame, dataFormats_); - for (auto it = stubs.begin(); it != stubs.end();) { - const auto start = it; - const int id = it->trackId(); - auto different = [id](const StubZHT& stub) { return id != stub.trackId(); }; - it = find_if(it, stubs.end(), different); - vector ttStubRefs; - ttStubRefs.reserve(distance(start, it)); - transform(start, it, back_inserter(ttStubRefs), [](const StubZHT& stub) { return stub.ttStubRef(); }); - tracks.push_back(ttStubRefs); - } - } - - // - void AnalyzerZHT::associate(const vector>& tracks, - const StubAssociation* ass, - set& tps, - int& sum) const { - for (const vector& ttStubRefs : tracks) { - const vector& tpPtrs = ass->associate(ttStubRefs); - if (tpPtrs.empty()) - continue; - sum++; - copy(tpPtrs.begin(), tpPtrs.end(), inserter(tps, tps.begin())); - } - } - -} // namespace trackerTFP - -DEFINE_FWK_MODULE(trackerTFP::AnalyzerZHT); diff --git a/L1Trigger/TrackerTFP/test/ProducerAS.cc b/L1Trigger/TrackerTFP/test/ProducerAS.cc deleted file mode 100644 index 685f992330619..0000000000000 --- a/L1Trigger/TrackerTFP/test/ProducerAS.cc +++ /dev/null @@ -1,97 +0,0 @@ -#include "FWCore/Framework/interface/stream/EDProducer.h" -#include "FWCore/Framework/interface/Run.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Utilities/interface/EDGetToken.h" -#include "FWCore/Utilities/interface/EDPutToken.h" -#include "FWCore/Utilities/interface/ESGetToken.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "DataFormats/Common/interface/Handle.h" - -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" -#include "L1Trigger/TrackTrigger/interface/Setup.h" - -#include - -using namespace std; -using namespace edm; -using namespace tt; - -namespace trackerTFP { - - /*! \class trackerTFP::ProducerAS - * \brief Associate the TTTracks output by KF fitter with the tracks input to KF fitter. - * \author Thomas Schuh - * \date 2020, Oct - */ - class ProducerAS : public stream::EDProducer<> { - public: - explicit ProducerAS(const ParameterSet&); - ~ProducerAS() override {} - - private: - void beginRun(const Run&, const EventSetup&) override; - void produce(Event&, const EventSetup&) override; - void endJob() {} - - // ED input token of kf tracks - EDGetTokenT edGetTokenKF_; - // ED input token of kf TTtracks - EDGetTokenT edGetTokenTT_; - // ED output token for TTTrackRefMap - EDPutTokenT edPutToken_; - // Setup token - ESGetToken esGetTokenSetup_; - // configuration - ParameterSet iConfig_; - // helper class to store configurations - const Setup* setup_ = nullptr; - }; - - ProducerAS::ProducerAS(const ParameterSet& iConfig) : iConfig_(iConfig) { - const string& labelKF = iConfig.getParameter("LabelKF"); - const string& labelTT = iConfig.getParameter("LabelTT"); - const string& branch = iConfig.getParameter("BranchAcceptedTracks"); - // book in- and output ED products - edGetTokenKF_ = consumes(InputTag(labelKF, branch)); - edGetTokenTT_ = consumes(InputTag(labelTT, branch)); - edPutToken_ = produces(branch); - // book ES products - esGetTokenSetup_ = esConsumes(); - } - - void ProducerAS::beginRun(const Run& iRun, const EventSetup& iSetup) { - // helper class to store configurations - setup_ = &iSetup.getData(esGetTokenSetup_); - if (!setup_->configurationSupported()) - return; - // check process history if desired - if (iConfig_.getParameter("CheckHistory")) - setup_->checkHistory(iRun.processHistory()); - } - - void ProducerAS::produce(Event& iEvent, const EventSetup& iSetup) { - // empty KFTTTrack product - TTTrackRefMap ttTrackMap; - // read in KF Product and produce AssociatorKF product - if (setup_->configurationSupported()) { - Handle handleKF; - iEvent.getByToken(edGetTokenKF_, handleKF); - const StreamsTrack& streams = *handleKF.product(); - Handle handleTT; - iEvent.getByToken(edGetTokenTT_, handleTT); - int i(0); - for (const StreamTrack& stream : streams) - for (const FrameTrack& frame : stream) - if (frame.first.isNonnull()) - ttTrackMap.emplace(TTTrackRef(handleTT, i++), frame.first); - } - // store products - iEvent.emplace(edPutToken_, std::move(ttTrackMap)); - } - -} // namespace trackerTFP - -DEFINE_FWK_MODULE(trackerTFP::ProducerAS); diff --git a/L1Trigger/TrackerTFP/test/demonstrator_cfg.py b/L1Trigger/TrackerTFP/test/demonstrator_cfg.py index 7d8f493cb7307..ebe77c67db9de 100644 --- a/L1Trigger/TrackerTFP/test/demonstrator_cfg.py +++ b/L1Trigger/TrackerTFP/test/demonstrator_cfg.py @@ -3,35 +3,38 @@ process = cms.Process( "Demo" ) process.load( 'FWCore.MessageService.MessageLogger_cfi' ) -process.load( 'Configuration.Geometry.GeometryExtendedRun4D88Reco_cff' ) -process.load( 'Configuration.Geometry.GeometryExtendedRun4D88_cff' ) +process.load( 'Configuration.Geometry.GeometryExtendedRun4D98Reco_cff' ) +process.load( 'Configuration.Geometry.GeometryExtendedRun4D98_cff' ) process.load( 'Configuration.StandardSequences.MagneticField_cff' ) process.load( 'Configuration.StandardSequences.FrontierConditions_GlobalTag_cff' ) process.load( 'L1Trigger.TrackTrigger.TrackTrigger_cff' ) from Configuration.AlCa.GlobalTag import GlobalTag -process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic', '') +process.GlobalTag = GlobalTag(process.GlobalTag, '133X_mcRun4_realistic_v1', '') # load code that produces DTCStubs -process.load( 'L1Trigger.TrackerDTC.ProducerED_cff' ) +process.load( 'L1Trigger.TrackerDTC.DTC_cff' ) # cosutmize TT algorithm -#from L1Trigger.TrackerDTC.Customize_cff import * -#producerUseTMTT(process) -#analyzerUseTMTT(process) +from L1Trigger.TrackerDTC.Customize_cff import * +producerUseTMTT(process) +analyzerUseTMTT(process) #--- Load code that produces tfp Stubs process.load( 'L1Trigger.TrackerTFP.Producer_cff' ) +from L1Trigger.TrackerTFP.Customize_cff import * +setupUseTMTT( process ) #--- Load code that demonstrates tfp Stubs process.load( 'L1Trigger.TrackerTFP.Demonstrator_cff' ) # build schedule -process.tt = cms.Sequence ( process.TrackerDTCProducer - + process.TrackerTFPProducerGP - + process.TrackerTFPProducerHT - + process.TrackerTFPProducerMHT - + process.TrackerTFPProducerZHT - + process.TrackerTFPProducerZHTout - + process.TrackerTFPProducerKFin - + process.TrackerTFPProducerKF +process.tt = cms.Sequence ( process.ProducerDTC + + process.ProducerPP + + process.ProducerGP + + process.ProducerHT + + process.ProducerCTB + + process.ProducerKF + + process.ProducerDR + + process.ProducerTQ + + process.ProducerTFP ) process.demo = cms.Path( process.tt + process.TrackerTFPDemonstrator ) process.schedule = cms.Schedule( process.demo ) @@ -41,7 +44,16 @@ options = VarParsing.VarParsing( 'analysis' ) # specify input MC Samples = [ -'/store/mc/CMSSW_12_6_0/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_125X_mcRun4_realistic_v5_2026D88PU200RV183v2-v1/30000/0959f326-3f52-48d8-9fcf-65fc41de4e27.root' +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/0b2b0b0b-f312-48a8-9d46-ccbadc69bbfd.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/0c3cb20d-8556-450d-b4f0-e5c754818f74.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/0eafa2b4-711a-43ec-be1c-7e564c294a9a.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1450b1bb-171e-495e-a767-68e2796d95c2.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/15498564-9cf0-4219-aab7-f97b3484b122.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1838a806-316b-4f53-9d22-5b3856019623.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1a34eb87-b9a3-47fb-b945-57e6f775fcac.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1add5b2e-19cb-4581-956d-271907d03b72.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1bed1837-ef65-4e07-a2ac-13c705b20fc1.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1d057884-72bd-4353-8375-ec4616c00a33.root' ] options.register( 'inputMC', Samples, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.string, "Files to be processed" ) # specify number of events to process. @@ -53,7 +65,7 @@ process.source = cms.Source( "PoolSource", fileNames = cms.untracked.vstring( options.inputMC ), - #skipEvents = cms.untracked.uint32( 914 ), + #skipEvents = cms.untracked.uint32( 2 ), secondaryFileNames = cms.untracked.vstring(), duplicateCheckMode = cms.untracked.string( 'noDuplicateCheck' ) ) diff --git a/L1Trigger/TrackerTFP/test/test_cfg.py b/L1Trigger/TrackerTFP/test/test_cfg.py index b4836e0ff0e9e..a873444928982 100644 --- a/L1Trigger/TrackerTFP/test/test_cfg.py +++ b/L1Trigger/TrackerTFP/test/test_cfg.py @@ -10,19 +10,22 @@ process = cms.Process( "Demo" ) process.load( 'FWCore.MessageService.MessageLogger_cfi' ) -process.load( 'Configuration.Geometry.GeometryExtendedRun4D88Reco_cff' ) -process.load( 'Configuration.Geometry.GeometryExtendedRun4D88_cff' ) +process.load( 'Configuration.Geometry.GeometryExtendedRun4D98Reco_cff' ) +process.load( 'Configuration.Geometry.GeometryExtendedRun4D98_cff' ) process.load( 'Configuration.StandardSequences.MagneticField_cff' ) +process.load( 'Configuration.StandardSequences.Services_cff' ) +process.load( 'Configuration.EventContent.EventContent_cff' ) +process.load( 'Configuration.StandardSequences.EndOfProcess_cff' ) process.load( 'Configuration.StandardSequences.FrontierConditions_GlobalTag_cff' ) process.load( 'L1Trigger.TrackTrigger.TrackTrigger_cff' ) from Configuration.AlCa.GlobalTag import GlobalTag -process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic', '') +process.GlobalTag = GlobalTag(process.GlobalTag, '133X_mcRun4_realistic_v1', '') # load code that associates stubs with mctruth process.load( 'SimTracker.TrackTriggerAssociation.StubAssociator_cff' ) # load code that produces DTCStubs -process.load( 'L1Trigger.TrackerDTC.ProducerED_cff' ) +process.load( 'L1Trigger.TrackerDTC.DTC_cff' ) # load code that analyzes DTCStubs process.load( 'L1Trigger.TrackerDTC.Analyzer_cff' ) # cosutmize TT algorithm @@ -33,20 +36,22 @@ process.load( 'L1Trigger.TrackerTFP.Producer_cff' ) from L1Trigger.TrackerTFP.Customize_cff import * setupUseTMTT( process ) +simUseTMTT( process ) #--- Load code that analyzes tfp Stubs process.load( 'L1Trigger.TrackerTFP.Analyzer_cff' ) # build schedule -process.mc = cms.Sequence( process.StubAssociator ) -process.dtc = cms.Sequence( process.TrackerDTCProducer + process.TrackerDTCAnalyzer ) -process.gp = cms.Sequence( process.TrackerTFPProducerGP + process.TrackerTFPAnalyzerGP ) -process.ht = cms.Sequence( process.TrackerTFPProducerHT + process.TrackerTFPAnalyzerHT ) -process.mht = cms.Sequence( process.TrackerTFPProducerMHT + process.TrackerTFPAnalyzerMHT ) -process.zht = cms.Sequence( process.TrackerTFPProducerZHT + process.TrackerTFPAnalyzerZHT ) -process.interIn = cms.Sequence( process.TrackerTFPProducerZHTout + process.TrackerTFPProducerKFin + process.TrackerTFPAnalyzerKFin ) -process.kf = cms.Sequence( process.TrackerTFPProducerKF + process.TrackerTFPAnalyzerKF ) -process.interOut = cms.Sequence( process.TrackerTFPProducerTT + process.TrackerTFPProducerAS )#+ process.TrackerTFPAnalyzerTT ) -process.tt = cms.Path( process.mc + process.dtc + process.gp + process.ht + process.mht + process.zht + process.interIn + process.kf )#+ process.interOut ) +process.mc = cms.Sequence( process.StubAssociator ) +process.dtc = cms.Sequence( process.ProducerDTC + process.AnalyzerDTC ) +process.pp = cms.Sequence( process.ProducerPP ) +process.gp = cms.Sequence( process.ProducerGP + process.AnalyzerGP ) +process.ht = cms.Sequence( process.ProducerHT + process.AnalyzerHT ) +process.ctb = cms.Sequence( process.ProducerCTB + process.AnalyzerCTB ) +process.kf = cms.Sequence( process.ProducerKF + process.AnalyzerKF ) +process.dr = cms.Sequence( process.ProducerDR + process.AnalyzerDR ) +process.tq = cms.Sequence( process.ProducerTQ ) +process.tfp = cms.Sequence( process.ProducerTFP ) +process.tt = cms.Path( process.mc + process.dtc + process.pp + process.gp + process.ht + process.ctb)# + process.kf )#+ process.dr + process.tq )# + process.tfp ) process.schedule = cms.Schedule( process.tt ) # create options @@ -54,7 +59,16 @@ options = VarParsing.VarParsing( 'analysis' ) # specify input MC Samples = [ -'/store/mc/CMSSW_12_6_0/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_125X_mcRun4_realistic_v5_2026D88PU200RV183v2-v1/30000/0959f326-3f52-48d8-9fcf-65fc41de4e27.root' +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/0b2b0b0b-f312-48a8-9d46-ccbadc69bbfd.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/0c3cb20d-8556-450d-b4f0-e5c754818f74.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/0eafa2b4-711a-43ec-be1c-7e564c294a9a.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1450b1bb-171e-495e-a767-68e2796d95c2.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/15498564-9cf0-4219-aab7-f97b3484b122.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1838a806-316b-4f53-9d22-5b3856019623.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1a34eb87-b9a3-47fb-b945-57e6f775fcac.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1add5b2e-19cb-4581-956d-271907d03b72.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1bed1837-ef65-4e07-a2ac-13c705b20fc1.root', +'/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/1d057884-72bd-4353-8375-ec4616c00a33.root' ] options.register( 'inputMC', Samples, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.string, "Files to be processed" ) # specify number of events to process. @@ -66,11 +80,11 @@ process.source = cms.Source( "PoolSource", fileNames = cms.untracked.vstring( options.inputMC ), - #skipEvents = cms.untracked.uint32( 3 + 8 ), + #skipEvents = cms.untracked.uint32( 30 ), noEventSort = cms.untracked.bool( True ), secondaryFileNames = cms.untracked.vstring(), - duplicateCheckMode = cms.untracked.string( 'noDuplicateCheck' ) + duplicateCheckMode = cms.untracked.string( 'noDuplicateCheck' ), ) -#process.Timing = cms.Service( "Timing", summaryOnly = cms.untracked.bool( True ) ) +process.Timing = cms.Service( "Timing", summaryOnly = cms.untracked.bool( True ) ) process.MessageLogger.cerr.enableStatistics = False process.TFileService = cms.Service( "TFileService", fileName = cms.string( "Hist.root" ) ) diff --git a/SimTracker/TrackTriggerAssociation/interface/StubAssociation.h b/SimTracker/TrackTriggerAssociation/interface/StubAssociation.h index e13c12c982556..4ea2d8ba5b13f 100644 --- a/SimTracker/TrackTriggerAssociation/interface/StubAssociation.h +++ b/SimTracker/TrackTriggerAssociation/interface/StubAssociation.h @@ -1,7 +1,8 @@ #ifndef SimTracker_TrackTriggerAssociation_StubAssociation_h #define SimTracker_TrackTriggerAssociation_StubAssociation_h -#include "SimDataFormats/Associations/interface/TTTypes.h" +#include "DataFormats/Common/interface/Ptr.h" +#include "SimDataFormats/TrackingAnalysis/interface/TrackingParticle.h" #include "L1Trigger/TrackTrigger/interface/Setup.h" #include @@ -9,6 +10,8 @@ namespace tt { + typedef edm::Ptr TPPtr; + /*! \class tt::StubAssociation * \brief Class to associate reconstrucable TrackingParticles with TTStubs and vice versa. * It may associate multiple TPs with a TTStub and can therefore be used to associate @@ -18,8 +21,15 @@ namespace tt { */ class StubAssociation { public: + // configuration + struct Config { + int minLayersGood_; + int minLayersGoodPS_; + int maxLayersBad_; + int maxLayersBadPS_; + }; StubAssociation() { setup_ = nullptr; } - StubAssociation(const Setup* setup) : setup_(setup) {} + StubAssociation(const Config& iConfig, const Setup* setup); ~StubAssociation() {} // insert a TPPtr and its associated collection of TTstubRefs into the underlayering maps void insert(const TPPtr& tpPtr, const std::vector& ttSTubRefs); @@ -47,6 +57,14 @@ namespace tt { private: // stores, calculates and provides run-time constants const Setup* setup_; + // required number of layers a found track has to have in common with a TP to consider it matched + int minLayersGood_; + // required number of ps layers a found track has to have in common with a TP to consider it matched + int minLayersGoodPS_; + // max number of unassociated 2S stubs allowed to still associate TTTrack with TP + int maxLayersBad_; + // max number of unassociated PS stubs allowed to still associate TTTrack with TP + int maxLayersBadPS_; // map containing TTStubRef and their associated collection of TPPtrs std::map> mapTTStubRefsTPPtrs_; // map containing TPPtr and their associated collection of TTStubRefs diff --git a/SimTracker/TrackTriggerAssociation/plugins/StubAssociator.cc b/SimTracker/TrackTriggerAssociation/plugins/StubAssociator.cc index f631345a24373..b94c2eb6401a8 100644 --- a/SimTracker/TrackTriggerAssociation/plugins/StubAssociator.cc +++ b/SimTracker/TrackTriggerAssociation/plugins/StubAssociator.cc @@ -1,4 +1,4 @@ -#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" #include "FWCore/Framework/interface/Run.h" #include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/Framework/interface/Event.h" @@ -9,19 +9,15 @@ #include "FWCore/Utilities/interface/EDPutToken.h" #include "DataFormats/Common/interface/Handle.h" -#include "SimDataFormats/Associations/interface/TTTypes.h" #include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" #include "L1Trigger/TrackTrigger/interface/Setup.h" #include #include +#include #include #include #include -#include - -using namespace std; -using namespace edm; namespace tt { @@ -34,65 +30,133 @@ namespace tt { * \author Thomas Schuh * \date 2020, Apr */ - class StubAssociator : public global::EDProducer<> { + class StubAssociator : public edm::stream::EDProducer<> { public: - explicit StubAssociator(const ParameterSet&); + explicit StubAssociator(const edm::ParameterSet&); + ~StubAssociator() override {} private: - void produce(StreamID, Event&, const EventSetup&) const override; + void beginRun(const edm::Run&, const edm::EventSetup&) override; + void produce(edm::Event&, const edm::EventSetup&) override; + // helper classe to store configurations + const Setup* setup_; // ED input token of TTStubs - EDGetTokenT getTokenTTStubDetSetVec_; + edm::EDGetTokenT getTokenTTStubDetSetVec_; // ED input token of TTClusterAssociation - EDGetTokenT getTokenTTClusterAssMap_; + edm::EDGetTokenT getTokenTTClusterAssMap_; // ED output token for recosntructable stub association - EDPutTokenT putTokenReconstructable_; + edm::EDPutTokenT putTokenReconstructable_; // ED output token for selected stub association - EDPutTokenT putTokenSelection_; + edm::EDPutTokenT putTokenSelection_; // Setup token - ESGetToken esGetTokenSetup_; + edm::ESGetToken esGetTokenSetup_; + // + StubAssociation::Config iConfig_; + // required number of associated stub layers to a TP to consider it reconstruct-able + int minLayers_; + // required number of associated ps stub layers to a TP to consider it reconstruct-able + int minLayersPS_; + // pt cut in GeV + double minPt_; + // max eta for TP with z0 = 0 + double maxEta0_; + // half lumi region size in cm + double maxZ0_; + // cut on impact parameter in cm + double maxD0_; + // cut on vertex pos r in cm + double maxVertR_; + // cut on vertex pos z in cm + double maxVertZ_; + // cut on TP zT + double maxZT_; + // selector to partly select TPs for efficiency measurements + TrackingParticleSelector tpSelector_; }; - StubAssociator::StubAssociator(const ParameterSet& iConfig) { + StubAssociator::StubAssociator(const edm::ParameterSet& iConfig) + : minLayers_(iConfig.getParameter("MinLayers")), + minLayersPS_(iConfig.getParameter("MinLayersPS")), + minPt_(iConfig.getParameter("MinPt")), + maxEta0_(iConfig.getParameter("MaxEta0")), + maxZ0_(iConfig.getParameter("MaxZ0")), + maxD0_(iConfig.getParameter("MaxD0")), + maxVertR_(iConfig.getParameter("MaxVertR")), + maxVertZ_(iConfig.getParameter("MaxVertZ")) { + iConfig_.minLayersGood_ = iConfig.getParameter("MinLayersGood"); + iConfig_.minLayersGoodPS_ = iConfig.getParameter("MinLayersGoodPS"); + iConfig_.maxLayersBad_ = iConfig.getParameter("MaxLayersBad"); + iConfig_.maxLayersBadPS_ = iConfig.getParameter("MaxLayersBadPS"); // book in- and output ed products - getTokenTTStubDetSetVec_ = consumes(iConfig.getParameter("InputTagTTStubDetSetVec")); - getTokenTTClusterAssMap_ = consumes(iConfig.getParameter("InputTagTTClusterAssMap")); - putTokenReconstructable_ = produces(iConfig.getParameter("BranchReconstructable")); - putTokenSelection_ = produces(iConfig.getParameter("BranchSelection")); + getTokenTTStubDetSetVec_ = + consumes(iConfig.getParameter("InputTagTTStubDetSetVec")); + getTokenTTClusterAssMap_ = + consumes(iConfig.getParameter("InputTagTTClusterAssMap")); + putTokenReconstructable_ = produces(iConfig.getParameter("BranchReconstructable")); + putTokenSelection_ = produces(iConfig.getParameter("BranchSelection")); // book ES product - esGetTokenSetup_ = esConsumes(); + esGetTokenSetup_ = esConsumes(); } - void StubAssociator::produce(StreamID, Event& iEvent, const EventSetup& iSetup) const { - auto const& setup = iSetup.getData(esGetTokenSetup_); + void StubAssociator::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) { + setup_ = &iSetup.getData(esGetTokenSetup_); + maxZT_ = std::sinh(maxEta0_) * setup_->chosenRofZ(); + // configure TrackingParticleSelector + constexpr double ptMax = 9.e9; + constexpr int minHit = 0; + constexpr bool signalOnly = true; + constexpr bool intimeOnly = true; + constexpr bool chargedOnly = true; + constexpr bool stableOnly = false; + const double maxEta = std::asinh((maxZT_ + maxZ0_) / setup_->chosenRofZ()); + tpSelector_ = TrackingParticleSelector( + minPt_, ptMax, -maxEta, maxEta, maxVertR_, maxVertZ_, minHit, signalOnly, intimeOnly, chargedOnly, stableOnly); + } + void StubAssociator::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { // associate TTStubs with TrackingParticles - Handle handleTTStubDetSetVec = iEvent.getHandle(getTokenTTStubDetSetVec_); - auto const& ttClusterAssMap = iEvent.get(getTokenTTClusterAssMap_); - - map> mapTPPtrsTTStubRefs; + edm::Handle handleTTStubDetSetVec; + iEvent.getByToken(getTokenTTStubDetSetVec_, handleTTStubDetSetVec); + edm::Handle handleTTClusterAssMap; + iEvent.getByToken(getTokenTTClusterAssMap_, handleTTClusterAssMap); + std::map> mapTPPtrsTTStubRefs; auto isNonnull = [](const TPPtr& tpPtr) { return tpPtr.isNonnull(); }; for (TTStubDetSetVec::const_iterator ttModule = handleTTStubDetSetVec->begin(); ttModule != handleTTStubDetSetVec->end(); ttModule++) { for (TTStubDetSet::const_iterator ttStub = ttModule->begin(); ttStub != ttModule->end(); ttStub++) { const TTStubRef ttStubRef = makeRefTo(handleTTStubDetSetVec, ttStub); - set tpPtrs; + std::set tpPtrs; for (unsigned int iClus = 0; iClus < 2; iClus++) { - const vector& assocPtrs = ttClusterAssMap.findTrackingParticlePtrs(ttStubRef->clusterRef(iClus)); - copy_if(assocPtrs.begin(), assocPtrs.end(), inserter(tpPtrs, tpPtrs.begin()), isNonnull); + const std::vector& assocPtrs = + handleTTClusterAssMap->findTrackingParticlePtrs(ttStubRef->clusterRef(iClus)); + std::copy_if(assocPtrs.begin(), assocPtrs.end(), std::inserter(tpPtrs, tpPtrs.begin()), isNonnull); } for (const TPPtr& tpPtr : tpPtrs) mapTPPtrsTTStubRefs[tpPtr].push_back(ttStubRef); } } // associate reconstructable TrackingParticles with TTStubs - StubAssociation reconstructable(&setup); - StubAssociation selection(&setup); + StubAssociation reconstructable(iConfig_, setup_); + StubAssociation selection(iConfig_, setup_); for (const auto& p : mapTPPtrsTTStubRefs) { - if (!setup.useForReconstructable(*p.first) || !setup.reconstructable(p.second)) + // require min layers + std::set hitPattern, hitPatternPS; + for (const TTStubRef& ttStubRef : p.second) { + const int layerId = setup_->layerId(ttStubRef); + hitPattern.insert(layerId); + if (setup_->psModule(ttStubRef)) + hitPatternPS.insert(layerId); + } + if (static_cast(hitPattern.size()) < minLayers_ || static_cast(hitPatternPS.size()) < minLayersPS_) continue; reconstructable.insert(p.first, p.second); - if (setup.useForAlgEff(*p.first)) + // require parameter space + const double zT = p.first->z0() + p.first->tanl() * setup_->chosenRofZ(); + if ((std::abs(p.first->d0()) > maxD0_) || (std::abs(p.first->z0()) > maxZ0_) || (std::abs(zT) > maxZT_)) + continue; + // require signal only and min pt + if (tpSelector_(*p.first)) selection.insert(p.first, p.second); } iEvent.emplace(putTokenReconstructable_, std::move(reconstructable)); diff --git a/SimTracker/TrackTriggerAssociation/python/StubAssociator_cff.py b/SimTracker/TrackTriggerAssociation/python/StubAssociator_cff.py index 4f7c6d9c1f9d8..7ed70928f5f58 100644 --- a/SimTracker/TrackTriggerAssociation/python/StubAssociator_cff.py +++ b/SimTracker/TrackTriggerAssociation/python/StubAssociator_cff.py @@ -7,7 +7,7 @@ import FWCore.ParameterSet.Config as cms -from L1Trigger.TrackTrigger.ProducerSetup_cff import TrackTriggerSetup +from L1Trigger.TrackTrigger.Setup_cff import TrackTriggerSetup from SimTracker.TrackTriggerAssociation.StubAssociator_cfi import StubAssociator_params StubAssociator = cms.EDProducer('tt::StubAssociator', StubAssociator_params) diff --git a/SimTracker/TrackTriggerAssociation/python/StubAssociator_cfi.py b/SimTracker/TrackTriggerAssociation/python/StubAssociator_cfi.py index 1e5a68cbab1fc..fd726425abf29 100644 --- a/SimTracker/TrackTriggerAssociation/python/StubAssociator_cfi.py +++ b/SimTracker/TrackTriggerAssociation/python/StubAssociator_cfi.py @@ -1,9 +1,23 @@ import FWCore.ParameterSet.Config as cms StubAssociator_params = cms.PSet ( - InputTagTTStubDetSetVec = cms.InputTag( "TTStubsFromPhase2TrackerDigis", "StubAccepted" ), # - InputTagTTClusterAssMap = cms.InputTag( "TTClusterAssociatorFromPixelDigis", "ClusterAccepted" ), # - InputTagTTStubAssMap = cms.InputTag( "TTStubAssociatorFromPixelDigis", "StubAccepted" ), # - BranchReconstructable = cms.string ( "Reconstructable" ), # name of StubAssociation collection made with reconstractable TPs - BranchSelection = cms.string ( "UseForAlgEff" ) # name of StubAssociation collection used for tracking efficiency + InputTagTTStubDetSetVec = cms.InputTag( "TTStubsFromPhase2TrackerDigis", "StubAccepted" ), # + InputTagTTClusterAssMap = cms.InputTag( "TTClusterAssociatorFromPixelDigis", "ClusterAccepted" ), # + #InputTagTTClusterAssMap = cms.InputTag( "CleanAssoc", "AtLeastOneCluster" ), + BranchReconstructable = cms.string ( "Reconstructable" ), # name of StubAssociation collection made with reconstractable TPs + BranchSelection = cms.string ( "UseForAlgEff" ), # name of StubAssociation collection used for tracking efficiency + + MinPt = cms.double( 2. ), # pt cut in GeV + MaxEta0 = cms.double( 2.4 ), # max eta for TP with z0 = 0 + MaxZ0 = cms.double( 15. ), # half lumi region size in cm + MaxD0 = cms.double( 5. ), # cut on impact parameter in cm + MaxVertR = cms.double( 1. ), # cut on vertex pos r in cm + MaxVertZ = cms.double( 30. ), # cut on vertex pos z in cm + MinLayers = cms.int32 ( 4 ), # required number of associated stub layers to a TP to consider it reconstruct-able + MinLayersPS = cms.int32 ( 0 ), # required number of associated ps stub layers to a TP to consider it reconstruct-able + MinLayersGood = cms.int32 ( 4 ), # required number of layers a found track has to have in common with a TP to consider it matched + MinLayersGoodPS = cms.int32 ( 0 ), # required number of ps layers a found track has to have in common with a TP to consider it matched + MaxLayersBad = cms.int32 ( 1 ), # max number of unassociated 2S stubs allowed to still associate TTTrack with TP + MaxLayersBadPS = cms.int32 ( 0 ) # max number of unassociated PS stubs allowed to still associate TTTrack with TP + ) diff --git a/SimTracker/TrackTriggerAssociation/src/StubAssociation.cc b/SimTracker/TrackTriggerAssociation/src/StubAssociation.cc index c6805b25b7019..e6a7208d4f2a1 100644 --- a/SimTracker/TrackTriggerAssociation/src/StubAssociation.cc +++ b/SimTracker/TrackTriggerAssociation/src/StubAssociation.cc @@ -5,53 +5,61 @@ #include #include -using namespace std; - namespace tt { + StubAssociation::StubAssociation(const Config& iConfig, const Setup* setup) + : setup_(setup), + minLayersGood_(iConfig.minLayersGood_), + minLayersGoodPS_(iConfig.minLayersGoodPS_), + maxLayersBad_(iConfig.maxLayersBad_), + maxLayersBadPS_(iConfig.maxLayersBadPS_) {} + // insert a TPPtr and its associated collection of TTstubRefs into the underlayering maps - void StubAssociation::insert(const TPPtr& tpPtr, const vector& ttSTubRefs) { + void StubAssociation::insert(const TPPtr& tpPtr, const std::vector& ttSTubRefs) { mapTPPtrsTTStubRefs_.insert({tpPtr, ttSTubRefs}); for (const TTStubRef& ttSTubRef : ttSTubRefs) mapTTStubRefsTPPtrs_[ttSTubRef].push_back(tpPtr); } // returns collection of TPPtrs associated to given TTstubRef - vector StubAssociation::findTrackingParticlePtrs(const TTStubRef& ttStubRef) const { + std::vector StubAssociation::findTrackingParticlePtrs(const TTStubRef& ttStubRef) const { const auto it = mapTTStubRefsTPPtrs_.find(ttStubRef); - const vector res = it != mapTTStubRefsTPPtrs_.end() ? it->second : emptyTPPtrs_; + const std::vector res = it != mapTTStubRefsTPPtrs_.end() ? it->second : emptyTPPtrs_; return res; } // returns collection of TTStubRefs associated to given TPPtr - vector StubAssociation::findTTStubRefs(const TPPtr& tpPtr) const { + std::vector StubAssociation::findTTStubRefs(const TPPtr& tpPtr) const { const auto it = mapTPPtrsTTStubRefs_.find(tpPtr); return it != mapTPPtrsTTStubRefs_.end() ? it->second : emptyTTStubRefs_; } // Get all TPs that are matched to these stubs in at least 'tpMinLayers' layers and 'tpMinLayersPS' ps layers - vector StubAssociation::associate(const vector& ttStubRefs) const { + std::vector StubAssociation::associate(const std::vector& ttStubRefs) const { // count associated layer for each TP - map> m; - map> mPS; + std::map, std::set>> m; for (const TTStubRef& ttStubRef : ttStubRefs) { for (const TPPtr& tpPtr : findTrackingParticlePtrs(ttStubRef)) { const int layerId = setup_->layerId(ttStubRef); - m[tpPtr].insert(layerId); + m[tpPtr].first.insert(layerId); if (setup_->psModule(ttStubRef)) - mPS[tpPtr].insert(layerId); + m[tpPtr].second.insert(layerId); } } // count matched TPs - auto acc = [this](int sum, const pair>& p) { - return sum + ((int)p.second.size() < setup_->tpMinLayers() ? 0 : 1); + auto acc = [this](int sum, const std::pair, std::set>>& p) { + return sum + (static_cast(p.second.first.size()) < minLayersGood_ || + static_cast(p.second.second.size()) < minLayersGoodPS_ + ? 0 + : 1); }; - const int nTPs = accumulate(m.begin(), m.end(), 0, acc); - vector tpPtrs; + const int nTPs = std::accumulate(m.begin(), m.end(), 0, acc); + std::vector tpPtrs; tpPtrs.reserve(nTPs); // fill and return matched TPs for (const auto& p : m) - if ((int)p.second.size() >= setup_->tpMinLayers() && (int)mPS[p.first].size() >= setup_->tpMinLayersPS()) + if (static_cast(p.second.first.size()) >= minLayersGood_ && + static_cast(p.second.second.size()) >= minLayersGoodPS_) tpPtrs.push_back(p.first); return tpPtrs; } @@ -59,21 +67,19 @@ namespace tt { // Get all TPs that are matched to these stubs in at least 'tpMinLayers' layers and 'tpMinLayersPS' ps layers with not more then 'tpMaxBadStubs2S' not associated 2S stubs and not more then 'tpMaxBadStubsPS' associated PS stubs std::vector StubAssociation::associateFinal(const std::vector& ttStubRefs) const { // Get all TPs that are matched to these stubs in at least 'tpMinLayers' layers and 'tpMinLayersPS' ps layers - vector tpPtrs = associate(ttStubRefs); + std::vector tpPtrs = associate(ttStubRefs); // remove TPs with more then 'tpMaxBadStubs2S' not associated 2S stubs and more then 'tpMaxBadStubsPS' not associated PS stubs auto check = [this, &ttStubRefs](const TPPtr& tpPtr) { int bad2S(0); int badPS(0); for (const TTStubRef& ttStubRef : ttStubRefs) { - const vector& tpPtrs = findTrackingParticlePtrs(ttStubRef); - if (find(tpPtrs.begin(), tpPtrs.end(), tpPtr) == tpPtrs.end()) + const std::vector& tpPtrs = findTrackingParticlePtrs(ttStubRef); + if (std::find(tpPtrs.begin(), tpPtrs.end(), tpPtr) == tpPtrs.end()) setup_->psModule(ttStubRef) ? badPS++ : bad2S++; } - if (badPS > setup_->tpMaxBadStubsPS() || bad2S > setup_->tpMaxBadStubs2S()) - return true; - return false; + return (badPS > maxLayersBadPS_ || badPS + bad2S > maxLayersBad_); }; - tpPtrs.erase(remove_if(tpPtrs.begin(), tpPtrs.end(), check), tpPtrs.end()); + tpPtrs.erase(std::remove_if(tpPtrs.begin(), tpPtrs.end(), check), tpPtrs.end()); return tpPtrs; }