From 17aee38df1bd42979e56b7bce566c813f3bc4f7c Mon Sep 17 00:00:00 2001 From: Thomas Schuh Date: Thu, 9 Jan 2025 14:48:49 +0000 Subject: [PATCH] squash before rebase for PR to central cmssw. ci workflow deleted from pr. data folder deleted. --- .../python/L1TrackTrigger_cff.py | 4 +- DataFormats/L1TrackTrigger/interface/TTBV.h | 129 ++- .../L1TrackTrigger/src/classes_def.xml | 2 + .../test/L1TrackObjectNtupleMaker.cc | 10 +- .../test/L1TrackObjectNtupleMaker_cfg.py | 4 +- .../make_l1ctLayer1_dumpFiles_fromRAW_cfg.py | 5 +- .../make_l1ct_patternFiles_fromRAW_cfg.py | 5 +- .../TrackFindingTMTT/interface/L1track3D.h | 29 + L1Trigger/TrackFindingTMTT/interface/Stub.h | 13 + .../python/TMTrackProducer_Defaults_cfi.py | 2 +- L1Trigger/TrackFindingTMTT/src/Settings.cc | 2 +- L1Trigger/TrackFindingTMTT/src/Stub.cc | 47 + L1Trigger/TrackFindingTracklet/README.md | 19 +- .../interface/ChannelAssignment.h | 50 +- .../interface/DataFormats.h | 492 +++++++++ .../interface/DataFormatsRcd.h | 17 + .../interface/{DR.h => DuplicateRemoval.h} | 48 +- .../interface/HitPatternHelper.h | 10 +- .../TrackFindingTracklet/interface/KFin.h | 95 -- .../interface/KalmanFilter.h | 164 +++ .../interface/KalmanFilterFormats.h | 243 +++++ .../TrackFindingTracklet/interface/Settings.h | 4 +- .../TrackFindingTracklet/interface/State.h | 143 +++ .../interface/TrackFindingProcessor.h | 92 ++ .../interface/{DRin.h => TrackMultiplexer.h} | 92 +- .../interface/TrackletProcessorDisplaced.h | 6 +- .../interface/TripletEngineUnit.h | 94 ++ .../plugins/L1FPGATrackProducer.cc | 149 +-- .../plugins/ProducerDR.cc | 88 +- .../plugins/ProducerDRin.cc | 152 --- .../plugins/ProducerDataFormats.cc | 46 + .../plugins/ProducerKF.cc | 178 ++++ .../plugins/ProducerKFin.cc | 147 --- .../plugins/ProducerKFout.cc | 381 ------- .../plugins/ProducerTBout.cc | 192 ---- .../plugins/ProducerTFP.cc | 125 +++ .../plugins/ProducerTM.cc | 127 +++ .../python/Analyzer_cff.py | 15 +- .../python/Analyzer_cfi.py | 9 +- .../python/ChannelAssignment_cff.py | 2 + .../python/ChannelAssignment_cfi.py | 19 +- .../python/Customize_cff.py | 54 +- .../python/DataFormats_cff.py | 11 + .../python/Demonstrator_cff.py | 3 + .../python/Demonstrator_cfi.py | 15 +- .../python/KalmanFilterFormats_cfi.py | 66 ++ .../python/ProducerHPH_cff.py | 6 +- .../python/Producer_cff.py | 26 +- .../python/Producer_cfi.py | 38 +- .../l1tTTTracksFromTrackletEmulation_cfi.py | 14 +- .../src/ChannelAssignment.cc | 32 +- L1Trigger/TrackFindingTracklet/src/DR.cc | 160 --- L1Trigger/TrackFindingTracklet/src/DRin.cc | 459 --------- .../TrackFindingTracklet/src/DataFormats.cc | 227 ++++ .../src/DuplicateRemoval.cc | 183 ++++ .../src/ES_DataFormats.cc | 6 + .../TrackFindingTracklet/src/FitTrack.cc | 4 +- .../src/HitPatternHelper.cc | 17 +- L1Trigger/TrackFindingTracklet/src/KFin.cc | 270 ----- .../TrackFindingTracklet/src/KalmanFilter.cc | 718 +++++++++++++ .../src/KalmanFilterFormats.cc | 588 +++++++++++ .../src/PurgeDuplicate.cc | 12 +- L1Trigger/TrackFindingTracklet/src/State.cc | 170 +++ .../src/TrackFindingProcessor.cc | 279 +++++ .../src/TrackMultiplexer.cc | 429 ++++++++ .../src/TrackletConfigBuilder.cc | 10 +- .../src/TrackletProcessorDisplaced.cc | 364 ++++--- .../src/TripletEngineUnit.cc | 112 ++ .../TrackFindingTracklet/test/AnalyzerDR.cc | 117 +-- .../test/AnalyzerDemonstrator.cc | 62 +- .../TrackFindingTracklet/test/AnalyzerKF.cc | 413 ++++++++ .../test/AnalyzerKFout.cc | 6 +- .../test/AnalyzerTBout.cc | 429 -------- .../test/{AnalyzerDRin.cc => AnalyzerTM.cc} | 161 ++- .../test/AnalyzerTracklet.cc | 22 +- .../test/HybridTracksNewKF_cfg.py | 49 +- .../test/HybridTracks_cfg.py | 21 +- .../test/L1TrackNtupleMaker.cc | 144 ++- .../test/L1TrackNtupleMaker_cfg.py | 26 +- .../test/L1TrackNtuplePlot.C | 14 +- .../TrackFindingTracklet/test/ProducerIRin.cc | 25 +- .../test/demonstrator_cfg.py | 33 +- .../TrackTrigger/interface/L1TrackQuality.h | 73 -- .../TrackTrigger/interface/SensorModule.h | 16 + L1Trigger/TrackTrigger/interface/Setup.h | 564 +++++----- L1Trigger/TrackTrigger/interface/SetupRcd.h | 18 +- .../TrackTrigger/plugins/ProducerSetup.cc | 50 +- .../TrackTrigger/python/ProducerSetup_cff.py | 14 - .../TrackTrigger/python/ProducerSetup_cfi.py | 230 ----- L1Trigger/TrackTrigger/python/Setup_cff.py | 6 + L1Trigger/TrackTrigger/python/Setup_cfi.py | 204 ++++ .../python/TTStubAlgorithmRegister_cfi.py | 3 +- .../python/TrackQualityParams_cfi.py | 11 - L1Trigger/TrackTrigger/src/L1TrackQuality.cc | 115 --- L1Trigger/TrackTrigger/src/SensorModule.cc | 7 + L1Trigger/TrackTrigger/src/Setup.cc | 459 +++------ .../TrackTrigger/test/CleanRelVal_cfg.py | 78 ++ L1Trigger/TrackerDTC/BuildFile.xml | 3 +- L1Trigger/TrackerDTC/interface/DTC.h | 4 + .../TrackerDTC/interface/LayerEncoding.h | 5 +- L1Trigger/TrackerDTC/interface/Stub.h | 36 +- .../plugins/{ProducerED.cc => ProducerDTC.cc} | 81 +- .../plugins/ProducerLayerEncoding.cc | 5 +- .../TrackerDTC/python/AnalyzerDAQ_cff.py | 4 +- .../TrackerDTC/python/AnalyzerDAQ_cfi.py | 2 + L1Trigger/TrackerDTC/python/Analyzer_cff.py | 8 +- L1Trigger/TrackerDTC/python/Analyzer_cfi.py | 13 +- L1Trigger/TrackerDTC/python/Customize_cff.py | 20 +- .../python/{ProducerED_cff.py => DTC_cff.py} | 9 +- .../python/{ProducerED_cfi.py => DTC_cfi.py} | 5 +- .../TrackerDTC/python/LayerEncoding_cff.py | 3 + .../python/ProducerLayerEncoding_cff.py | 5 - .../python/ProducerLayerEncoding_cfi.py | 7 - L1Trigger/TrackerDTC/src/DTC.cc | 17 +- L1Trigger/TrackerDTC/src/LayerEncoding.cc | 5 +- L1Trigger/TrackerDTC/src/Stub.cc | 285 +++-- L1Trigger/TrackerDTC/test/Analyzer.cc | 432 +++----- L1Trigger/TrackerDTC/test/testDAQ_cfg.py | 4 +- L1Trigger/TrackerDTC/test/test_cfg.py | 6 +- L1Trigger/TrackerTFP/BuildFile.xml | 1 + L1Trigger/TrackerTFP/README.md | 28 +- .../TrackerTFP/interface/CleanTrackBuilder.h | 138 +++ L1Trigger/TrackerTFP/interface/DataFormats.h | 973 ++++++------------ L1Trigger/TrackerTFP/interface/Demonstrator.h | 16 +- .../TrackerTFP/interface/DuplicateRemoval.h | 58 ++ .../TrackerTFP/interface/GeometricProcessor.h | 26 +- .../TrackerTFP/interface/HoughTransform.h | 52 +- L1Trigger/TrackerTFP/interface/KalmanFilter.h | 154 +-- .../interface/KalmanFilterFormats.h | 120 ++- .../interface/KalmanFilterFormatsRcd.h | 17 - .../TrackerTFP/interface/LayerEncoding.h | 38 +- .../TrackerTFP/interface/MiniHoughTransform.h | 69 -- L1Trigger/TrackerTFP/interface/State.h | 125 ++- .../interface/TrackFindingProcessor.h | 89 ++ L1Trigger/TrackerTFP/interface/TrackQuality.h | 160 +++ .../TrackerTFP/interface/TrackQualityRcd.h | 17 + .../TrackerTFP/interface/ZHoughTransform.h | 56 - L1Trigger/TrackerTFP/plugins/ProducerCTB.cc | 246 +++++ L1Trigger/TrackerTFP/plugins/ProducerDR.cc | 188 ++++ .../{ProducerES.cc => ProducerDataFormats.cc} | 16 +- .../plugins/ProducerDemonstrator.cc | 3 +- .../TrackerTFP/plugins/ProducerFormatsKF.cc | 45 - L1Trigger/TrackerTFP/plugins/ProducerGP.cc | 118 ++- L1Trigger/TrackerTFP/plugins/ProducerHT.cc | 101 +- L1Trigger/TrackerTFP/plugins/ProducerKF.cc | 195 ++-- L1Trigger/TrackerTFP/plugins/ProducerKFin.cc | 225 ---- L1Trigger/TrackerTFP/plugins/ProducerMHT.cc | 110 -- L1Trigger/TrackerTFP/plugins/ProducerPP.cc | 81 ++ L1Trigger/TrackerTFP/plugins/ProducerTFP.cc | 120 +++ L1Trigger/TrackerTFP/plugins/ProducerTQ.cc | 154 +++ L1Trigger/TrackerTFP/plugins/ProducerTT.cc | 124 --- .../plugins/ProducerTrackQuality.cc | 39 + L1Trigger/TrackerTFP/plugins/ProducerZHT.cc | 110 -- .../TrackerTFP/plugins/ProducerZHTout.cc | 135 --- L1Trigger/TrackerTFP/python/Analyzer_cff.py | 16 +- L1Trigger/TrackerTFP/python/Analyzer_cfi.py | 10 +- L1Trigger/TrackerTFP/python/Customize_cff.py | 28 +- .../TrackerTFP/python/DataFormats_cff.py | 5 + .../TrackerTFP/python/Demonstrator_cff.py | 3 + .../TrackerTFP/python/Demonstrator_cfi.py | 16 +- .../python/KalmanFilterFormats_cff.py | 5 - .../python/KalmanFilterFormats_cfi.py | 121 +-- .../TrackerTFP/python/LayerEncoding_cff.py | 5 + L1Trigger/TrackerTFP/python/ProducerES_cff.py | 5 - L1Trigger/TrackerTFP/python/ProducerES_cfi.py | 28 - .../python/ProducerLayerEncoding_cff.py | 5 - .../python/ProducerLayerEncoding_cfi.py | 7 - L1Trigger/TrackerTFP/python/Producer_cff.py | 26 +- L1Trigger/TrackerTFP/python/Producer_cfi.py | 34 +- .../TrackerTFP/python/TrackQuality_cff.py | 12 + .../TrackerTFP/python/TrackQuality_cfi.py | 35 + L1Trigger/TrackerTFP/src/CleanTrackBuilder.cc | 489 +++++++++ L1Trigger/TrackerTFP/src/DataFormats.cc | 889 +++------------- L1Trigger/TrackerTFP/src/Demonstrator.cc | 63 +- L1Trigger/TrackerTFP/src/DuplicateRemoval.cc | 142 +++ .../TrackerTFP/src/ES_KalmanFilterFormats.cc | 4 - L1Trigger/TrackerTFP/src/ES_TrackQuality.cc | 5 + .../TrackerTFP/src/GeometricProcessor.cc | 150 +-- L1Trigger/TrackerTFP/src/HoughTransform.cc | 297 +++--- L1Trigger/TrackerTFP/src/KalmanFilter.cc | 800 ++++++++------ .../TrackerTFP/src/KalmanFilterFormats.cc | 410 ++++++-- .../TrackerTFP/src/KalmanFilterFormatsRcd.cc | 4 - L1Trigger/TrackerTFP/src/LayerEncoding.cc | 203 ++-- .../TrackerTFP/src/MiniHoughTransform.cc | 317 ------ L1Trigger/TrackerTFP/src/State.cc | 246 +++-- .../TrackerTFP/src/TrackFindingProcessor.cc | 278 +++++ L1Trigger/TrackerTFP/src/TrackQuality.cc | 283 +++++ L1Trigger/TrackerTFP/src/ZHoughTransform.cc | 322 ------ .../test/{AnalyzerKFin.cc => AnalyzerCTB.cc} | 210 ++-- .../test/AnalyzerDR.cc} | 174 ++-- .../TrackerTFP/test/AnalyzerDemonstrator.cc | 17 +- L1Trigger/TrackerTFP/test/AnalyzerGP.cc | 105 +- L1Trigger/TrackerTFP/test/AnalyzerHT.cc | 141 ++- L1Trigger/TrackerTFP/test/AnalyzerKF.cc | 348 ++++--- .../test/{AnalyzerZHT.cc => AnalyzerTFP.cc} | 215 ++-- .../test/{AnalyzerMHT.cc => AnalyzerTQ.cc} | 213 ++-- L1Trigger/TrackerTFP/test/AnalyzerTT.cc | 131 --- L1Trigger/TrackerTFP/test/ProducerAS.cc | 97 -- L1Trigger/TrackerTFP/test/demonstrator_cfg.py | 46 +- L1Trigger/TrackerTFP/test/test_cfg.py | 50 +- .../interface/StubAssociation.h | 16 +- .../plugins/StubAssociator.cc | 101 +- .../python/StubAssociator_cff.py | 2 +- .../python/StubAssociator_cfi.py | 24 +- .../src/StubAssociation.cc | 28 +- 205 files changed, 13207 insertions(+), 10174 deletions(-) create mode 100644 L1Trigger/TrackFindingTracklet/interface/DataFormats.h create mode 100644 L1Trigger/TrackFindingTracklet/interface/DataFormatsRcd.h rename L1Trigger/TrackFindingTracklet/interface/{DR.h => DuplicateRemoval.h} (56%) delete mode 100644 L1Trigger/TrackFindingTracklet/interface/KFin.h create mode 100644 L1Trigger/TrackFindingTracklet/interface/KalmanFilter.h create mode 100644 L1Trigger/TrackFindingTracklet/interface/KalmanFilterFormats.h create mode 100644 L1Trigger/TrackFindingTracklet/interface/State.h create mode 100644 L1Trigger/TrackFindingTracklet/interface/TrackFindingProcessor.h rename L1Trigger/TrackFindingTracklet/interface/{DRin.h => TrackMultiplexer.h} (64%) create mode 100644 L1Trigger/TrackFindingTracklet/interface/TripletEngineUnit.h delete mode 100644 L1Trigger/TrackFindingTracklet/plugins/ProducerDRin.cc create mode 100644 L1Trigger/TrackFindingTracklet/plugins/ProducerDataFormats.cc create mode 100644 L1Trigger/TrackFindingTracklet/plugins/ProducerKF.cc delete mode 100644 L1Trigger/TrackFindingTracklet/plugins/ProducerKFin.cc delete mode 100644 L1Trigger/TrackFindingTracklet/plugins/ProducerKFout.cc delete mode 100644 L1Trigger/TrackFindingTracklet/plugins/ProducerTBout.cc create mode 100644 L1Trigger/TrackFindingTracklet/plugins/ProducerTFP.cc create mode 100644 L1Trigger/TrackFindingTracklet/plugins/ProducerTM.cc create mode 100644 L1Trigger/TrackFindingTracklet/python/DataFormats_cff.py create mode 100644 L1Trigger/TrackFindingTracklet/python/KalmanFilterFormats_cfi.py delete mode 100644 L1Trigger/TrackFindingTracklet/src/DR.cc delete mode 100644 L1Trigger/TrackFindingTracklet/src/DRin.cc create mode 100644 L1Trigger/TrackFindingTracklet/src/DataFormats.cc create mode 100644 L1Trigger/TrackFindingTracklet/src/DuplicateRemoval.cc create mode 100644 L1Trigger/TrackFindingTracklet/src/ES_DataFormats.cc delete mode 100644 L1Trigger/TrackFindingTracklet/src/KFin.cc create mode 100644 L1Trigger/TrackFindingTracklet/src/KalmanFilter.cc create mode 100644 L1Trigger/TrackFindingTracklet/src/KalmanFilterFormats.cc create mode 100644 L1Trigger/TrackFindingTracklet/src/State.cc create mode 100644 L1Trigger/TrackFindingTracklet/src/TrackFindingProcessor.cc create mode 100644 L1Trigger/TrackFindingTracklet/src/TrackMultiplexer.cc create mode 100644 L1Trigger/TrackFindingTracklet/src/TripletEngineUnit.cc create mode 100644 L1Trigger/TrackFindingTracklet/test/AnalyzerKF.cc delete mode 100644 L1Trigger/TrackFindingTracklet/test/AnalyzerTBout.cc rename L1Trigger/TrackFindingTracklet/test/{AnalyzerDRin.cc => AnalyzerTM.cc} (61%) delete mode 100644 L1Trigger/TrackTrigger/interface/L1TrackQuality.h delete mode 100644 L1Trigger/TrackTrigger/python/ProducerSetup_cff.py delete mode 100644 L1Trigger/TrackTrigger/python/ProducerSetup_cfi.py create mode 100644 L1Trigger/TrackTrigger/python/Setup_cff.py create mode 100644 L1Trigger/TrackTrigger/python/Setup_cfi.py delete mode 100644 L1Trigger/TrackTrigger/python/TrackQualityParams_cfi.py delete mode 100644 L1Trigger/TrackTrigger/src/L1TrackQuality.cc create mode 100644 L1Trigger/TrackTrigger/test/CleanRelVal_cfg.py rename L1Trigger/TrackerDTC/plugins/{ProducerED.cc => ProducerDTC.cc} (56%) rename L1Trigger/TrackerDTC/python/{ProducerED_cff.py => DTC_cff.py} (51%) rename L1Trigger/TrackerDTC/python/{ProducerED_cfi.py => DTC_cfi.py} (77%) create mode 100644 L1Trigger/TrackerDTC/python/LayerEncoding_cff.py delete mode 100644 L1Trigger/TrackerDTC/python/ProducerLayerEncoding_cff.py delete mode 100644 L1Trigger/TrackerDTC/python/ProducerLayerEncoding_cfi.py create mode 100644 L1Trigger/TrackerTFP/interface/CleanTrackBuilder.h create mode 100644 L1Trigger/TrackerTFP/interface/DuplicateRemoval.h delete mode 100644 L1Trigger/TrackerTFP/interface/KalmanFilterFormatsRcd.h delete mode 100644 L1Trigger/TrackerTFP/interface/MiniHoughTransform.h create mode 100644 L1Trigger/TrackerTFP/interface/TrackFindingProcessor.h create mode 100644 L1Trigger/TrackerTFP/interface/TrackQuality.h create mode 100644 L1Trigger/TrackerTFP/interface/TrackQualityRcd.h delete mode 100644 L1Trigger/TrackerTFP/interface/ZHoughTransform.h create mode 100644 L1Trigger/TrackerTFP/plugins/ProducerCTB.cc create mode 100644 L1Trigger/TrackerTFP/plugins/ProducerDR.cc rename L1Trigger/TrackerTFP/plugins/{ProducerES.cc => ProducerDataFormats.cc} (67%) delete mode 100644 L1Trigger/TrackerTFP/plugins/ProducerFormatsKF.cc delete mode 100644 L1Trigger/TrackerTFP/plugins/ProducerKFin.cc delete mode 100644 L1Trigger/TrackerTFP/plugins/ProducerMHT.cc create mode 100644 L1Trigger/TrackerTFP/plugins/ProducerPP.cc create mode 100644 L1Trigger/TrackerTFP/plugins/ProducerTFP.cc create mode 100644 L1Trigger/TrackerTFP/plugins/ProducerTQ.cc delete mode 100644 L1Trigger/TrackerTFP/plugins/ProducerTT.cc create mode 100644 L1Trigger/TrackerTFP/plugins/ProducerTrackQuality.cc delete mode 100644 L1Trigger/TrackerTFP/plugins/ProducerZHT.cc delete mode 100644 L1Trigger/TrackerTFP/plugins/ProducerZHTout.cc create mode 100644 L1Trigger/TrackerTFP/python/DataFormats_cff.py delete mode 100644 L1Trigger/TrackerTFP/python/KalmanFilterFormats_cff.py create mode 100644 L1Trigger/TrackerTFP/python/LayerEncoding_cff.py delete mode 100644 L1Trigger/TrackerTFP/python/ProducerES_cff.py delete mode 100644 L1Trigger/TrackerTFP/python/ProducerES_cfi.py delete mode 100644 L1Trigger/TrackerTFP/python/ProducerLayerEncoding_cff.py delete mode 100644 L1Trigger/TrackerTFP/python/ProducerLayerEncoding_cfi.py create mode 100644 L1Trigger/TrackerTFP/python/TrackQuality_cff.py create mode 100644 L1Trigger/TrackerTFP/python/TrackQuality_cfi.py create mode 100644 L1Trigger/TrackerTFP/src/CleanTrackBuilder.cc create mode 100644 L1Trigger/TrackerTFP/src/DuplicateRemoval.cc delete mode 100644 L1Trigger/TrackerTFP/src/ES_KalmanFilterFormats.cc create mode 100644 L1Trigger/TrackerTFP/src/ES_TrackQuality.cc delete mode 100644 L1Trigger/TrackerTFP/src/KalmanFilterFormatsRcd.cc delete mode 100644 L1Trigger/TrackerTFP/src/MiniHoughTransform.cc create mode 100644 L1Trigger/TrackerTFP/src/TrackFindingProcessor.cc create mode 100644 L1Trigger/TrackerTFP/src/TrackQuality.cc delete mode 100644 L1Trigger/TrackerTFP/src/ZHoughTransform.cc rename L1Trigger/TrackerTFP/test/{AnalyzerKFin.cc => AnalyzerCTB.cc} (58%) rename L1Trigger/{TrackFindingTracklet/test/AnalyzerKFin.cc => TrackerTFP/test/AnalyzerDR.cc} (58%) rename L1Trigger/TrackerTFP/test/{AnalyzerZHT.cc => AnalyzerTFP.cc} (51%) rename L1Trigger/TrackerTFP/test/{AnalyzerMHT.cc => AnalyzerTQ.cc} (53%) delete mode 100644 L1Trigger/TrackerTFP/test/AnalyzerTT.cc delete mode 100644 L1Trigger/TrackerTFP/test/ProducerAS.cc 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..c7ceb3cda0b08 100644 --- a/DataFormats/L1TrackTrigger/interface/TTBV.h +++ b/DataFormats/L1TrackTrigger/interface/TTBV.h @@ -20,16 +20,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 +39,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 +70,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 +100,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 +247,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 +286,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 +322,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 +338,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 +372,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/classes_def.xml b/DataFormats/L1TrackTrigger/src/classes_def.xml index 800cf2528af7f..5f23a6744b6a4 100644 --- a/DataFormats/L1TrackTrigger/src/classes_def.xml +++ b/DataFormats/L1TrackTrigger/src/classes_def.xml @@ -51,5 +51,7 @@ + + diff --git a/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker.cc b/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker.cc index a90b8f1d4f9f1..b32a89ed18038 100644 --- a/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker.cc +++ b/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker.cc @@ -2302,7 +2302,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(); @@ -2365,7 +2365,7 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even this_l1track++; } //end track loop - } //end if SaveAllTracks + } //end if SaveAllTracks // ---------------------------------------------------------------------------------------------- // loop over (extended) L1 tracks @@ -2579,7 +2579,7 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even m_trkExt_selected_associated_emulation_foretmiss_index->push_back(this_l1track); this_l1track++; } //end track loop - } //end if SaveAllTracks (displaced) + } //end if SaveAllTracks (displaced) // ---------------------------------------------------------------------------------------------- // loop over tracking particles @@ -2829,7 +2829,7 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even } } // end loop over matched L1 tracks - } // end has at least 1 matched L1 track + } // end has at least 1 matched L1 track // ---------------------------------------------------------------------------------------------- float tmp_matchtrk_pt = -999; @@ -3000,7 +3000,7 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even } } // end loop over matched L1 tracks - } // end has at least 1 matched L1 track + } // end has at least 1 matched L1 track // ---------------------------------------------------------------------------------------------- float tmp_matchtrkExt_pt = -999; diff --git a/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker_cfg.py b/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker_cfg.py index 0ad414a072c7b..564c5b4caf3d7 100644 --- a/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker_cfg.py +++ b/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker_cfg.py @@ -80,8 +80,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..530d67aa6eed5 100644 --- a/L1Trigger/TrackFindingTMTT/interface/L1track3D.h +++ b/L1Trigger/TrackFindingTMTT/interface/L1track3D.h @@ -72,6 +72,35 @@ 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_(stubs), + stubsConst_(std::vector()), + bestStubs_(std::unordered_set()), + 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), + matchedStubs_(std::vector()), + 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..7b5d5572dfe11 100644 --- a/L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h +++ b/L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h @@ -22,28 +22,26 @@ namespace trklet { ChannelAssignment() {} ChannelAssignment(const edm::ParameterSet& 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_; } + // + 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 +64,26 @@ 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_; + // TM parameter + edm::ParameterSet pSetTM_; + // + 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 + int tmWidthStubId_; + // + int tmWidthCot_; + // DR parameter edm::ParameterSet pSetDR_; // 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 +104,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..24a6e7ca2d1b4 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/DataFormats.h @@ -0,0 +1,492 @@ +#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/DataFormatsRcd.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() {} + ~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_; + }; + + // class representing format of a specific variable + template + class Format : public DataFormat { + public: + Format(const ChannelAssignment* ca); + ~Format() {} + }; + + template <> + Format::Format(const ChannelAssignment* ca); + template <> + Format::Format(const ChannelAssignment* ca); + template <> + Format::Format(const ChannelAssignment* ca); + template <> + Format::Format(const ChannelAssignment* ca); + + template <> + Format::Format(const ChannelAssignment* ca); + template <> + Format::Format(const ChannelAssignment* ca); + template <> + Format::Format(const ChannelAssignment* ca); + template <> + Format::Format(const ChannelAssignment* ca); + + template <> + Format::Format(const ChannelAssignment* ca); + template <> + Format::Format(const ChannelAssignment* ca); + template <> + Format::Format(const ChannelAssignment* ca); + template <> + Format::Format(const ChannelAssignment* ca); + template <> + Format::Format(const ChannelAssignment* ca); + template <> + Format::Format(const ChannelAssignment* ca); + + template <> + Format::Format(const ChannelAssignment* ca); + template <> + Format::Format(const ChannelAssignment* ca); + template <> + Format::Format(const ChannelAssignment* ca); + template <> + Format::Format(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() {} + // 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); + } + // configuration during construction + edm::ParameterSet iConfig_; + // 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::DataFormatsRcd); + +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/DataFormatsRcd.h b/L1Trigger/TrackFindingTracklet/interface/DataFormatsRcd.h new file mode 100644 index 0000000000000..25f45d0cdb4ec --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/DataFormatsRcd.h @@ -0,0 +1,17 @@ +#ifndef L1Trigger_TrackFindingTracklet_DataFormatsRcd_h +#define L1Trigger_TrackFindingTracklet_DataFormatsRcd_h + +#include "FWCore/Framework/interface/DependentRecordImplementation.h" +#include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignmentRcd.h" +#include "FWCore/Utilities/interface/mplVector.h" + +namespace trklet { + + typedef edm::mpl::Vector RcdsDataFormats; + + // record of trklet::DataFormats + class DataFormatsRcd : public edm::eventsetup::DependentRecordImplementation {}; + +} // namespace trklet + +#endif \ No newline at end of file diff --git a/L1Trigger/TrackFindingTracklet/interface/DR.h b/L1Trigger/TrackFindingTracklet/interface/DuplicateRemoval.h similarity index 56% rename from L1Trigger/TrackFindingTracklet/interface/DR.h rename to L1Trigger/TrackFindingTracklet/interface/DuplicateRemoval.h index b3956fb0744ec..8fbb22a993603 100644 --- a/L1Trigger/TrackFindingTracklet/interface/DR.h +++ b/L1Trigger/TrackFindingTracklet/interface/DuplicateRemoval.h @@ -1,50 +1,50 @@ -#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 edm::ParameterSet& iConfig, + 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 +56,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 +69,9 @@ 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_; }; } // namespace trklet diff --git a/L1Trigger/TrackFindingTracklet/interface/HitPatternHelper.h b/L1Trigger/TrackFindingTracklet/interface/HitPatternHelper.h index 6b1c81db4f342..20b4b7160c02f 100644 --- a/L1Trigger/TrackFindingTracklet/interface/HitPatternHelper.h +++ b/L1Trigger/TrackFindingTracklet/interface/HitPatternHelper.h @@ -59,11 +59,13 @@ namespace hph { 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::vector layerEncoding(int binEta, int binZT, int binCot) const { + //return layerEncoding_.layerEncoding(binEta, binZT, binCot); + return std::vector(); } - const std::map& layerEncodingMap(int binEta, int binZT, int binCot) const { - return layerEncoding_.layerEncodingMap(binEta, binZT, binCot); + const std::map layerEncodingMap(int binEta, int binZT, int binCot) const { + //return layerEncoding_.layerEncodingMap(binEta, binZT, binCot); + return std::map(); } private: 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..51eaff05a5585 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/KalmanFilter.h @@ -0,0 +1,164 @@ +#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 edm::ParameterSet& iConfig, + 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 + void addLayer(); + // adds a layer to states to build seeds + void addSeedLayer(); + // Assign next combinatoric (i.e. not first in layer) stub to state + void comb(State*& state); + // apply final cuts + void finalize(); + // best state selection + void accumulator(); + // updates state + void update(State*& state) { use5ParameterFit_ ? update5(state) : update4(state); } + // updates state using 4 paramter fit + void update4(State*& state); + // updates state using 5 parameter fit + void update5(State*& state); + + // true if truncation is enbaled + bool enableTruncation_; + // + bool use5ParameterFit_; + // + bool useSimmulation_; + // + bool useTTStubResiduals_; + // 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_; + }; + +} // namespace trklet + +#endif \ No newline at end of file diff --git a/L1Trigger/TrackFindingTracklet/interface/KalmanFilterFormats.h b/L1Trigger/TrackFindingTracklet/interface/KalmanFilterFormats.h new file mode 100644 index 0000000000000..1fc7c9775da8c --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/KalmanFilterFormats.h @@ -0,0 +1,243 @@ +#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 { + + 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) { return VariableKF(+v + 1); } + + class DataFormatKF { + public: + DataFormatKF(const VariableKF& v, bool twos, const edm::ParameterSet& iConfig); + 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(const edm::ParameterSet& iConfig); + ~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); + void endJob(); + + private: + template + void fillFormats(); + const edm::ParameterSet iConfig_; + const DataFormats* dataFormats_; + std::vector formats_; + }; + + template + class FormatKF : public DataFormatKF { + public: + FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + ~FormatKF() override {} + + private: + void calcRange() { range_ = base_ * pow(2, width_); } + void calcWidth() { width_ = ceil(log2(range_ / base_) - 1.e-11); } + }; + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + +} // namespace trklet + +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/Settings.h b/L1Trigger/TrackFindingTracklet/interface/Settings.h index 6d4abf30d37a7..9675d6ae85dbe 100644 --- a/L1Trigger/TrackFindingTracklet/interface/Settings.h +++ b/L1Trigger/TrackFindingTracklet/interface/Settings.h @@ -158,6 +158,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]; } @@ -666,7 +667,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..029106d7a3bcc --- /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 \ No newline at end of file diff --git a/L1Trigger/TrackFindingTracklet/interface/TrackFindingProcessor.h b/L1Trigger/TrackFindingTracklet/interface/TrackFindingProcessor.h new file mode 100644 index 0000000000000..ef3cde5b97f28 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/TrackFindingProcessor.h @@ -0,0 +1,92 @@ +#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 to format final tfp output and to prodcue final TTTrackCollection + class TrackFindingProcessor { + public: + TrackFindingProcessor(const edm::ParameterSet& iConfig, + 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: + // + static constexpr int partial_width = 32; + // + static constexpr int partial_in = 3; + // + static constexpr int partial_out = 2; + // + typedef std::bitset PartialFrame; + // + typedef std::pair PartialFrameTrack; + // + 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; + // true if truncation is enbaled + bool enableTruncation_; + // 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_; + }; + +} // namespace trklet + +#endif \ No newline at end of file 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..e0641691f6503 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,25 @@ 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 edm::ParameterSet& iConfig, + 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 +37,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 +54,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 +68,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 +91,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 +122,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..6cd0d241241ce 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 @@ -114,6 +115,7 @@ using namespace edm; using namespace std; using namespace tt; using namespace trklet; +using namespace trackerTFP; ////////////////////////////// // // @@ -180,9 +182,6 @@ class L1FPGATrackProducer : public edm::one::EDProducer { bool extended_; bool reduced_; - bool trackQuality_; - std::unique_ptr trackQualityModel_; - std::map> dtclayerdisk; edm::InputTag MCTruthClusterInputTag; @@ -194,26 +193,30 @@ class L1FPGATrackProducer : public edm::one::EDProducer { edm::EDGetTokenT> getTokenTTClusterMCTruth_; edm::EDGetTokenT> getTokenTrackingParticle_; + // ED output token for TTTracks + const EDPutTokenT putTokenTTTracks_; // ED output token for clock and bit accurate tracks - const edm::EDPutTokenT putTokenTracks_; + 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_; + EDPutTokenT putTokenStubs_; + + // helper class to store Track Trigger configuration + const Setup* setup_ = nullptr; + // helper class to store Tracklet specific configuration + const ChannelAssignment* channelAssignment_ = nullptr; + // helper class to determine track quality + const 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 esGetTokenHPH_; + const ESGetToken esGetTokenBfield_; + const ESGetToken esGetTokenTGeom_; + const ESGetToken esGetTokenTTopo_; + const ESGetToken esGetTokenSetup_; + const ESGetToken esGetTokenChannelAssignment_; + const ESGetToken esGetTokenTrackQuality_; + const ESGetToken esGetTokenHPH_; /// ///////////////// /// /// MANDATORY METHODS /// @@ -236,23 +239,26 @@ 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()), + esGetTokenSetup_(esConsumes()), + esGetTokenChannelAssignment_(esConsumes()), + esGetTokenTrackQuality_(esConsumes()), esGetTokenHPH_(esConsumes()) { if (readMoreMcTruth_) { getTokenTTClusterMCTruth_ = consumes>(MCTruthClusterInputTag); getTokenTrackingParticle_ = consumes>(TrackingParticleInputTag); } - - produces>>("Level1TTTracks").setBranchAlias("Level1TTTracks"); + const string& branchStubs = iConfig.getParameter("BranchStubs"); + const 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); asciiEventOutName_ = iConfig.getUntrackedParameter("asciiFileName", ""); @@ -271,10 +277,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 // -------------------------------------------------------------------------------- @@ -323,11 +325,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 +357,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_); } @@ -748,7 +748,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,50 +761,57 @@ 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 OrphanHandle oh = iEvent.emplace(putTokenTTTracks_, 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); + int iTrk(0); + StreamsTrack 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()); + 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 vector& tracks = streamsTrackRaw[channel]; + 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 Frame bitsTrk(tracks[frame]); + if (bitsTrk.none()) { + streamTrack.emplace_back(FrameTrack()); + for (int layer = 0; layer < numLayers; layer++) + streamsStub[offsetOut + layer].emplace_back(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); + StreamStub stubs(numLayers, FrameStub()); + for (int layer = 0; layer < numLayers; layer++) { + const 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] = FrameStub(ttStubRef, stub.dataBits()); } + int layer(0); + for (const FrameStub& fs : stubs) + streamsStub[offsetOut + layer++].push_back(fs); } } - - iEvent.emplace(putTokenTracks_, std::move(streamsTrack)); - iEvent.emplace(putTokenStubs_, std::move(streamsStub)); + iEvent.emplace(putTokenTracks_, move(streamsTrack)); + iEvent.emplace(putTokenStubs_, move(streamsStub)); } /// End of produce() diff --git a/L1Trigger/TrackFindingTracklet/plugins/ProducerDR.cc b/L1Trigger/TrackFindingTracklet/plugins/ProducerDR.cc index 1c8055c022282..5df86920d3ad0 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 @@ -25,13 +26,14 @@ using namespace std; using namespace edm; -using namespace trackerTFP; using namespace tt; +using namespace trackerTFP; 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 */ @@ -49,13 +51,13 @@ namespace trklet { // ED input token of Stubs EDGetTokenT edGetTokenStubs_; // ED output token for stubs - EDPutTokenT edPutTokenAcceptedStubs_; - EDPutTokenT edPutTokenLostStubs_; + EDPutTokenT edPutTokenStubs_; // ED output token for tracks - EDPutTokenT edPutTokenAcceptedTracks_; - EDPutTokenT edPutTokenLostTracks_; + EDPutTokenT edPutTokenTracks_; // Setup token ESGetToken esGetTokenSetup_; + // LayerEncoding token + ESGetToken esGetTokenLayerEncoding_; // DataFormats token ESGetToken esGetTokenDataFormats_; // ChannelAssignment token @@ -64,6 +66,8 @@ namespace trklet { ParameterSet iConfig_; // helper class to store configurations const Setup* setup_ = nullptr; + // helper class to encode layer + const LayerEncoding* layerEncoding_ = nullptr; // helper class to extract structured data from tt::Frames const DataFormats* dataFormats_ = nullptr; // helper class to assign tracks to channel @@ -71,20 +75,17 @@ namespace trklet { }; 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"); + const string& label = iConfig.getParameter("InputLabelDR"); + const string& branchStubs = iConfig.getParameter("BranchStubs"); + const 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(InputTag(label, branchTracks)); + edGetTokenStubs_ = consumes(InputTag(label, branchStubs)); + edPutTokenTracks_ = produces(branchTracks); + edPutTokenStubs_ = produces(branchStubs); // book ES products esGetTokenSetup_ = esConsumes(); + esGetTokenLayerEncoding_ = esConsumes(); esGetTokenDataFormats_ = esConsumes(); esGetTokenChannelAssignment_ = esConsumes(); } @@ -92,11 +93,8 @@ namespace trklet { void ProducerDR::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 encode layer + layerEncoding_ = &iSetup.getData(esGetTokenLayerEncoding_); // helper class to extract structured data from tt::Frames dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); // helper class to assign tracks to channel @@ -105,34 +103,28 @@ namespace trklet { void ProducerDR::produce(Event& iEvent, const EventSetup& iSetup) { // empty DR products - const int numStreamsTracks = channelAssignment_->numNodesDR() * setup_->numRegions(); + const int numStreamsTracks = setup_->numRegions(); const int numStreamsStubs = numStreamsTracks * setup_->numLayers(); - StreamsStub acceptedStubs(numStreamsStubs); - StreamsTrack acceptedTracks(numStreamsTracks); - StreamsStub lostStubs(numStreamsStubs); - StreamsTrack lostTracks(numStreamsTracks); + StreamsStub streamsStub(numStreamsStubs); + StreamsTrack streamsTrack(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 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); - } + 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 + DuplicateRemoval dr(iConfig_, 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_, move(streamsStub)); + iEvent.emplace(edPutTokenTracks_, 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..dbf9d104e4b46 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/plugins/ProducerDataFormats.cc @@ -0,0 +1,46 @@ +#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 + +using namespace std; +using namespace edm; +using namespace tt; + +namespace trklet { + + /*! \class trklet::ProducerDataFormats + * \brief Class to produce setup of Hybrid emulator data formats + * \author Thomas Schuh + * \date 2024, Sep + */ + class ProducerDataFormats : public ESProducer { + public: + ProducerDataFormats(const ParameterSet& iConfig); + ~ProducerDataFormats() override {} + unique_ptr produce(const DataFormatsRcd& rcd); + + private: + const ParameterSet iConfig_; + ESGetToken esGetToken_; + }; + + ProducerDataFormats::ProducerDataFormats(const ParameterSet& iConfig) { + auto cc = setWhatProduced(this); + esGetToken_ = cc.consumes(); + } + + unique_ptr ProducerDataFormats::produce(const DataFormatsRcd& rcd) { + const ChannelAssignment* ca = &rcd.get(esGetToken_); + return make_unique(ca); + } + +} // namespace trklet + +DEFINE_FWK_EVENTSETUP_MODULE(trklet::ProducerDataFormats); \ No newline at end of file diff --git a/L1Trigger/TrackFindingTracklet/plugins/ProducerKF.cc b/L1Trigger/TrackFindingTracklet/plugins/ProducerKF.cc new file mode 100644 index 0000000000000..dc21db1ec1ef6 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/plugins/ProducerKF.cc @@ -0,0 +1,178 @@ +#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 + +using namespace std; +using namespace edm; +using namespace tt; +using namespace tmtt; + +namespace trklet { + + /*! \class trklet::ProducerKF + * \brief L1TrackTrigger Kamlan Filter emulator + * \author Thomas Schuh + * \date 2020, July + */ + class ProducerKF : public stream::EDProducer<> { + public: + explicit ProducerKF(const ParameterSet&); + ~ProducerKF() override {} + + private: + void beginRun(const Run&, const EventSetup&) override; + void produce(Event&, const EventSetup&) override; + void endStream() override { + if (printDebug_) + kalmanFilterFormats_.endJob(); + } + // ED input token of sf stubs and tracks + EDGetTokenT edGetTokenStubs_; + EDGetTokenT edGetTokenTracks_; + // ED output token for accepted stubs and tracks + EDPutTokenT edPutTokenTTTracks_; + EDPutTokenT edPutTokenStubs_; + EDPutTokenT edPutTokenTracks_; + // ED output token for number of accepted and lost States + EDPutTokenT edPutTokenNumStatesAccepted_; + EDPutTokenT edPutTokenNumStatesTruncated_; + // 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; + // provides dataformats of Kalman filter internals + KalmanFilterFormats kalmanFilterFormats_; + // + Settings settings_; + // + KFParamsComb tmtt4_; + // + KFParamsComb tmtt5_; + // + KFParamsComb* tmtt_; + // print end job internal unused MSB + bool printDebug_; + // + bool use5ParameterFit_; + }; + + ProducerKF::ProducerKF(const ParameterSet& iConfig) + : iConfig_(iConfig), + kalmanFilterFormats_(iConfig), + settings_(iConfig), + tmtt4_(&settings_, 4, "KF5ParamsComb"), + tmtt5_(&settings_, 5, "KF4ParamsComb"), + tmtt_(&tmtt4_) { + printDebug_ = iConfig.getParameter("PrintKFDebug"); + use5ParameterFit_ = iConfig.getParameter("Use5ParameterFit"); + if (use5ParameterFit_) + tmtt_ = &tmtt5_; + const string& label = iConfig.getParameter("InputLabelKF"); + const string& branchStubs = iConfig.getParameter("BranchStubs"); + const string& branchTracks = iConfig.getParameter("BranchTracks"); + const string& branchTruncated = iConfig.getParameter("BranchTruncated"); + // book in- and output ED products + edGetTokenStubs_ = consumes(InputTag(label, branchStubs)); + edGetTokenTracks_ = consumes(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::beginRun(const Run& iRun, 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_); + // provides dataformats of Kalman filter internals + kalmanFilterFormats_.consume(dataFormats_); + settings_.setMagneticField(setup_->bField()); + } + + void ProducerKF::produce(Event& iEvent, const EventSetup& iSetup) { + auto valid = [](int sum, const FrameTrack& f) { return sum += (f.first.isNull() ? 0 : 1); }; + static const int numRegions = setup_->numRegions(); + static const int numLayers = setup_->numLayers(); + // empty KF products + StreamsStub streamsStub(numRegions * numLayers); + StreamsTrack streamsTrack(numRegions); + int numStatesAccepted(0); + int numStatesTruncated(0); + // read in DR Product and produce KF product + Handle handleStubs; + iEvent.getByToken(edGetTokenStubs_, handleStubs); + const StreamsStub& stubs = *handleStubs; + Handle handleTracks; + iEvent.getByToken(edGetTokenTracks_, handleTracks); + const StreamsTrack& tracks = *handleTracks; + // prep TTTracks + TTTracks ttTracks; + vector ttTrackRefs; + if (use5ParameterFit_) { + int nTracks(0); + for (const StreamTrack& stream : tracks) + nTracks += accumulate(stream.begin(), stream.end(), 0, valid); + ttTracks.reserve(nTracks); + ttTrackRefs.reserve(nTracks); + for (const StreamTrack& stream : tracks) + for (const 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(iConfig_, 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 (use5ParameterFit_) { + // store ttTracks + const OrphanHandle oh = iEvent.emplace(edPutTokenTTTracks_, move(ttTracks)); + // replace ttTrackRefs in track streams + int iTrk(0); + for (StreamTrack& stream : streamsTrack) + for (FrameTrack& frame : stream) + if (frame.first.isNonnull()) + frame.first = TTTrackRef(oh, iTrk++); + } + // store products + iEvent.emplace(edPutTokenStubs_, move(streamsStub)); + iEvent.emplace(edPutTokenTracks_, 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..3e76db01a7a1e --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/plugins/ProducerTFP.cc @@ -0,0 +1,125 @@ +#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 + +using namespace std; +using namespace edm; +using namespace tt; +using namespace trackerTFP; + +namespace trklet { + + /*! \class trklet::ProducerTFP + * \brief L1TrackTrigger final TFP output formatter + * \author Thomas Schuh + * \date 2023, June + */ + class ProducerTFP : public stream::EDProducer<> { + public: + explicit ProducerTFP(const ParameterSet&); + ~ProducerTFP() override {} + + private: + void beginRun(const Run&, const EventSetup&) override; + void produce(Event&, const EventSetup&) override; + void endStream() override {} + // ED input token of stubs and tracks + EDGetTokenT edGetTokenTracks_; + EDGetTokenT edGetTokenTracksAdd_; + EDGetTokenT edGetTokenStubs_; + // ED output token for accepted stubs and tracks + EDPutTokenT edPutTokenTTTracks_; + EDPutTokenT edPutTokenTracks_; + // Setup token + ESGetToken esGetTokenSetup_; + // DataFormats token + ESGetToken esGetTokenDataFormats_; + // TrackQuality token + ESGetToken esGetTokenTrackQuality_; + // 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 determine track quality + const TrackQuality* trackQuality_ = nullptr; + }; + + ProducerTFP::ProducerTFP(const ParameterSet& iConfig) : iConfig_(iConfig) { + const string& labelTracks = iConfig.getParameter("InputLabelTFP"); + const string& labelStubs = iConfig.getParameter("InputLabelTQ"); + const string& branchTracks = iConfig.getParameter("BranchTracks"); + const string& branchTTTracks = iConfig.getParameter("BranchTTTracks"); + const string& branchStubs = iConfig.getParameter("BranchStubs"); + // book in- and output ED products + edGetTokenTracks_ = consumes(InputTag(labelTracks, branchTracks)); + edGetTokenTracksAdd_ = consumes(InputTag(labelTracks, branchTracks)); + edGetTokenStubs_ = consumes(InputTag(labelStubs, branchStubs)); + edPutTokenTTTracks_ = produces(branchTTTracks); + edPutTokenTracks_ = produces(branchTracks); + // book ES products + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + esGetTokenTrackQuality_ = esConsumes(); + } + + void ProducerTFP::beginRun(const Run& iRun, 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 determine track quality + trackQuality_ = &iSetup.getData(esGetTokenTrackQuality_); + } + + void ProducerTFP::produce(Event& iEvent, const EventSetup& iSetup) { + // empty TFP products + TTTracks ttTracks; + StreamsTrack streamsTrack(setup_->numRegions() * setup_->tfpNumChannel()); + // read in TQ Products + Handle handleTracks; + iEvent.getByToken(edGetTokenTracks_, handleTracks); + Handle handleTracksAdd; + iEvent.getByToken(edGetTokenTracksAdd_, handleTracksAdd); + Handle handleStubs; + iEvent.getByToken(edGetTokenStubs_, handleStubs); + // produce TTTracks + TrackFindingProcessor tfp(iConfig_, setup_, dataFormats_, trackQuality_); + tfp.produce(*handleTracks, *handleTracksAdd, *handleStubs, ttTracks, streamsTrack); + // put TTTRacks and produce TTTRackRefs + const int nTrks = ttTracks.size(); + const OrphanHandle oh = iEvent.emplace(edPutTokenTTTracks_, move(ttTracks)); + 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_, move(streamsTrack)); + } + +} // namespace trklet + +DEFINE_FWK_MODULE(trklet::ProducerTFP); \ No newline at end of file diff --git a/L1Trigger/TrackFindingTracklet/plugins/ProducerTM.cc b/L1Trigger/TrackFindingTracklet/plugins/ProducerTM.cc new file mode 100644 index 0000000000000..0a9d79bac3b27 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/plugins/ProducerTM.cc @@ -0,0 +1,127 @@ +#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 + +using namespace std; +using namespace edm; +using namespace tt; + +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 stream::EDProducer<> { + public: + explicit ProducerTM(const ParameterSet&); + ~ProducerTM() 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 edPutTokenStubs_; + // ED output token for tracks + EDPutTokenT edPutTokenTracks_; + // 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 + const ChannelAssignment* channelAssignment_ = nullptr; + // helper class to store tracklet configurations + Settings settings_; + }; + + ProducerTM::ProducerTM(const ParameterSet& iConfig) : iConfig_(iConfig) { + const string& label = iConfig.getParameter("InputLabelTM"); + const string& branchStubs = iConfig.getParameter("BranchStubs"); + const string& branchTracks = iConfig.getParameter("BranchTracks"); + // book in- and output ED products + edGetTokenTracks_ = consumes(InputTag(label, branchTracks)); + edGetTokenStubs_ = consumes(InputTag(label, branchStubs)); + edPutTokenStubs_ = produces(branchStubs); + edPutTokenTracks_ = produces(branchTracks); + // book ES products + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + esGetTokenChannelAssignment_ = esConsumes(); + } + + void ProducerTM::beginRun(const Run& iRun, 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 tracks to channel + channelAssignment_ = &iSetup.getData(esGetTokenChannelAssignment_); + } + + void ProducerTM::produce(Event& iEvent, const EventSetup& iSetup) { + // empty TM products + const int numStreamsTracks = setup_->numRegions(); + const int numStreamsStubs = numStreamsTracks * channelAssignment_->tmNumLayers(); + StreamsStub streamsStub(numStreamsStubs); + StreamsTrack streamsTrack(numStreamsTracks); + // read in TBout Product and produce TM product + 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 + TrackMultiplexer tm(iConfig_, 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_, move(streamsTrack)); + iEvent.emplace(edPutTokenStubs_, 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..6324e4684a24e 100644 --- a/L1Trigger/TrackFindingTracklet/python/Analyzer_cff.py +++ b/L1Trigger/TrackFindingTracklet/python/Analyzer_cff.py @@ -1,12 +1,13 @@ +# 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 -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..921055a241081 100644 --- a/L1Trigger/TrackFindingTracklet/python/Customize_cff.py +++ b/L1Trigger/TrackFindingTracklet/python/Customize_cff.py @@ -1,13 +1,12 @@ -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.TrackTriggerSetup.TrackFinding.MaxEta = 2.5 + process.TrackTriggerSetup.GeometricProcessor.ChosenRofZ = 57.76 process.l1tTTTracksFromTrackletEmulation.RemovalType = "" process.l1tTTTracksFromTrackletEmulation.DoMultipleMatches = False process.l1tTTTracksFromTrackletEmulation.StoreTrackBuilderOutput = True @@ -15,6 +14,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 +30,44 @@ 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): + process.ProducerKF.Hybrid = True + process.ProducerKF.DeadModuleOpts.KillScenario = 0 + process.ProducerKF.DeadModuleOpts.KillRecover = False + process.ProducerKF.HTArraySpecRphi.HoughMinPt = 2. + process.ProducerKF.TrackDigi.KF_skipTrackDigi = True + process.ProducerKF.StubDigitize.EnableDigitize = False + process.ProducerKF.GeometricProc.UseApproxB = True + process.ProducerKF.GeometricProc.BApprox_gradient = 0.886454 + process.ProducerKF.GeometricProc.BApprox_intercept = 0.504148 + process.ProducerKF.PhiSectors.NumPhiSectors = 9 + process.ProducerKF.PhiSectors.NumPhiNonants = 9 + process.ProducerKF.PhiSectors.ChosenRofPhi = 55. + 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] + process.ProducerKF.EtaSectors.ChosenRofZ = 50.0 + process.ProducerKF.TrackFitSettings.KalmanMinNumStubs = 4 + process.ProducerKF.TrackFitSettings.KalmanMaxNumStubs = 6 + process.ProducerKF.TrackFitSettings.KalmanMaxSkipLayersHard = 1 + process.ProducerKF.TrackFitSettings.KalmanMaxSkipLayersEasy = 2 + process.ProducerKF.TrackFitSettings.KalmanMaxStubsEasy = 10 + process.ProducerKF.TrackFitSettings.KalmanMaxStubsPerLayer = 4 + process.ProducerKF.TrackFitSettings.KalmanMultiScattTerm = 0.00075 + process.ProducerKF.TrackFitSettings.KalmanChi2RphiScale = 8 + process.ProducerKF.TrackFitSettings.KFUseMaybeLayers = True + process.ProducerKF.TrackFitSettings.KalmanRemove2PScut = True + process.ProducerKF.TrackFitSettings.KFLayerVsPtToler = [999., 999., 0.1, 0.1, 0.05, 0.05, 0.05] + 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.] + process.ProducerKF.TrackFitSettings.KFLayerVsChiSq5 = [999., 999., 10., 30., 80., 120., 160.] + process.ProducerKF.TrackFitSettings.KFLayerVsChiSq4 = [999., 999., 10., 30., 80., 120., 160.] + process.ProducerKF.TrackFitSettings.KalmanAddBeamConstr = False + process.ProducerKF.TrackFitSettings.KalmanHOfw = False + process.ProducerKF.TrackFitSettings.KalmanHOtilted = True + process.ProducerKF.TrackFitSettings.KalmanHOprojZcorr = 1 + process.ProducerKF.TrackFitSettings.KalmanHOalpha = 0 + process.ProducerKF.TrackFitSettings.KalmanHOhelixExp = True + process.ProducerKF.TrackFitSettings.KalmanDebugLevel = 0 \ No newline at end of file diff --git a/L1Trigger/TrackFindingTracklet/python/DataFormats_cff.py b/L1Trigger/TrackFindingTracklet/python/DataFormats_cff.py new file mode 100644 index 0000000000000..5e7416487b67c --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/python/DataFormats_cff.py @@ -0,0 +1,11 @@ +# ESProducer to provide and calculate and provide dataformats used by Hybrid emulator + +import FWCore.ParameterSet.Config as cms + +HybridDataFormats = cms.ESProducer("trklet::ProducerDataFormats") + +fakeHybridDataFormatsSource = cms.ESSource("EmptyESSource", + recordName = cms.string('trklet::DataFormatsRcd'), + iovIsRunNotTime = cms.bool(True), + firstValid = cms.vuint32(1) +) \ No newline at end of file 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..d22bbe5ffde91 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/python/KalmanFilterFormats_cfi.py @@ -0,0 +1,66 @@ +# 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 + +HybridKalmanFilterFormats_params = cms.PSet ( + + EnableIntegerEmulation = cms.bool( True ), + + WidthR00 = cms.int32( 20 ), + WidthR11 = cms.int32( 20 ), + + WidthC00 = cms.int32( 20 ), + WidthC01 = cms.int32( 20 ), + WidthC11 = cms.int32( 20 ), + WidthC22 = cms.int32( 20 ), + WidthC23 = cms.int32( 20 ), + WidthC33 = cms.int32( 20 ), + + BaseShiftx0 = cms.int32( -1 ), + BaseShiftx1 = cms.int32( -8 ), + 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 ), + + 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 ), + + BaseShiftr02 = cms.int32( -2 ), + BaseShiftr12 = cms.int32( 10 ), + BaseShiftchi20 = cms.int32( -10 ), + BaseShiftchi21 = cms.int32( -10 ) + +) \ No newline at end of file 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..234b327985d6e 100644 --- a/L1Trigger/TrackFindingTracklet/python/Producer_cfi.py +++ b/L1Trigger/TrackFindingTracklet/python/Producer_cfi.py @@ -1,26 +1,24 @@ +# 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" ), # + EnableTruncation = cms.bool ( True ), # enable emulation of truncation for TM, DR, KF, TQ and TFP + PrintKFDebug = cms.bool ( False ), # print end job internal unused MSB + 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 ), # + Use5ParameterFit = cms.bool ( False ), # double precision simulation of 5 parameter fit instead of bit accurate emulation of 4 parameter fit + UseKFsimmulation = cms.bool ( False ) # simulate KF instead of emulate ) 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..57c66a53e1278 100644 --- a/L1Trigger/TrackFindingTracklet/src/ChannelAssignment.cc +++ b/L1Trigger/TrackFindingTracklet/src/ChannelAssignment.cc @@ -16,21 +16,21 @@ namespace trklet { ChannelAssignment::ChannelAssignment(const edm::ParameterSet& 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")), + pSetTM_(iConfig.getParameter("TM")), + tmMuxOrder_((pSetTM_.getParameter>("MuxOrder"))), + tmNumLayers_((pSetTM_.getParameter("NumLayers"))), + tmWidthStubId_(pSetTM_.getParameter("WidthStubId")), + tmWidthCot_(pSetTM_.getParameter("WidthCot")), pSetDR_(iConfig.getParameter("DR")), numComparisonModules_(pSetDR_.getParameter("NumComparisonModules")), minIdenticalStubs_(pSetDR_.getParameter("MinIdenticalStubs")), - numNodesDR_(2 * (ptBoundaries_.size() + 1)), seedTypeNames_(iConfig.getParameter>("SeedTypes")), numSeedTypes_(seedTypeNames_.size()), numChannelsTrack_(numSeedTypes_), channelEncoding_(iConfig.getParameter>("IRChannelsIn")) { + tmMuxOrderInt_.reserve(tmMuxOrder_.size()); + for (const string& s : tmMuxOrder_) + tmMuxOrderInt_.push_back(distance(tmMuxOrder_.begin(), find(tmMuxOrder_.begin(), tmMuxOrder_.end(), s))); const ParameterSet& pSetSeedTypesSeedLayers = iConfig.getParameter("SeedTypesSeedLayers"); const ParameterSet& pSetSeedTypesProjectionLayers = iConfig.getParameter("SeedTypesProjectionLayers"); seedTypesSeedLayers_.reserve(numSeedTypes_); @@ -186,22 +186,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..4a0b091944474 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/DataFormats.cc @@ -0,0 +1,227 @@ +#include "L1Trigger/TrackFindingTracklet/interface/DataFormats.h" +#include "DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace edm; +using namespace tt; + +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(Format(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 <> + Format::Format(const ChannelAssignment* ca) : DataFormat(true) { + width_ = TTTrack_TrackWord::TrackBitWidths::kRinvSize; + range_ = -2. * TTTrack_TrackWord::minRinv; + base_ = range_ * pow(2, -width_); + } + template <> + Format::Format(const ChannelAssignment* ca) : DataFormat(true) { + width_ = TTTrack_TrackWord::TrackBitWidths::kPhiSize; + range_ = -2. * TTTrack_TrackWord::minPhi0; + base_ = range_ * pow(2, -width_); + } + template <> + Format::Format(const ChannelAssignment* ca) : DataFormat(true) { + width_ = TTTrack_TrackWord::TrackBitWidths::kTanlSize; + range_ = -2. * TTTrack_TrackWord::minTanl; + base_ = range_ * pow(2, -width_); + } + template <> + Format::Format(const ChannelAssignment* ca) : DataFormat(true) { + width_ = TTTrack_TrackWord::TrackBitWidths::kZ0Size; + range_ = -2. * TTTrack_TrackWord::minZ0; + base_ = range_ * pow(2, -width_); + } + + template <> + Format::Format(const ChannelAssignment* ca) : DataFormat(true) { + const Setup* s = ca->setup(); + static const double thight = s->htNumBinsInv2R(); + static const double loose = thight + 2; + range_ = 2. * s->invPtToDphi() / s->minPt() * loose / thight; + base_ = range_ / loose; + width_ = ceil(log2(range_ / base_)); + } + template <> + Format::Format(const ChannelAssignment* ca) : DataFormat(true) { + const Setup* s = ca->setup(); + static const double thight = s->gpNumBinsPhiT() * s->htNumBinsPhiT(); + static const double loose = thight + 2 * s->gpNumBinsPhiT(); + range_ = 2. * M_PI / s->numRegions() * loose / thight; + base_ = range_ / loose; + width_ = ceil(log2(range_ / base_)); + } + template <> + Format::Format(const ChannelAssignment* ca) : DataFormat(true) { + const Setup* s = ca->setup(); + static const double thight = s->gpNumBinsZT(); + static const double loose = thight + 2; + range_ = 2. * sinh(s->maxEta()) * s->chosenRofZ() * loose / thight; + base_ = range_ / loose; + width_ = ceil(log2(range_ / base_)); + } + template <> + Format::Format(const ChannelAssignment* ca) : DataFormat(true) { + const Setup* s = ca->setup(); + const Format zT(ca); + range_ = (zT.range() + 2. * s->beamWindowZ()) / s->chosenRofZ(); + base_ = (zT.base() + 2. * s->beamWindowZ()) / s->chosenRofZ(); + } + + template <> + Format::Format(const ChannelAssignment* ca) : DataFormat(false) { + width_ = ca->tmWidthStubId() + 1; + } + template <> + Format::Format(const ChannelAssignment* ca) : DataFormat(true) { + const Setup* s = ca->setup(); + const Format phiT(ca); + const Format inv2R(ca); + range_ = 2. * s->maxRphi(); + base_ = phiT.base() / inv2R.base(); + const int shift = ceil(log2(range_ / base_)) - s->tmttWidthR(); + base_ *= pow(2., shift); + width_ = ceil(log2(range_ / base_)); + } + template <> + Format::Format(const ChannelAssignment* ca) : DataFormat(true) { + const Setup* s = ca->setup(); + const Format phiT(ca); + const Format inv2R(ca); + const double range = s->baseRegion() + s->maxRphi() * inv2R.range(); + range_ = phiT.base() + s->maxRphi() * inv2R.base(); + const int shift = ceil(log2(range / phiT.base())) - s->tmttWidthPhi(); + base_ = phiT.base() * pow(2., shift); + width_ = ceil(log2(range_ / base_)); + } + template <> + Format::Format(const ChannelAssignment* ca) : DataFormat(true) { + const Setup* s = ca->setup(); + const Format zT(ca); + const Format cot(ca); + const double range = 2. * s->halfLength(); + range_ = zT.base() + s->maxRz() * cot.base(); + const int shift = ceil(log2(range / zT.base())) - s->tmttWidthZ(); + base_ = zT.base() * pow(2., shift); + width_ = ceil(log2(range_ / base_)); + } + template <> + Format::Format(const ChannelAssignment* ca) : DataFormat(false) { + const Setup* s = ca->setup(); + const Format phi(ca); + const Format inv2R(ca); + range_ = .5 * s->pitchRowPS() / s->innerRadius() + .25 * (s->pitchCol2S() + s->scattering()) * inv2R.range(); + base_ = phi.base(); + width_ = ceil(log2(range_ / base_)); + } + template <> + Format::Format(const ChannelAssignment* ca) : DataFormat(false) { + const Setup* s = ca->setup(); + const Format z(ca); + range_ = .5 * s->pitchCol2S() * sinh(s->maxEta()); + base_ = z.base(); + width_ = ceil(log2(range_ / base_)); + } + + template <> + Format::Format(const ChannelAssignment* ca) : DataFormat(true) { + const Format tfp(ca); + const Format tm(ca); + range_ = tm.range(); + base_ = tm.base() * pow(2., floor(log2(.5 * tfp.base() / tm.base()))); + width_ = ceil(log2(range_ / base_)); + } + template <> + Format::Format(const ChannelAssignment* ca) : DataFormat(true) { + const Format tfp(ca); + const Format tm(ca); + range_ = tm.range(); + base_ = tm.base() * pow(2., floor(log2(tfp.base() / tm.base()))); + width_ = ceil(log2(range_ / base_)); + } + template <> + Format::Format(const ChannelAssignment* ca) : DataFormat(true) { + const Format tfp(ca); + const Format cot(ca); + const Format z(ca); + const Format r(ca); + range_ = cot.range(); + base_ = z.base() / r.base() * pow(2., floor(log2(tfp.base() / z.base() * r.base()))); + width_ = ceil(log2(range_ / base_)); + } + template <> + Format::Format(const ChannelAssignment* ca) : DataFormat(true) { + const Format tfp(ca); + const Format tm(ca); + range_ = tm.range(); + base_ = tm.base() * pow(2., floor(log2(tfp.base() / tm.base()))); + width_ = ceil(log2(range_ / base_)); + } + +} // namespace trklet diff --git a/L1Trigger/TrackFindingTracklet/src/DuplicateRemoval.cc b/L1Trigger/TrackFindingTracklet/src/DuplicateRemoval.cc new file mode 100644 index 0000000000000..0cebcde1731b1 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/DuplicateRemoval.cc @@ -0,0 +1,183 @@ +#include "L1Trigger/TrackFindingTracklet/interface/DuplicateRemoval.h" + +#include +#include +#include + +using namespace std; +using namespace edm; +using namespace tt; +using namespace trackerTFP; + +namespace trklet { + + DuplicateRemoval::DuplicateRemoval(const ParameterSet& iConfig, + const Setup* setup, + const LayerEncoding* layerEncoding, + const DataFormats* dataFormats, + const ChannelAssignment* channelAssignment, + int region) + : enableTruncation_(iConfig.getParameter("EnableTruncation")), + 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); + } + + // read in and organize input tracks and stubs + void DuplicateRemoval::consume(const StreamsTrack& streamsTrack, const StreamsStub& streamsStub) { + 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 sizeStubs(0); + static const int numLayers = channelAssignment_->tmNumLayers(); + const int offset = region_ * numLayers; + const StreamTrack& streamTrack = streamsTrack[region_]; + input_.reserve(streamTrack.size()); + const int sizeTracks = accumulate(streamTrack.begin(), streamTrack.end(), 0, nonNullTrack); + for (int layer = 0; layer < numLayers; layer++) { + const StreamStub& streamStub = streamsStub[offset + layer]; + sizeStubs += accumulate(streamStub.begin(), streamStub.end(), 0, nonNullStub); + } + tracks_.reserve(sizeTracks); + stubs_.reserve(sizeStubs); + // transform input data into handy structs + for (int frame = 0; frame < (int)streamTrack.size(); frame++) { + const 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 vector& layerEncoding = layerEncoding_->layerEncoding(zT); + vector stubs(numLayers, nullptr); + TTBV hitPattern(0, setup_->numLayers()); + for (int layer = 0; layer < numLayers; layer++) { + const 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 = find(layerEncoding.begin(), layerEncoding.end(), decodedLayerId); + const int encodedLayerId = min((int)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 const DataFormat& dfPhi = dataFormats_->format(Variable::phi, Process::dr); + 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 = dfPhi.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 = dfPhi.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(StreamsTrack& streamsTrack, StreamsStub& streamsStub) { + const int offset = region_ * setup_->numLayers(); + // remove duplicated tracks, no merge of stubs, one stub per layer expected + 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 + 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(FrameTrack()); + for (int layer = 0; layer < setup_->numLayers(); layer++) + streamsStub[offset + layer].emplace_back(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(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..411f1e9f3e36f --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/ES_DataFormats.cc @@ -0,0 +1,6 @@ +#include "FWCore/Utilities/interface/typelookup.h" +#include "L1Trigger/TrackFindingTracklet/interface/DataFormats.h" +#include "L1Trigger/TrackFindingTracklet/interface/DataFormatsRcd.h" + +TYPELOOKUP_DATA_REG(trklet::DataFormats); +TYPELOOKUP_DATA_REG(trklet::DataFormatsRcd); \ No newline at end of file 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..3b475819c0e0f 100644 --- a/L1Trigger/TrackFindingTracklet/src/HitPatternHelper.cc +++ b/L1Trigger/TrackFindingTracklet/src/HitPatternHelper.cc @@ -21,13 +21,12 @@ namespace hph { 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)), + dfcot_(dataFormats_.format(trackerTFP::Variable::cot, trackerTFP::Process::gp)), + dfzT_(dataFormats_.format(trackerTFP::Variable::zT, trackerTFP::Process::gp)), layerEncoding_(layerEncoding), hphDebug_(iConfig.getParameter("hphDebug")), useNewKF_(iConfig.getParameter("useNewKF")), chosenRofZNewKF_(setupTT_.chosenRofZ()), - etaRegionsNewKF_(setupTT_.boundarieEta()), layermap_(), nEtaRegions_(tmtt::KFbase::nEta_ / 2), nKalmanLayers_(tmtt::KFbase::nKFlayer_) { @@ -259,14 +258,16 @@ namespace hph { } int Setup::digiCot(double cot, int binEta) const { - double cotLocal = dfcot_.digi(cot - setupTT_.sectorCot(binEta)); - return dfcot_.toUnsigned(dfcot_.integer(cotLocal)); + //double cotLocal = dfcot_.digi(cot - setupTT_.sectorCot(binEta)); + //return dfcot_.toUnsigned(dfcot_.integer(cotLocal)); + return int(); } 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)); + //double zT = z0 + setupTT_.chosenRofZ() * cot; + //double zTLocal = dfzT_.digi(zT - setupTT_.sectorCot(binEta) * setupTT_.chosenRofZ()); + //return dfzT_.toUnsigned(dfzT_.integer(zTLocal)); + return int(); } int HitPatternHelper::reducedId(int layerId) { 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..8799cdf101f3c --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/KalmanFilter.cc @@ -0,0 +1,718 @@ +#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 + +using namespace std; +using namespace edm; +using namespace tt; +using namespace tmtt; + +namespace trklet { + + KalmanFilter::KalmanFilter(const ParameterSet& iConfig, + const Setup* setup, + const DataFormats* dataFormats, + KalmanFilterFormats* kalmanFilterFormats, + Settings* settings, + KFParamsComb* tmtt, + int region, + TTTracks& ttTracks) + : enableTruncation_(iConfig.getParameter("EnableTruncation")), + use5ParameterFit_(iConfig.getParameter("Use5ParameterFit")), + useSimmulation_(iConfig.getParameter("UseKFsimmulation")), + useTTStubResiduals_(iConfig.getParameter("UseTTStubResiduals")), + setup_(setup), + dataFormats_(dataFormats), + kalmanFilterFormats_(kalmanFilterFormats), + settings_(settings), + tmtt_(tmtt), + region_(region), + ttTracks_(ttTracks), + layer_(0) {} + + // read in and organize input tracks and stubs + void KalmanFilter::consume(const StreamsTrack& streamsTrack, const StreamsStub& streamsStub) { + static const int numLayers = setup_->numLayers(); + const int offset = region_ * numLayers; + const StreamTrack& streamTrack = streamsTrack[region_]; + const int numTracks = accumulate(streamTrack.begin(), streamTrack.end(), 0, [](int sum, const FrameTrack& f) { + return sum += (f.first.isNull() ? 0 : 1); + }); + int numStubs(0); + for (int layer = 0; layer < numLayers; layer++) { + const StreamStub& streamStub = streamsStub[offset + layer]; + numStubs += accumulate(streamStub.begin(), streamStub.end(), 0, [](int sum, const FrameStub& f) { + return sum += (f.first.isNull() ? 0 : 1); + }); + } + tracks_.reserve(numTracks); + stubs_.reserve(numStubs); + int trackId(0); + for (int frame = 0; frame < (int)streamTrack.size(); frame++) { + const FrameTrack& frameTrack = streamTrack[frame]; + if (frameTrack.first.isNull()) { + stream_.push_back(nullptr); + continue; + } + tracks_.emplace_back(frameTrack, dataFormats_); + TrackDR* track = &tracks_.back(); + vector stubs(numLayers, nullptr); + TTBV hitPattern(0, setup_->numLayers()); + for (int layer = 0; layer < numLayers; layer++) { + const 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 (enableTruncation_ && trackId == setup_->kfMaxTracks()) + break; + } + } + + // call old KF + void KalmanFilter::simulate(tt::StreamsStub& streamsStub, tt::StreamsTrack& streamsTrack) { + static vector zTs; + if (zTs.empty()) { + zTs.reserve(settings_->etaRegions().size()); + for (double eta : settings_->etaRegions()) + zTs.emplace_back(sinh(eta) * settings_->chosenRofZ()); + } + finals_.reserve(states_.size()); + for (const State& state : states_) { + TrackDR* trackFound = state.track(); + const TTTrackRef& ttTrackRef = trackFound->frame().first; + const double qOverPt = -trackFound->inv2R() / setup_->invPtToDphi(); + const double phi0 = + 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.; + vector stubs; + vector stubsFound; + stubs.reserve(state.trackPattern().count()); + stubsFound.reserve(state.trackPattern().count()); + const 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; + SensorModule* sensorModule = setup_->sensorModule(ttStubRef); + double r, phi, z; + if (useTTStubResiduals_) { + const GlobalPoint gp = setup_->stubPos(ttStubRef); + r = gp.perp(); + phi = gp.phi(); + z = gp.z(); + } else { + r = stub.r() + setup_->chosenRofPhi(); + phi = deltaPhi(stub.phi() + trackFound->phiT() + stub.r() * trackFound->inv2R() + + region_ * setup_->baseRegion()); + z = stub.z() + trackFound->zT() + (r - setup_->chosenRofZ()) * tanLambda; + } + 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()); + } + 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 L1track3D l1track3D(settings_, stubsFound, qOverPt, phi0, z0, tanLambda, helixD0, iPhiSec, iEtaReg); + const L1fittedTrack trackFitted(tmtt_->fit(l1track3D)); + if (!trackFitted.accepted()) + continue; + 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 = + deltaPhi(trackFitted.phi0() + inv2R * setup_->chosenRofPhi() - region_ * setup_->baseRegion()); + const double cot = trackFitted.tanLambda(); + const double zT = trackFitted.z0() + cot * setup_->chosenRofZ(); + 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; + TTBV hitPattern(0, setup_->numLayers()); + vector stubsKF; + stubsKF.reserve(setup_->numLayers()); + for (tmtt::Stub* stub : trackFitted.stubs()) { + if (!stub) + continue; + const auto it = find_if(stubsState.begin(), stubsState.end(), [stub](Stub* state) { + return state && (stub->ttStubRef() == state->stubDR_.frame().first); + }); + const StubDR& s = (*it)->stubDR_; + 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 = distance(stubsState.begin(), it); + 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); + } + if (hitPattern.count() < setup_->kfMinLayers()) + continue; + 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(StreamsStub& streamsStub, + StreamsTrack& streamsTrack, + int& numAcceptedStates, + int& numLostStates) { + if (useSimmulation_) + return simulate(streamsStub, streamsTrack); + // 5 parameter fit simulation + if (use5ParameterFit_) { + // 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_++) + addSeedLayer(); + // 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 = + accumulate(stream_.begin(), stream_.end(), 0, [](int sum, State* state) { return sum += (state ? 1 : 0); }); + // apply truncation + if (enableTruncation_ && (int)stream_.size() > setup_->numFramesHigh()) + stream_.resize(setup_->numFramesHigh()); + // cycle event, remove gaps + stream_.erase(remove(stream_.begin(), stream_.end(), nullptr), stream_.end()); + // store number of states which got taken into account + numAcceptedStates += (int)stream_.size(); + // store number of states which got not taken into account due to truncation + numLostStates += nStates - (int)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(); + 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()); + } + 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 + vector finals; + finals.reserve(finals_.size()); + transform(finals_.begin(), finals_.end(), back_inserter(finals), [](Track& track) { return &track; }); + // prepare arrival order + vector trackIds; + trackIds.reserve(tracks_.size()); + for (Track* track : finals) { + const int trackId = track->trackId_; + if (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_; }; + 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_; }; + 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 distance(r, l) < 0; + }; + stable_sort(finals.begin(), finals.end(), order); + // keep first state (best due to previous sorts) per track id + const auto it = + 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(StreamsStub& streamsStub, StreamsTrack& streamsTrack) { + const int offset = region_ * setup_->numLayers(); + 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 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() : FrameStub()); + // store d0 in copied TTTracks + if (use5ParameterFit_) { + 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 to build seeds + void KalmanFilter::addSeedLayer() { + // Latency of KF Associator block firmware + static constexpr int latency = 5; + // dynamic state container for clock accurate emulation + deque streamOutput; + // Memory stack used to handle combinatorics + deque stack; + // static delay container + 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; })) { + 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); + } + stream_ = streamOutput; + // Update state with next stub using KF maths + for (State*& state : stream_) + if (state) + state = state->update(states_, layer_); + } + + // adds a layer to states + void KalmanFilter::addLayer() { + // Latency of KF Associator block firmware + static constexpr int latency = 5; + // dynamic state container for clock accurate emulation + deque streamOutput; + // Memory stack used to handle combinatorics + deque stack; + // static delay container + 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; })) { + 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->comb(states_, layer_); + 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_) + if (state && state->hitPattern().pmEncode() == layer_) + 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 = max(0, (int)ceil(log2(R00 / base(VariableKF::R00)))); + const int msb1 = max(0, (int)ceil(log2(R11 / base(VariableKF::R11)))); + const int shift0 = width(VariableKF::R00) - msb0; + const int shift1 = width(VariableKF::R11) - msb1; + const double R00Shifted = R00 * pow(2., shift0); + const double R11Shifted = R11 * 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 * pow(2., shift0), base(VariableKF::S00Shifted)); + const double S01Shifted = digiShifted(S01 * pow(2., shift0), base(VariableKF::S01Shifted)); + const double S12Shifted = digiShifted(S12 * pow(2., shift1), base(VariableKF::S12Shifted)); + const double S13Shifted = digiShifted(S13 * 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(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..b105968dbd8eb --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/KalmanFilterFormats.cc @@ -0,0 +1,588 @@ +#include "L1Trigger/TrackFindingTracklet/interface/KalmanFilterFormats.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace edm; +using namespace tt; + +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() { + const int wName = + strlen(*max_element(variableKFstrs_.begin(), variableKFstrs_.end(), [](const auto& a, const auto& b) { + return strlen(a) < 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() - ceil(log2(r / format(v).base())); + cout << setw(wName) << *next(variableKFstrs_.begin(), +v) << ": "; + cout << setw(3) << (delta == -2147483648 ? "-" : to_string(delta)) << endl; + } + } + + KalmanFilterFormats::KalmanFilterFormats(const ParameterSet& iConfig) : iConfig_(iConfig) { + formats_.reserve(+VariableKF::end); + } + + void KalmanFilterFormats::consume(const DataFormats* dataFormats) { + dataFormats_ = dataFormats; + fillFormats(); + } + + template + void KalmanFilterFormats::fillFormats() { + formats_.emplace_back(FormatKF(dataFormats_, iConfig_)); + if constexpr (++it != VariableKF::end) + fillFormats<++it>(); + } + + DataFormatKF::DataFormatKF(const VariableKF& v, bool twos, const ParameterSet& iConfig) + : v_(v), + twos_(twos), + enableIntegerEmulation_(iConfig.getParameter("EnableIntegerEmulation")), + width_(0), + base_(1.), + range_(0.), + min_(numeric_limits::max()), + abs_(numeric_limits::max()), + max_(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)) { + string v = *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_) << "." << 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 <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::x0, true, 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(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::x1, true, 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(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::x2, true, 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(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::x3, true, 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(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::H00, true, iConfig) { + const DataFormat& tm = dataFormats->format(Variable::r, Process::tm); + base_ = tm.base(); + width_ = tm.width(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::H12, true, iConfig) { + const Setup* setup = dataFormats->setup(); + const DataFormat& tm = dataFormats->format(Variable::r, Process::tm); + base_ = tm.base(); + range_ = 2. * setup->maxRz(); + width_ = ceil(log2(range_ / base_)); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::m0, true, iConfig) { + const DataFormat& tm = dataFormats->format(Variable::phi, Process::tm); + base_ = tm.base(); + width_ = tm.width(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::m1, true, iConfig) { + const DataFormat& tm = dataFormats->format(Variable::z, Process::tm); + base_ = tm.base(); + width_ = tm.width(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::v0, false, iConfig) { + const DataFormat& dPhi = dataFormats->format(Variable::dPhi, Process::tm); + const FormatKF S01(dataFormats, iConfig); + range_ = 4. * dPhi.range() * dPhi.range(); + base_ = S01.base(); + calcWidth(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::v1, false, iConfig) { + const DataFormat& dZ = dataFormats->format(Variable::dZ, Process::tm); + const FormatKF S13(dataFormats, iConfig); + range_ = 4. * dZ.range() * dZ.range(); + base_ = S13.base(); + calcWidth(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::r0, true, 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(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::r1, true, 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(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::S00, true, 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()->widthDSPab(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::S01, true, 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()->widthDSPab(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::S12, true, 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()->widthDSPab(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::S13, true, 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()->widthDSPab(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::S00Shifted, true, iConfig) { + const DataFormat& x0 = dataFormats->format(Variable::inv2R, Process::kf); + const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.getParameter("BaseShiftS00Shifted"); + base_ = pow(2., baseShift) * x0.base() * x1.base(); + width_ = dataFormats->setup()->widthDSPab(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::S01Shifted, true, iConfig) { + const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.getParameter("BaseShiftS01Shifted"); + base_ = pow(2., baseShift) * x1.base() * x1.base(); + width_ = dataFormats->setup()->widthDSPab(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::S12Shifted, true, iConfig) { + const DataFormat& x2 = dataFormats->format(Variable::cot, Process::kf); + const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.getParameter("BaseShiftS12Shifted"); + base_ = pow(2., baseShift) * x2.base() * x3.base(); + width_ = dataFormats->setup()->widthDSPab(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::S13Shifted, true, iConfig) { + const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.getParameter("BaseShiftS13Shifted"); + base_ = pow(2., baseShift) * x3.base() * x3.base(); + width_ = dataFormats->setup()->widthDSPab(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::K00, true, 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()->widthDSPbb(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::K10, true, iConfig) { + const int baseShift = iConfig.getParameter("BaseShiftK10"); + base_ = pow(2., baseShift); + width_ = dataFormats->setup()->widthDSPbb(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::K21, true, 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()->widthDSPbb(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::K31, true, iConfig) { + const int baseShift = iConfig.getParameter("BaseShiftK31"); + base_ = pow(2., baseShift); + width_ = dataFormats->setup()->widthDSPbb(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::R00, false, iConfig) { + const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.getParameter("BaseShiftR00"); + width_ = iConfig.getParameter("WidthR00"); + base_ = pow(2., baseShift) * x1.base() * x1.base(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::R11, false, iConfig) { + const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.getParameter("BaseShiftR11"); + width_ = iConfig.getParameter("WidthR11"); + base_ = pow(2., baseShift) * x3.base() * x3.base(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::R00Rough, false, iConfig) { + const FormatKF R00(dataFormats, iConfig); + width_ = dataFormats->setup()->widthAddrBRAM18(); + range_ = R00.range(); + const int baseShift = R00.width() - width_ - 1; + base_ = pow(2., baseShift) * R00.base(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::R11Rough, false, iConfig) { + const FormatKF R11(dataFormats, iConfig); + width_ = dataFormats->setup()->widthAddrBRAM18(); + range_ = R11.range(); + const int baseShift = R11.width() - width_ - 1; + base_ = pow(2., baseShift) * R11.base(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::invR00Approx, false, 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(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::invR11Approx, false, 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(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::invR00Cor, false, iConfig) { + const int baseShift = iConfig.getParameter("BaseShiftInvR00Cor"); + base_ = pow(2., baseShift); + width_ = dataFormats->setup()->widthDSPau(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::invR11Cor, false, iConfig) { + const int baseShift = iConfig.getParameter("BaseShiftInvR11Cor"); + base_ = pow(2., baseShift); + width_ = dataFormats->setup()->widthDSPau(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::invR00, false, 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()->widthDSPbu(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::invR11, false, 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()->widthDSPbu(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::C00, false, iConfig) { + const DataFormat& x0 = dataFormats->format(Variable::inv2R, Process::kf); + const int baseShift = iConfig.getParameter("BaseShiftC00"); + width_ = iConfig.getParameter("WidthC00"); + base_ = pow(2., baseShift) * x0.base() * x0.base(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::C01, true, 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"); + width_ = iConfig.getParameter("WidthC01"); + base_ = pow(2., baseShift) * x0.base() * x1.base(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::C11, false, iConfig) { + const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.getParameter("BaseShiftC11"); + width_ = iConfig.getParameter("WidthC11"); + base_ = pow(2., baseShift) * x1.base() * x1.base(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::C22, false, iConfig) { + const DataFormat& x2 = dataFormats->format(Variable::cot, Process::kf); + const int baseShift = iConfig.getParameter("BaseShiftC22"); + width_ = iConfig.getParameter("WidthC22"); + base_ = pow(2., baseShift) * x2.base() * x2.base(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::C23, true, 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"); + width_ = iConfig.getParameter("WidthC23"); + base_ = pow(2., baseShift) * x2.base() * x3.base(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::C33, false, iConfig) { + const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.getParameter("BaseShiftC33"); + width_ = iConfig.getParameter("WidthC33"); + base_ = pow(2., baseShift) * x3.base() * x3.base(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::end, false, iConfig) { + const Setup* setup = dataFormats->setup(); + const DataFormat& tm = dataFormats->format(Variable::r, Process::tm); + width_ = setup->widthAddrBRAM18(); + range_ = setup->outerRadius() - setup->innerRadius(); + base_ = tm.base() * pow(2, ceil(log2(range_ / tm.base())) - width_); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::end, false, iConfig) { + const FormatKF H00(dataFormats, iConfig); + const Setup* setup = dataFormats->setup(); + width_ = setup->widthDSPbu(); + range_ = 1. / setup->kfMinSeedDeltaR(); + const int baseShift = ceil(log2(range_ * pow(2., -width_) * H00.base())); + base_ = pow(2., baseShift) / H00.base(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::end, false, iConfig) { + const FormatKF H00(dataFormats, iConfig); + const Setup* setup = dataFormats->setup(); + width_ = setup->widthDSPbu(); + range_ = 1. / pow(setup->kfMinSeedDeltaR(), 2); + const double baseH2 = H00.base() * H00.base(); + const int baseShift = ceil(log2(range_ * pow(2., -width_) * baseH2)); + base_ = pow(2., baseShift) / baseH2; + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::end, false, iConfig) { + const FormatKF H00(dataFormats, iConfig); + base_ = H00.base() * H00.base(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::end, true, iConfig) { + const FormatKF H00(dataFormats, iConfig); + const FormatKF m0(dataFormats, iConfig); + base_ = H00.base() * m0.base(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::end, true, iConfig) { + const FormatKF H12(dataFormats, iConfig); + const FormatKF m1(dataFormats, iConfig); + base_ = H12.base() * m1.base(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::end, false, iConfig) { + const Setup* setup = dataFormats->setup(); + const FormatKF H00(dataFormats, iConfig); + const FormatKF v0(dataFormats, iConfig); + width_ = setup->widthDSPab(); + base_ = H00.base() * v0.base() * pow(2, H00.width() + v0.width() - width_); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::end, false, iConfig) { + const FormatKF H12(dataFormats, iConfig); + const Setup* setup = dataFormats->setup(); + const FormatKF v1(dataFormats, iConfig); + width_ = setup->widthDSPab(); + base_ = H12.base() * v1.base() * pow(2, H12.width() + v1.width() - width_); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::end, false, iConfig) { + const Setup* setup = dataFormats->setup(); + const FormatKF H00(dataFormats, iConfig); + const FormatKF v0(dataFormats, iConfig); + width_ = setup->widthDSPau(); + base_ = H00.base() * H00.base() * v0.base() * pow(2, 2 * H00.width() + v0.width() - width_); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::end, false, iConfig) { + const Setup* setup = dataFormats->setup(); + const FormatKF H12(dataFormats, iConfig); + const FormatKF v1(dataFormats, iConfig); + width_ = setup->widthDSPau(); + base_ = H12.base() * H12.base() * v1.base() * pow(2, 2 * H12.width() + v1.width() - width_); + } + +} // namespace trklet diff --git a/L1Trigger/TrackFindingTracklet/src/PurgeDuplicate.cc b/L1Trigger/TrackFindingTracklet/src/PurgeDuplicate.cc index 3807aac937c3c..4088076a31adb 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..0bf4a08162479 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/State.cc @@ -0,0 +1,170 @@ +#include "L1Trigger/TrackFindingTracklet/interface/State.h" + +#include +#include +#include +#include +#include + +using namespace std; +using namespace tt; + +namespace trklet { + + // + State::Stub::Stub(KalmanFilterFormats* kff, const FrameStub& frame) : stubDR_(frame, kff->dataFormats()) { + const 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 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 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(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(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(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..380f060cf5205 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/TrackFindingProcessor.cc @@ -0,0 +1,279 @@ +#include "L1Trigger/TrackFindingTracklet/interface/TrackFindingProcessor.h" +#include "L1Trigger/TrackTrigger/interface/StubPtConsistency.h" + +#include +#include +#include +#include +#include + +using namespace std; +using namespace edm; +using namespace tt; +using namespace trackerTFP; + +namespace trklet { + + TrackFindingProcessor::TrackFindingProcessor(const ParameterSet& iConfig, + const Setup* setup, + const DataFormats* dataFormats, + const TrackQuality* trackQuality) + : enableTruncation_(iConfig.getParameter("EnableTruncation")), + setup_(setup), + dataFormats_(dataFormats), + trackQuality_(trackQuality) {} + + // + TrackFindingProcessor::Track::Track(const FrameTrack& frameTrack, + const Frame& frameTQ, + const vector& ttStubRefs, + const DataFormats* df, + const TrackQuality* tq) + : ttTrackRef_(frameTrack.first), ttStubRefs_(ttStubRefs), valid_(true) { + partials_.reserve(partial_in); + // convert bits into nice formats + const Setup* setup = df->setup(); + const TrackKF track(frameTrack, df); + inv2R_ = track.inv2R(); + phiT_ = track.phiT(); + cot_ = track.cot(); + zT_ = track.zT(); + const double d0 = max(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, widthMVA_).val(); + ttBV >>= 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; + static const double rangeInvR = -2. * TTTrack_TrackWord::minRinv; + static const double rangePhi0 = -2. * TTTrack_TrackWord::minPhi0; + static const double rangeCot = -2. * TTTrack_TrackWord::minTanl; + static const double rangeZ0 = -2. * TTTrack_TrackWord::minZ0; + static const double rangeD0 = -2. * TTTrack_TrackWord::minD0; + if (abs(invR) > rangeInvR / 2.) + valid_ = false; + if (abs(phi0) > rangePhi0 / 2.) + valid_ = false; + if (abs(cot_) > rangeCot / 2.) + valid_ = false; + if (abs(z0) > rangeZ0 / 2.) + valid_ = false; + if (abs(d0) > rangeD0 / 2.) + valid_ = false; + if (!valid_) + return; + static const double baseInvR = rangeInvR / pow(2., TTTrack_TrackWord::TrackBitWidths::kRinvSize); + static const double basePhi0 = rangePhi0 / pow(2., TTTrack_TrackWord::TrackBitWidths::kPhiSize); + static const double baseCot = rangeCot / pow(2., TTTrack_TrackWord::TrackBitWidths::kTanlSize); + static const double baseZ0 = rangeZ0 / pow(2., TTTrack_TrackWord::TrackBitWidths::kZ0Size); + static const double baseD0 = rangeD0 / pow(2., TTTrack_TrackWord::TrackBitWidths::kD0Size); + static constexpr int nLayers = TTTrack_TrackWord::TrackBitWidths::kHitPatternSize; + static const TTBV Other_MVAs(0, 2 * TTTrack_TrackWord::TrackBitWidths::kMVAQualitySize); + const TTBV MVA_quality(mva_, TTTrack_TrackWord::TrackBitWidths::kMVAQualitySize); + const TTBV hit_pattern(hitPattern_.resize(nLayers).val(), nLayers); + static const TTBV chi2bend(0, TTTrack_TrackWord::TrackBitWidths::kBendChi2Size); + static 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); + static const TTBV valid(1, TTTrack_TrackWord::TrackBitWidths::kValidSize); + 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 StreamsTrack& inputs, + const Streams& inputsAdd, + const StreamsStub& stubs, + TTTracks& ttTracks, + StreamsTrack& outputs) { + // organize input tracks + 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 StreamsTrack& inputs, + const Streams& inputsAdd, + const StreamsStub& stubs, + vector>& outputs) { + // count input objects + int nTracks(0); + auto valid = [](int sum, const FrameTrack& frame) { return sum += (frame.first.isNonnull() ? 1 : 0); }; + for (const StreamTrack& tracks : inputs) + nTracks += 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 StreamTrack& streamKF = inputs[region]; + const Stream& streamTQ = inputsAdd[region]; + for (int channel = 0; channel < setup_->tfpNumChannel(); channel++) + outputs[offsetTFP + channel] = deque(streamKF.size(), nullptr); + for (int frame = 0; frame < (int)streamKF.size(); frame++) { + const FrameTrack& frameTrack = streamKF[frame]; + const Frame& frameTQ = streamTQ[frame]; + if (frameTrack.first.isNull()) + continue; + 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++) { + 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(vector>& inputs, StreamsTrack& outputs) const { + for (int channel = 0; channel < (int)inputs.size(); channel++) { + deque& input = inputs[channel]; + deque stack; + 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(FrameTrack()); + 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 (enableTruncation_ && (int)output.size() > setup_->numFramesIOHigh()) + output.resize(setup_->numFramesIOHigh()); + outputs[channel] = StreamTrack(output.begin(), output.end()); + } + } + + // produce TTTracks + void TrackFindingProcessor::produce(const StreamsTrack& inputs, TTTracks& outputs) const { + // collect input TTTrackRefs + vector ttTrackRefs; + ttTrackRefs.reserve(tracks_.size()); + const TTTrack* last = nullptr; + for (const StreamTrack& stream : inputs) { + for (const 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 = find_if(tracks_.begin(), tracks_.end(), match); + // TTTrack conversion + const int region = ttTrackRef->phiSector(); + const double aRinv = -2. * it->inv2R_; + const double aphi = 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(); + static const double Bfield = setup_->bField(); + 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 vector& inputs, StreamsTrack& outputs) const { + int iTrk(-1); + const TTTrack* last = nullptr; + for (StreamTrack& stream : outputs) { + for (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(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..aa1f67d2a9dfc --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/TrackMultiplexer.cc @@ -0,0 +1,429 @@ +#include "L1Trigger/TrackFindingTracklet/interface/TrackMultiplexer.h" + +#include +#include +#include +#include +#include + +using namespace std; +using namespace edm; +using namespace tt; + +namespace trklet { + + TrackMultiplexer::TrackMultiplexer(const ParameterSet& iConfig, + const Setup* setup, + const DataFormats* dataFormats, + const ChannelAssignment* channelAssignment, + const Settings* settings, + int region) + : enableTruncation_(iConfig.getParameter("EnableTruncation")), + useTTStubResiduals_(iConfig.getParameter("UseTTStubResiduals")), + useTTStubParameters_(iConfig.getParameter("UseTTStubParameters")), + applyNonLinearCorrection_(iConfig.getParameter("ApplyNonLinearCorrection")), + 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 StreamsTrack& streamsTrack, const StreamsStub& streamsStub) { + static const int numS = channelAssignment_->numSeedingLayers(); + static const int numChannel = channelAssignment_->numChannelsTrack(); + const int offsetTrack = region_ * numChannel; + // count tracks and stubs to reserve container + int nTracks(0); + int nStubs(0); + for (int channel = 0; channel < numChannel; channel++) { + const int channelTrack = offsetTrack + channel; + const int offsetStub = channelAssignment_->offsetStub(channelTrack); + const int numProjectionLayers = channelAssignment_->numProjectionLayers(channel); + 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 < numProjectionLayers; layer++) + if (streamsStub[offsetStub + layer][frame].first.isNonnull()) + nStubs++; + } + } + stubs_.reserve(nStubs + nTracks * numS); + tracks_.reserve(nTracks); + // store tracks and stubs + for (int channel = 0; channel < numChannel; channel++) { + const int numP = channelAssignment_->numProjectionLayers(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 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 + vector stubs; + stubs.reserve(numS + numP); + for (int layer = 0; layer < numP; layer++) { + const 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 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 == 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 = abs(posZ) < limit; + } + stubs_.emplace_back(ttStubRef, layerIdTracklet, stubId, r, phi, z, psTilt); + stubs.push_back(&stubs_.back()); + } + if (useTTStubParameters_) { + vector seedTTStubRefs; + seedTTStubRefs.reserve(numS); + 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()) * deltaPhi(gp0.phi() - offset); + const double H0m1 = (gp0.perp() - setup_->chosenRofPhi()) * 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 < numS; seedingLayer++) { + const int channelStub = numP + seedingLayer; + const 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 (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(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 = abs(posZ) < limit; + } else + psTilt = true; + stubs_.emplace_back(ttStubRef, trackletLayerId, stubId, r, phi, z, psTilt); + stubs.push_back(&stubs_.back()); + } + if (useTTStubResiduals_) { + for (Stub* stub : stubs) { + const GlobalPoint gp = setup_->stubPos(stub->ttStubRef_); + stub->r_ = gp.perp() - setup_->chosenRofPhi(); + stub->phi_ = deltaPhi(gp.phi() - region_ * setup_->baseRegion()); + stub->phi_ -= phiT + stub->r_ * inv2R; + stub->z_ = gp.z() - (z0 + gp.perp() * cot); + } + } + // non linear corrections + if (applyNonLinearCorrection_) { + for (Stub* stub : stubs) { + const double d = inv2R * (stub->r_ + setup_->chosenRofPhi()); + const double dPhi = asin(d) - d; + stub->phi_ -= dPhi; + stub->z_ -= dPhi / inv2R * cot; + } + } + // check track validity + bool valid = true; + // kill truncated rtacks + if (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 + 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 ((int)layers.size() < setup_->kfMinLayers() || (int)(int)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(StreamsTrack& streamsTrack, 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; + static const int numChannel = channelAssignment_->numChannelsTrack(); + vector> streams(numChannel); + for (int channel = 0; channel < numChannel; channel++) { + int iTrack(0); + deque& stream = streams[channel]; + const 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 (deque& stream : streams) + for (auto it = stream.end(); it != stream.begin();) + it = (*--it) ? stream.begin() : stream.erase(it); + // route into single channel + deque accepted; + vector> stacks(numChannel); + // clock accurate firmware emulation, each while trip describes one clock tick, one stub in and one stub out per tick + while (!all_of(streams.begin(), streams.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 < numChannel; 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 (enableTruncation_ && (int)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_) : FrameTrack(); }; + auto frameStub = [this](Track* track, int layer) { + const auto it = + 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 FrameStub(); + + return (*it)->frame(dataFormats_); + }; + static const int numLayers = channelAssignment_->tmNumLayers(); + const int offsetStub = region_ * numLayers; + // fill output tracks and stubs + streamsTrack[region_].reserve(accepted.size()); + for (int layer = 0; layer < numLayers; layer++) + streamsStub[offsetStub + layer].reserve(accepted.size()); + for (Track* track : accepted) { + if (!track) { // fill gaps + streamsTrack[region_].emplace_back(FrameTrack()); + for (int layer = 0; layer < numLayers; layer++) + streamsStub[offsetStub + layer].emplace_back(FrameStub()); + continue; + } + streamsTrack[region_].emplace_back(frameTrack(track)); + for (int layer = 0; layer < numLayers; 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(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 = 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/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 fc5e36f397075..7308ade969ea0 100644 --- a/L1Trigger/TrackFindingTracklet/test/AnalyzerDR.cc +++ b/L1Trigger/TrackFindingTracklet/test/AnalyzerDR.cc @@ -62,13 +62,9 @@ namespace trklet { int& sum, bool perfect = false) const; // ED input token of stubs - EDGetTokenT edGetTokenAcceptedStubs_; + 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_; + EDGetTokenT edGetTokenTracks_; // ED input token of TTStubRef to TPPtr association for tracking efficiency EDGetTokenT edGetTokenSelection_; // ED input token of TTStubRef to recontructable TPPtr association @@ -95,6 +91,7 @@ namespace trklet { TProfile* prof_; TProfile* profChannel_; TH1F* hisChannel_; + TH1F* hisTracks_; // printout stringstream log_; @@ -103,15 +100,11 @@ namespace trklet { AnalyzerDR::AnalyzerDR(const 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 string& label = iConfig.getParameter("OutputLabelDR"); + const string& branchStubs = iConfig.getParameter("BranchStubs"); + const string& branchTracks = iConfig.getParameter("BranchTracks"); + edGetTokenStubs_ = consumes(InputTag(label, branchStubs)); + edGetTokenTracks_ = consumes(InputTag(label, branchTracks)); if (useMCTruth_) { const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); @@ -141,35 +134,28 @@ namespace trklet { 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) { // 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; + Handle handleStubs; + iEvent.getByToken(edGetTokenStubs_, handleStubs); + const StreamsStub& streamsStub = *handleStubs; + Handle handleTracks; + iEvent.getByToken(edGetTokenTracks_, handleTracks); + const StreamsTrack& streamsTrack = *handleTracks; // read in MCTruth const StubAssociation* selection = nullptr; const StubAssociation* reconstructable = nullptr; @@ -186,53 +172,38 @@ namespace trklet { 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(), 0, [](int sum, const vector& track) { - return sum + static_cast(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); - } + vector> tracks; + formTracks(streamsTrack, streamsStub, tracks, region); + nTracks += tracks.size(); + nStubs += accumulate(tracks.begin(), tracks.end(), 0, [](int sum, const vector& track) { + return sum += (int)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 StreamTrack& stream = streamsTrack[region]; + 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; + 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,46 +211,38 @@ 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 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 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_ << " 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; log_ << "============================================================="; - LogPrint("L1Trigger/TrackerTFP") << log_.str(); + LogPrint(moduleDescription().moduleName()) << log_.str(); } // diff --git a/L1Trigger/TrackFindingTracklet/test/AnalyzerDemonstrator.cc b/L1Trigger/TrackFindingTracklet/test/AnalyzerDemonstrator.cc index cd0e596601bfb..98b224b1b0df5 100644 --- a/L1Trigger/TrackFindingTracklet/test/AnalyzerDemonstrator.cc +++ b/L1Trigger/TrackFindingTracklet/test/AnalyzerDemonstrator.cc @@ -25,8 +25,8 @@ 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 */ @@ -44,7 +44,8 @@ namespace trklet { void convert(const Event& iEvent, const EDGetTokenT& tokenTracks, const EDGetTokenT& tokenStubs, - vector>& bits) const; + vector>& bits, + bool TB = false) const; // template void convert(const T& collection, vector>& bits) const; @@ -70,26 +71,30 @@ namespace trklet { int nEvents_ = 0; // int nEventsSuccessful_ = 0; + // + bool TBin_; + bool TBout_; }; AnalyzerDemonstrator::AnalyzerDemonstrator(const 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"); + const string& branchStubs = iConfig.getParameter("BranchStubs"); + const string& branchTracks = iConfig.getParameter("BranchTracks"); edGetTokenStubsIn_ = consumes(InputTag(labelIn, branchStubs)); edGetTokenStubsOut_ = consumes(InputTag(labelOut, branchStubs)); - if (labelOut != "TrackFindingTrackletProducerKFout") - edGetTokenStubsOut_ = consumes(InputTag(labelOut, branchStubs)); - if (labelIn != "TrackFindingTrackletProducerIRin") + if (labelIn != "ProducerIRin") edGetTokenTracksIn_ = consumes(InputTag(labelIn, branchTracks)); - if (labelOut != "TrackFindingTrackletProducerIRin") + if (labelOut != "ProducerIRin") edGetTokenTracksOut_ = consumes(InputTag(labelOut, branchTracks)); // book ES products esGetTokenSetup_ = esConsumes(); esGetTokenChannelAssignment_ = esConsumes(); esGetTokenDemonstrator_ = esConsumes(); + // + TBin_ = labelIn == "l1tTTTracksFromTrackletEmulation"; + TBout_ = labelOut == "l1tTTTracksFromTrackletEmulation"; } void AnalyzerDemonstrator::beginRun(const Run& iEvent, const EventSetup& iSetup) { @@ -105,8 +110,8 @@ namespace trklet { nEvents_++; vector> input; vector> output; - convert(iEvent, edGetTokenTracksIn_, edGetTokenStubsIn_, input); - convert(iEvent, edGetTokenTracksOut_, edGetTokenStubsOut_, output); + convert(iEvent, edGetTokenTracksIn_, edGetTokenStubsIn_, input, TBin_); + convert(iEvent, edGetTokenTracksOut_, edGetTokenStubsOut_, output, TBout_); if (demonstrator_->analyze(input, output)) nEventsSuccessful_++; } @@ -115,36 +120,41 @@ namespace trklet { void AnalyzerDemonstrator::convert(const Event& iEvent, const EDGetTokenT& tokenTracks, const EDGetTokenT& tokenStubs, - vector>& bits) const { + vector>& bits, + bool TB) const { const bool tracks = !tokenTracks.isUninitialized(); const bool stubs = !tokenStubs.isUninitialized(); Handle handleStubs; Handle handleTracks; + int numChannelStubs(0); + if (stubs) { + iEvent.getByToken(tokenStubs, handleStubs); + numChannelStubs = handleStubs->size(); + } int numChannelTracks(0); if (tracks) { 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); } } @@ -168,7 +178,7 @@ namespace trklet { void AnalyzerDemonstrator::endJob() { stringstream log; log << "Successrate: " << nEventsSuccessful_ << " / " << nEvents_ << " = " << nEventsSuccessful_ / (double)nEvents_; - LogPrint("L1Trigger/TrackerTFP") << log.str(); + 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..6eeb2220a6ede --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/test/AnalyzerKF.cc @@ -0,0 +1,413 @@ +#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 + +using namespace std; +using namespace edm; +using namespace tt; + +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 one::EDAnalyzer { + public: + AnalyzerKF(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 vector& tracks, + const vector>& stubs, + int region, + const StubAssociation* ass, + set& tps, + int& sum, + const vector& his, + const vector& prof, + bool perfect = true) const; + // + void analyzeTPz0(const StubAssociation* sa); + // ED input token of accepted Tracks + EDGetTokenT edGetTokenStubs_; + // ED input token of accepted Stubs + EDGetTokenT edGetTokenTracks_; + // ED input token for number of accepted States + EDGetTokenT edGetTokenNumStatesAccepted_; + // ED input token for number of lost States + EDGetTokenT edGetTokenNumStatesTruncated_; + // 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; + // + const DataFormats* dataFormats_ = nullptr; + // enables analyze of TPs + bool useMCTruth_; + // + int nEvents_ = 0; + // + string label_; + + // Histograms + + TProfile* prof_; + TProfile* profChannel_; + TH1F* hisChannel_; + vector hisRes_; + 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 + stringstream log_; + }; + + AnalyzerKF::AnalyzerKF(const 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 string& branchStubs = iConfig.getParameter("BranchStubs"); + const string& branchTracks = iConfig.getParameter("BranchTracks"); + const string& branchTruncated = iConfig.getParameter("BranchTruncated"); + edGetTokenStubs_ = consumes(InputTag(label_, branchStubs)); + edGetTokenTracks_ = consumes(InputTag(label_, branchTracks)); + edGetTokenNumStatesAccepted_ = consumes(InputTag(label_, branchTracks)); + edGetTokenNumStatesTruncated_ = consumes(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(ios::fixed, ios::floatfield); + log_.precision(4); + } + + void AnalyzerKF::beginRun(const Run& iEvent, const EventSetup& iSetup) { + // helper class to store configurations + setup_ = &iSetup.getData(esGetTokenSetup_); + dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); + // book histograms + 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 vector names = {"phi0", "inv2R", "z0", "cot", "d0"}; + static const 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 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 Event& iEvent, const 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 + Handle handleStubs; + iEvent.getByToken(edGetTokenStubs_, handleStubs); + const StreamsStub& allStubs = *handleStubs; + Handle handleTracks; + iEvent.getByToken(edGetTokenTracks_, handleTracks); + const StreamsTrack& allTracks = *handleTracks; + Handle handleNumStatesAccepted; + iEvent.getByToken(edGetTokenNumStatesAccepted_, handleNumStatesAccepted); + Handle handleNumStatesTruncated; + iEvent.getByToken(edGetTokenNumStatesTruncated_, handleNumStatesTruncated); + // 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, hisEffEtaTotal_, hisEffInv2RTotal_, hisEffPTTotal_, hisEffD0Total_); + } + // analyze kf products and associate found tracks with reconstrucable TrackingParticles + set tpPtrs; + set tpPtrsSelection; + 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 StreamTrack& channelTracks = allTracks[region]; + hisChannel_->Fill(channelTracks.size()); + profChannel_->Fill(1, channelTracks.size()); + vector tracks; + vector stubs; + vector> tracksStubs(channelTracks.size(), 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 = abs(asinh(tracks.back().cot())); + int nLayers(0); + for (int layer = 0; layer < numLayers; layer++) { + const 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, vector(), vector()); + associate(tracks, tracksStubs, region, selection, tpPtrsMax, tmp, vector(), 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 = sqrt(eff * (1. - eff) / 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}; + 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_ << " 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_ << " tracking efficiency = " << setw(wNums) << eff << " +- " << setw(wErrs) << errEff << endl; + log_ << " max tracking efficiency = " << setw(wNums) << effMax << " +- " << setw(wErrs) << errEffMax << endl; + log_ << " fake rate = " << setw(wNums) << fracFake << endl; + log_ << " duplicate rate = " << setw(wNums) << fracDup << endl; + log_ << " state assessment fraction = " << setw(wNums) << fracSatest << endl; + log_ << " number of states per TFP = " << setw(wNums) << (numStates + numStatesLost) / setup_->numRegions() + << endl; + log_ << "============================================================="; + LogPrint(moduleDescription().moduleName()) << log_.str(); + } + + // + void AnalyzerKF::associate(const vector& tracks, + const vector>& tracksStubs, + int region, + const StubAssociation* ass, + set& tps, + int& sum, + const vector& his, + const vector& prof, + bool perfect) const { + for (int frame = 0; frame < (int)tracks.size(); frame++) { + const TrackKF& track = tracks[frame]; + const vector& stubs = tracksStubs[frame]; + 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 vector& tpPtrs = perfect ? ass->associateFinal(ttStubRefs) : ass->associate(ttStubRefs); + if (tpPtrs.empty()) + continue; + sum++; + copy(tpPtrs.begin(), tpPtrs.end(), 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 = 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 = 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 = deltaPhi(tpPhi0 - phi0); + const double dD0 = tpPtr->d0() + track.frame().first->d0(); + const 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(abs(tpPtr->eta()), 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/AnalyzerKFout.cc b/L1Trigger/TrackFindingTracklet/test/AnalyzerKFout.cc index 1418a03e4c409..b4c625c9d8074 100644 --- a/L1Trigger/TrackFindingTracklet/test/AnalyzerKFout.cc +++ b/L1Trigger/TrackFindingTracklet/test/AnalyzerKFout.cc @@ -86,8 +86,8 @@ namespace trklet { 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"); + const string& branchAccepted = iConfig.getParameter("BranchTracksAccepted"); + const string& branchLost = iConfig.getParameter("BranchTracksTruncated"); edGetTokenAccepted_ = consumes(InputTag(label, branchAccepted)); edGetTokenLost_ = consumes(InputTag(label, branchLost)); if (useMCTruth_) { @@ -231,7 +231,7 @@ namespace trklet { log_ << " fake rate = " << setw(wNums) << fracFake << endl; log_ << " duplicate rate = " << setw(wNums) << fracDup << endl; log_ << "============================================================="; - LogPrint("L1Trigger/TrackerTFP") << log_.str(); + LogPrint(moduleDescription().moduleName()) << log_.str(); } // 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/AnalyzerDRin.cc b/L1Trigger/TrackFindingTracklet/test/AnalyzerTM.cc similarity index 61% rename from L1Trigger/TrackFindingTracklet/test/AnalyzerDRin.cc rename to L1Trigger/TrackFindingTracklet/test/AnalyzerTM.cc index e91d45c0b06e2..00931d48591c4 100644 --- a/L1Trigger/TrackFindingTracklet/test/AnalyzerDRin.cc +++ b/L1Trigger/TrackFindingTracklet/test/AnalyzerTM.cc @@ -35,14 +35,14 @@ using namespace tt; namespace trklet { - /*! \class trklet::AnalyzerDRin - * \brief Class to analyze hardware like structured TTStub Collection generated by DRin module + /*! \class trklet::AnalyzerTM + * \brief Class to analyze hardware like structured TTStub Collection generated by TM module * \author Thomas Schuh * \date 2023, Jan */ - class AnalyzerDRin : public one::EDAnalyzer { + class AnalyzerTM : public one::EDAnalyzer { public: - AnalyzerDRin(const ParameterSet& iConfig); + AnalyzerTM(const ParameterSet& iConfig); void beginJob() override {} void beginRun(const Run& iEvent, const EventSetup& iSetup) override; void analyze(const Event& iEvent, const EventSetup& iSetup) override; @@ -63,13 +63,9 @@ namespace trklet { bool perfect = false) const; // ED input token of stubs - EDGetTokenT edGetTokenAcceptedStubs_; + 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_; + EDGetTokenT edGetTokenTracks_; // ED input token of TTStubRef to TPPtr association for tracking efficiency EDGetTokenT edGetTokenSelection_; // ED input token of TTStubRef to recontructable TPPtr association @@ -101,18 +97,14 @@ namespace trklet { stringstream log_; }; - AnalyzerDRin::AnalyzerDRin(const ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { + AnalyzerTM::AnalyzerTM(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)); + const string& label = iConfig.getParameter("OutputLabelTM"); + const string& branchStubs = iConfig.getParameter("BranchStubs"); + const string& branchTracks = iConfig.getParameter("BranchTracks"); + edGetTokenStubs_ = consumes(InputTag(label, branchStubs)); + edGetTokenTracks_ = consumes(InputTag(label, branchTracks)); if (useMCTruth_) { const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); @@ -128,7 +120,7 @@ namespace trklet { log_.precision(4); } - void AnalyzerDRin::beginRun(const Run& iEvent, const EventSetup& iSetup) { + void AnalyzerTM::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 @@ -138,39 +130,31 @@ namespace trklet { // book histograms Service fs; TFileDirectory dir; - dir = fs->mkdir("DRin"); + 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(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); } - void AnalyzerDRin::analyze(const Event& iEvent, const EventSetup& iSetup) { + void AnalyzerTM::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; + Handle handleStubs; + iEvent.getByToken(edGetTokenStubs_, handleStubs); + const StreamsStub& streamsStub = *handleStubs; + Handle handleTracks; + iEvent.getByToken(edGetTokenTracks_, handleTracks); + const StreamsTrack& streamsTrack = *handleTracks; // read in MCTruth const StubAssociation* selection = nullptr; const StubAssociation* reconstructable = nullptr; @@ -187,108 +171,85 @@ namespace trklet { 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(), 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(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); - } + vector> tracks; + formTracks(streamsTrack, streamsStub, tracks, region); + nTracks += tracks.size(); + nStubs += accumulate(tracks.begin(), tracks.end(), 0, [](int sum, const vector& track) { + return sum += (int)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 StreamTrack& stream = streamsTrack[region]; + 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(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_++; } - void AnalyzerDRin::endJob() { + void AnalyzerTM::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 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 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_ << " DRin SUMMARY " << endl; + log_ << " TM 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(); + LogPrint(moduleDescription().moduleName()) << log_.str(); } // - void AnalyzerDRin::formTracks(const StreamsTrack& streamsTrack, - const StreamsStub& streamsStubs, - vector>& tracks, - int channel) const { - const int offset = channel * setup_->numLayers(); + void AnalyzerTM::formTracks(const StreamsTrack& streamsTrack, + const StreamsStub& streamsStubs, + vector>& tracks, + int channel) const { + static const int numLayers = channelAssignment_->tmNumLayers(); + const int offset = channel * 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); @@ -299,8 +260,8 @@ namespace trklet { if (frameTrack.first.isNull()) continue; vector ttStubRefs; - ttStubRefs.reserve(setup_->numLayers()); - for (int layer = 0; layer < setup_->numLayers(); layer++) { + ttStubRefs.reserve(numLayers); + for (int layer = 0; layer < numLayers; layer++) { const FrameStub& stub = streamsStubs[offset + layer][frame]; if (stub.first.isNonnull()) ttStubRefs.push_back(stub.first); @@ -310,11 +271,11 @@ namespace trklet { } // - void AnalyzerDRin::associate(const vector>& tracks, - const StubAssociation* ass, - set& tps, - int& sum, - bool perfect) const { + void AnalyzerTM::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()) @@ -326,4 +287,4 @@ namespace trklet { } // namespace trklet -DEFINE_FWK_MODULE(trklet::AnalyzerDRin); +DEFINE_FWK_MODULE(trklet::AnalyzerTM); \ No newline at end of file diff --git a/L1Trigger/TrackFindingTracklet/test/AnalyzerTracklet.cc b/L1Trigger/TrackFindingTracklet/test/AnalyzerTracklet.cc index 0306313194801..897838737b89b 100644 --- a/L1Trigger/TrackFindingTracklet/test/AnalyzerTracklet.cc +++ b/L1Trigger/TrackFindingTracklet/test/AnalyzerTracklet.cc @@ -15,6 +15,7 @@ #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 @@ -66,10 +67,14 @@ namespace trklet { 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 tracks to channel + const ChannelAssignment* channelAssignment_ = nullptr; // enables analyze of TPs bool useMCTruth_; // @@ -105,6 +110,7 @@ namespace trklet { // book ES products esGetTokenSetup_ = esConsumes(); esGetTokenDataFormats_ = esConsumes(); + esGetTokenChannelAssignment_ = esConsumes(); // log config log_.setf(ios::fixed, ios::floatfield); log_.precision(4); @@ -115,6 +121,8 @@ namespace trklet { 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; TFileDirectory dir; @@ -132,7 +140,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 @@ -178,12 +186,18 @@ namespace trklet { 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 = + accumulate(ttTrackRefs.begin(), ttTrackRefs.end(), 0, [seedType](int sum, const TTTrackRef& ttTrackRef) { + return sum += ((int)ttTrackRef->trackSeedType() == seedType ? 1 : 0); + }); + hisChannel_->Fill(nTracks); + profChannel_->Fill(seedType, nTracks); + } } // analyze tracklet products and associate found tracks with reconstrucable TrackingParticles set tpPtrs; @@ -251,7 +265,7 @@ namespace trklet { log_ << " fake rate = " << setw(wNums) << fracFake << endl; log_ << " duplicate rate = " << setw(wNums) << fracDup << endl; log_ << "============================================================="; - LogPrint("L1Trigger/TrackFindingTracklet") << log_.str(); + LogPrint(moduleDescription().moduleName()) << log_.str(); } // gets all TPs associated too any of the tracks & number of tracks matching at least one TP 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..9e037330ff6e9 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..4a9717c407f3c 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!!!") @@ -117,8 +117,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 +129,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 @@ -172,18 +170,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..f798a2e2b7cd4 100644 --- a/L1Trigger/TrackFindingTracklet/test/ProducerIRin.cc +++ b/L1Trigger/TrackFindingTracklet/test/ProducerIRin.cc @@ -60,7 +60,7 @@ namespace trklet { ProducerIRin::ProducerIRin(const ParameterSet& iConfig) : iConfig_(iConfig) { const InputTag& inputTag = iConfig.getParameter("InputTagDTC"); - const string& branchStubs = iConfig.getParameter("BranchAcceptedStubs"); + const string& branchStubs = iConfig.getParameter("BranchStubsAccepted"); // book in- and output ED products edGetTokenTTDTC_ = consumes(inputTag); edPutTokenStubs_ = produces(branchStubs); @@ -74,11 +74,6 @@ namespace trklet { void ProducerIRin::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()); channelAssignment_ = const_cast(&iSetup.getData(esGetTokenChannelAssignment_)); // map of used tfp channels channelEncoding_ = channelAssignment_->channelEncoding(); @@ -88,17 +83,15 @@ namespace trklet { // empty IRin product 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)); - } + 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)); + iEvent.emplace(edPutTokenStubs_, move(streamStubs)); } } // namespace trklet 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..a717ab3b1b26b 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_) * 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..2e2724e37c8fe 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" @@ -45,21 +40,13 @@ namespace tt { public: Setup() {} Setup(const edm::ParameterSet& iConfig, - const MagneticField& magneticField, 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 +63,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 @@ -88,12 +77,6 @@ namespace tt { GlobalPoint stubPos(bool hybrid, 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 +89,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,13 +102,23 @@ 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 @@ -150,29 +145,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 +198,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 +239,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 +258,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 +281,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 +308,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 @@ -398,8 +383,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 +395,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 +424,73 @@ 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_; } - // 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_; } + 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 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 // 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 +500,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 +517,6 @@ namespace tt { // configure TPSelector void configureTPSelector(); - // MagneticField - const MagneticField* magneticField_; // TrackerGeometry const TrackerGeometry* trackerGeometry_; // TrackerTopology @@ -565,59 +527,28 @@ 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_; + + // TMTT specific parameter + edm::ParameterSet pSetTMTT_; // number of bits used for stub r - ChosenRofPhi int tmttWidthR_; // number of bits used for stub phi w.r.t. phi sector centre @@ -627,15 +558,7 @@ namespace tt { // 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,32 +586,13 @@ 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_; // width of the 'A' port of an DSP slice @@ -718,13 +622,18 @@ 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_; + + // Tracker specific Parameter + edm::ParameterSet pSetOT_; // BField used in fw in T double bField_; // accepted BField difference between FW to EventSetup in T @@ -736,31 +645,35 @@ 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 @@ -824,13 +737,13 @@ namespace tt { // 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_; @@ -838,17 +751,21 @@ namespace tt { // 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_; @@ -861,91 +778,78 @@ namespace tt { // internal fifo depth int htDepthMemory_; - // Parameter specifying MiniHoughTransform - edm::ParameterSet pSetMHT_; + // Parameter specifying Clean Track Builder + edm::ParameterSet pSetCTB_; // 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_; + int ctbMaxStubs_; + // internal memory depth + int ctbDepthMemory_; // Parameter specifying KalmanFilter edm::ParameterSet pSetKF_; // 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_; - - // 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_; + // + int kfShiftChi20_; + // + int kfShiftChi21_; + // + double kfCutChi2_; + // + int kfWidthChi2_; // Parameter specifying DuplicateRemoval edm::ParameterSet pSetDR_; // internal memory depth int drDepthMemory_; + // Parameter specifying Track Quality + edm::ParameterSet pSetTQ_; + // 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 +866,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 +965,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..3cc8421c3f125 100644 --- a/L1Trigger/TrackTrigger/plugins/ProducerSetup.cc +++ b/L1Trigger/TrackTrigger/plugins/ProducerSetup.cc @@ -1,9 +1,8 @@ #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 @@ -26,70 +25,29 @@ namespace tt { private: const ParameterSet iConfig_; - ESGetToken getTokenTTStubAlgorithm_; - ESGetToken getTokenMagneticField_; ESGetToken getTokenTrackerGeometry_; ESGetToken getTokenTrackerTopology_; ESGetToken getTokenCablingMap_; - ESGetToken getTokenGeometryConfiguration_; - ESGetToken getTokenGeometryConfigurationDD4hep_; - bool fromDD4hep_; + ESGetToken getTokenTTStubAlgorithm_; }; ProducerSetup::ProducerSetup(const ParameterSet& iConfig) : iConfig_(iConfig) { - fromDD4hep_ = iConfig.getParameter("fromDD4hep"); 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(); } unique_ptr ProducerSetup::produce(const SetupRcd& setupRcd) { - const MagneticField& magneticField = setupRcd.get(getTokenMagneticField_); 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 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); - } + return 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..5fc3c2288a8ad --- /dev/null +++ b/L1Trigger/TrackTrigger/python/Setup_cfi.py @@ -0,0 +1,204 @@ +# 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.4 ), # 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 ( + 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 ), # + 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( 50 ), # 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 ( + 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 ), # + MaxSeedingLayer = cms.int32 ( 4 ), # + NumSeedStubs = cms.int32 ( 2 ), # + MinSeedDeltaR = cms.double( 1.6 ), # + 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 ), # + ShiftChi21 = cms.int32 ( -5 ), # + CutChi2 = cms.double( 2.0 ), # + WidthChi2 = cms.int32 ( 8 ) # + ), + + # 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..43e8215c4e253 100644 --- a/L1Trigger/TrackTrigger/python/TTStubAlgorithmRegister_cfi.py +++ b/L1Trigger/TrackTrigger/python/TTStubAlgorithmRegister_cfi.py @@ -42,5 +42,4 @@ # We prefer the global geometry algorithm for now in order not to break # anything. Override with process.TTStubAlgorithm_PSimHit_ = ..., # etc. in your configuration. -TTStubAlgorithm_Phase2TrackerDigi_ = cms.ESPrefer("TTStubAlgorithm_official_Phase2TrackerDigi_") - +TTStubAlgorithm_Phase2TrackerDigi_ = cms.ESPrefer("TTStubAlgorithm_official_Phase2TrackerDigi_") \ No newline at end of file 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..e71df45626453 100644 --- a/L1Trigger/TrackTrigger/src/SensorModule.cc +++ b/L1Trigger/TrackTrigger/src/SensorModule.cc @@ -113,10 +113,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_ = abs(sinTilt_) * pitchCol_; + dPhi_ = pitchRow_ / r_; + dZ_ = abs(cosTilt_) * pitchCol_ + dR_ * 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..e9dab24ac4496 100644 --- a/L1Trigger/TrackTrigger/src/Setup.cc +++ b/L1Trigger/TrackTrigger/src/Setup.cc @@ -1,16 +1,13 @@ #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; @@ -18,59 +15,33 @@ using namespace edm; namespace tt { Setup::Setup(const ParameterSet& iConfig, - const MagneticField& magneticField, 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 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")), + minPt_(pSetTF_.getParameter("MinPt")), + minPtCand_(pSetTF_.getParameter("MinPtCand")), + maxEta_(pSetTF_.getParameter("MaxEta")), + maxD0_(pSetTF_.getParameter("MaxD0")), + chosenRofPhi_(pSetTF_.getParameter("ChosenRofPhi")), + numLayers_(pSetTF_.getParameter("NumLayers")), + minLayers_(pSetTF_.getParameter("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")), // 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")), @@ -84,19 +55,9 @@ namespace tt { hybridLayerRs_(pSetHybrid_.getParameter>("LayerRs")), hybridDiskZs_(pSetHybrid_.getParameter>("DiskZs")), hybridDisk2SRsSet_(pSetHybrid_.getParameter>("Disk2SRsSet")), + tbBarrelHalfLength_(pSetHybrid_.getParameter("BarrelHalfLength")), 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")), // Fimrware specific Parameter pSetFW_(iConfig.getParameter("Firmware")), widthDSPa_(pSetFW_.getParameter("WidthDSPa")), @@ -106,28 +67,33 @@ namespace tt { widthAddrBRAM18_(pSetFW_.getParameter("WidthAddrBRAM18")), numFramesInfra_(pSetFW_.getParameter("NumFramesInfra")), freqLHC_(pSetFW_.getParameter("FreqLHC")), - freqBE_(pSetFW_.getParameter("FreqBE")), + freqBEHigh_(pSetFW_.getParameter("FreqBEHigh")), + freqBELow_(pSetFW_.getParameter("FreqBELow")), 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")), + // Tracker specific Paramter + pSetOT_(iConfig.getParameter("Tracker")), + bField_(pSetOT_.getParameter("BField")), + bFieldError_(pSetOT_.getParameter("BFieldError")), + outerRadius_(pSetOT_.getParameter("OuterRadius")), + innerRadius_(pSetOT_.getParameter("InnerRadius")), + halfLength_(pSetOT_.getParameter("HalfLength")), + tiltApproxSlope_(pSetOT_.getParameter("TiltApproxSlope")), + tiltApproxIntercept_(pSetOT_.getParameter("TiltApproxIntercept")), + tiltUncertaintyR_(pSetOT_.getParameter("TiltUncertaintyR")), + scattering_(pSetOT_.getParameter("Scattering")), + pitchRow2S_(pSetOT_.getParameter("PitchRow2S")), + pitchRowPS_(pSetOT_.getParameter("PitchRowPS")), + pitchCol2S_(pSetOT_.getParameter("PitchCol2S")), + pitchColPS_(pSetOT_.getParameter("PitchColPS")), + limitPSBarrel_(pSetOT_.getParameter("LimitPSBarrel")), + limitsTiltedR_(pSetOT_.getParameter>("LimitsTiltedR")), + limitsTiltedZ_(pSetOT_.getParameter>("LimitsTiltedZ")), + limitsPSDiksZ_(pSetOT_.getParameter>("LimitsPSDiksZ")), + limitsPSDiksR_(pSetOT_.getParameter>("LimitsPSDiksR")), + tiltedLayerLimitsZ_(pSetOT_.getParameter>("TiltedLayerLimitsZ")), + psDiskLimitsR_(pSetOT_.getParameter>("PSDiskLimitsR")), // Parmeter specifying front-end pSetFE_(iConfig.getParameter("FrontEnd")), widthBend_(pSetFE_.getParameter("WidthBend")), @@ -159,70 +125,62 @@ namespace tt { // Parmeter specifying TFP pSetTFP_(iConfig.getParameter("TFP")), tfpWidthPhi0_(pSetTFP_.getParameter("WidthPhi0")), - tfpWidthInv2R_(pSetTFP_.getParameter("WidthInv2R")), + tfpWidthInvR_(pSetTFP_.getParameter("WidthInvR")), tfpWidthCot_(pSetTFP_.getParameter("WidthCot")), tfpWidthZ0_(pSetTFP_.getParameter("WidthZ0")), tfpNumChannel_(pSetTFP_.getParameter("NumChannel")), // Parmeter specifying GeometricProcessor pSetGP_(iConfig.getParameter("GeometricProcessor")), - numSectorsPhi_(pSetGP_.getParameter("NumSectorsPhi")), + gpNumBinsPhiT_(pSetGP_.getParameter("NumBinsPhiT")), + gpNumBinsZT_(pSetGP_.getParameter("NumBinsZT")), chosenRofZ_(pSetGP_.getParameter("ChosenRofZ")), - neededRangeChiZ_(pSetGP_.getParameter("RangeChiZ")), gpDepthMemory_(pSetGP_.getParameter("DepthMemory")), - boundariesEta_(pSetGP_.getParameter>("BoundariesEta")), + gpWidthModule_(pSetGP_.getParameter("WidthModule")), + gpPosPS_(pSetGP_.getParameter("PosPS")), + gpPosBarrel_(pSetGP_.getParameter("PosBarrel")), + gpPosTilted_(pSetGP_.getParameter("PosTilted")), // 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")), + // Parameter specifying Track Builder + pSetCTB_(iConfig.getParameter("CleanTrackBuilder")), + ctbNumBinsInv2R_(pSetCTB_.getParameter("NumBinsInv2R")), + ctbNumBinsPhiT_(pSetCTB_.getParameter("NumBinsPhiT")), + ctbNumBinsCot_(pSetCTB_.getParameter("NumBinsCot")), + ctbNumBinsZT_(pSetCTB_.getParameter("NumBinsZT")), + ctbMinLayers_(pSetCTB_.getParameter("MinLayers")), + ctbMaxTracks_(pSetCTB_.getParameter("MaxTracks")), + ctbMaxStubs_(pSetCTB_.getParameter("MaxStubs")), + ctbDepthMemory_(pSetCTB_.getParameter("DepthMemory")), // Parmeter specifying KalmanFilter pSetKF_(iConfig.getParameter("KalmanFilter")), kfNumWorker_(pSetKF_.getParameter("NumWorker")), + kfMaxTracks_(pSetKF_.getParameter("MaxTracks")), kfMinLayers_(pSetKF_.getParameter("MinLayers")), + kfMinLayersPS_(pSetKF_.getParameter("MinLayersPS")), kfMaxLayers_(pSetKF_.getParameter("MaxLayers")), + kfMaxGaps_(pSetKF_.getParameter("MaxGaps")), + kfMaxSeedingLayer_(pSetKF_.getParameter("MaxSeedingLayer")), + kfNumSeedStubs_(pSetKF_.getParameter("NumSeedStubs")), + kfMinSeedDeltaR_(pSetKF_.getParameter("MinSeedDeltaR")), 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")), + kfShiftChi20_(pSetKF_.getParameter("ShiftChi20")), + kfShiftChi21_(pSetKF_.getParameter("ShiftChi21")), + kfCutChi2_(pSetKF_.getParameter("CutChi2")), + kfWidthChi2_(pSetKF_.getParameter("WidthChi2")), // 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_(pSetDR_.getParameter("DepthMemory")), + // Parmeter specifying Track Quality + pSetTQ_(iConfig.getParameter("TrackQuality")), + tqNumChannel_(pSetTQ_.getParameter("NumChannel")) { // derive constants calculateConstants(); // convert configuration of TTStubAlgorithm @@ -234,60 +192,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,49 +277,18 @@ namespace tt { return it->second; } + // sensor module for ttStubRef + SensorModule* Setup::sensorModule(const TTStubRef& ttStubRef) const { + const DetId detId = ttStubRef->getDetId() + offsetDetIdDSV_; + return this->sensorModule(detId); + } + // 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_ << "). "; - } - } - - // 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. "; - } - } - } - // convert configuration of TTStubAlgorithm void Setup::consumeStubAlgorithm() { numTiltedLayerRings_ = pSetSA_->getParameter>("NTiltedRings"); @@ -488,25 +361,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 +370,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,7 +391,9 @@ 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(); + //return trackerGeometry_->getDetectorType(detId) == TrackerGeometry::ModuleType::Ph2PSP; } // @@ -541,7 +401,7 @@ namespace tt { 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; } @@ -551,7 +411,7 @@ namespace tt { 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; } @@ -561,7 +421,7 @@ namespace tt { TTBV bv(ttBV); 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; @@ -572,7 +432,7 @@ namespace tt { TTBV bv(ttBV); 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 +440,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; } @@ -639,28 +477,71 @@ namespace tt { 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 (abs(z) < limitPSBarrel_) { + barrel = true; + if (r < limitsTiltedR_[layer3]) + ps = true; + if (r < limitsTiltedR_[layer1]) + tilted = abs(z) > limitsTiltedZ_[layer1]; + else if (r < limitsTiltedR_[layer2]) + tilted = abs(z) > limitsTiltedZ_[layer2]; + else if (r < limitsTiltedR_[layer3]) + tilted = abs(z) > limitsTiltedZ_[layer3]; + } else if (abs(z) > limitsPSDiksZ_[disk5]) + ps = r < limitsPSDiksR_[disk5]; + else if (abs(z) > limitsPSDiksZ_[disk4]) + ps = r < limitsPSDiksR_[disk4]; + else if (abs(z) > limitsPSDiksZ_[disk3]) + ps = r < limitsPSDiksR_[disk3]; + else if (abs(z) > limitsPSDiksZ_[disk2]) + ps = r < limitsPSDiksR_[disk2]; + else if (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,26 +550,23 @@ namespace tt { widthDSPcb_ = widthDSPc_ - 1; widthDSPcu_ = widthDSPcb_ - 1; // firmware - maxPitch_ = max(pitchPS_, pitch2S_); - maxLength_ = max(lengthPS_, length2S_); + maxPitchRow_ = max(pitchRowPS_, pitchRow2S_); + maxPitchCol_ = max(pitchColPS_, pitchCol2S_); // common track finding invPtToDphi_ = speedOfLight_ * bField_ / 2000.; baseRegion_ = 2. * M_PI / numRegions_; + maxCot_ = beamWindowZ_ / chosenRofZ_ + 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_ = max(abs(outerRadius_ - chosenRofPhi_), abs(innerRadius_ - chosenRofPhi_)); + maxRz_ = max(abs(outerRadius_ - chosenRofZ_), 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 double rangeR = 2. * maxRphi_; const int baseShiftR = ceil(log2(rangeR / baseRgen / pow(2., tmttWidthR_))); tmttBaseR_ = baseRgen * pow(2., baseShiftR); const double rangeZ = 2. * halfLength_; @@ -698,14 +576,13 @@ namespace tt { const int baseShiftPhi = ceil(log2(rangePhi / tmttBasePhiT_ / pow(2., tmttWidthPhi_))); tmttBasePhi_ = tmttBasePhiT_ * pow(2., baseShiftPhi); tmttWidthLayer_ = ceil(log2(numLayers_)); - tmttWidthSectorEta_ = ceil(log2(numSectorsEta_)); + tmttWidthSectorEta_ = ceil(log2(gpNumBinsZT_)); tmttWidthInv2R_ = ceil(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 hybridRangeR = - 2. * max(abs(outerRadius_ - hybridChosenRofPhi_), abs(innerRadius_ - hybridChosenRofPhi_)); + const double hybridRangeInv2R = 2. * invPtToDphi_ / minPt_; + const double hybridRangeR = 2. * max(abs(outerRadius_ - chosenRofPhi_), abs(innerRadius_ - chosenRofPhi_)); hybridRangePhi_ = baseRegion_ + (hybridRangeR * hybridRangeInv2R) / 2.; hybridWidthLayerId_ = ceil(log2(hybridNumLayers_)); hybridBasesZ_.reserve(SensorModule::NumTypes); @@ -726,7 +603,10 @@ namespace tt { 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_ = *min_element(hybridBasesR_.begin(), hybridBasesR_.end()); + hybridBasePhi_ = *min_element(hybridBasesPhi_.begin(), hybridBasesPhi_.end()); + hybridBaseZ_ = *min_element(hybridBasesZ_.begin(), hybridBasesZ_.end()); + hybridMaxCot_ = sinh(maxEta_); disk2SRs_.reserve(hybridDisk2SRsSet_.size()); for (const auto& pSet : hybridDisk2SRsSet_) disk2SRs_.emplace_back(pSet.getParameter>("Disk2SRs")); @@ -741,17 +621,14 @@ namespace tt { dtcBaseInv2R_ = tmttBaseInv2R_ * 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 x1 = pow(2, widthRow_) * baseRow_ * maxPitchRow_ / 2.; + const double x0 = x1 - pow(2, dtcWidthRowLUT_) * baseRow_ * maxPitchRow_; const double maxM = atan2(x1, innerRadius_) - atan2(x0, innerRadius_); dtcWidthM_ = ceil(log2(maxM / dtcBaseM_)); dtcNumStreams_ = numDTCs_ * numOverlappingRegions_; - // mht - mhtNumCells_ = mhtNumBinsInv2R_ * mhtNumBinsPhiT_; - // zht - zhtNumCells_ = zhtNumBinsCot_ * zhtNumBinsZT_; - // - kfWidthLayerCount_ = ceil(log2(zhtMaxStubsPerLayer_)); + // ctb + ctbWidthLayerCount_ = ceil(log2(ctbMaxStubs_)); + // kf } // returns bit accurate hybrid stub radius for given TTStubRef and h/w bit word @@ -806,7 +683,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/TrackTrigger/test/CleanRelVal_cfg.py b/L1Trigger/TrackTrigger/test/CleanRelVal_cfg.py new file mode 100644 index 0000000000000..9576afb41be57 --- /dev/null +++ b/L1Trigger/TrackTrigger/test/CleanRelVal_cfg.py @@ -0,0 +1,78 @@ +################################################################################################ +# Run bit-accurate TMTT L1 tracking emulation. +# +# To run execute do +# cmsRun L1Trigger/L1TTrackerTFP/test/test_cfg.py +# where the arguments take default values if you don't specify them. You can change defaults below. +################################################################################################# + +import FWCore.ParameterSet.Config as cms + +process = cms.Process( "CleanUp" ) +process.load( 'FWCore.MessageService.MessageLogger_cfi' ) +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( 'Configuration.EventContent.EventContent_cff' ) +process.load( 'L1Trigger.TrackTrigger.TrackTrigger_cff' ) + +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic', '') + +# load code that creates clean TVs +process.load( 'SimTracker.TrackTriggerAssociation.CleanTV_cff' ) +# load code that creates clean TPs +process.load( 'SimTracker.TrackTriggerAssociation.CleanTP_cff' ) +# load code that associates TTStubs with clean TPs +process.load( 'SimTracker.TrackTriggerAssociation.CleanAssoc_cff' ) + +# build schedule +process.clean = cms.Path( process.CleanTV + process.CleanTP + process.CleanAssoc ) +process.schedule = cms.Schedule( process.clean ) + +# create options +import FWCore.ParameterSet.VarParsing as VarParsing +options = VarParsing.VarParsing( 'analysis' ) +# specify input MC +File = '28f2ac9b-b0a6-44a1-b10e-32ea9f59b611.root' +Samples = [ + '/store/relvalOrig/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/'+File +] +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() + +process.options = cms.untracked.PSet( wantSummary = cms.untracked.bool(False) ) +process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(options.Events) ) +process.source = cms.Source( + "PoolSource", + fileNames = cms.untracked.vstring( options.inputMC ), + noEventSort = cms.untracked.bool( True ), + secondaryFileNames = cms.untracked.vstring(), + duplicateCheckMode = cms.untracked.string( 'noDuplicateCheck' ) +) +#process.Timing = cms.Service( "Timing", summaryOnly = cms.untracked.bool( True ) ) +process.MessageLogger.cerr.enableStatistics = False + +if True : + process.writeDataset = cms.OutputModule("PoolOutputModule", + splitLevel = cms.untracked.int32(0), + eventAutoFlushCompressedSize = cms.untracked.int32(5242880), + outputCommands = process.RAWSIMEventContent.outputCommands, + fileName = cms.untracked.string('/heplnw039/store/relvalTrimmed/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/'+File), + dataset = cms.untracked.PSet( + filterName = cms.untracked.string(''), + dataTier = cms.untracked.string('GEN-SIM') + ) + ) + process.writeDataset.outputCommands.append('drop *_*_*_*') + process.writeDataset.outputCommands.append('keep *_CleanTV_AtLeastOneCluster_*') + process.writeDataset.outputCommands.append('keep *_CleanTP_AtLeastOneCluster_*') + process.writeDataset.outputCommands.append('keep *_TTStubsFromPhase2TrackerDigis_ClusterAccepted_*') + process.writeDataset.outputCommands.append('keep *_TTStubsFromPhase2TrackerDigis_StubAccepted_*') + process.writeDataset.outputCommands.append('keep *_CleanAssoc_AtLeastOneCluster_*') + + process.pd = cms.EndPath(process.writeDataset) + process.schedule.append(process.pd) \ No newline at end of file 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..2716d9d0564fc 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 @@ -25,6 +26,7 @@ namespace trackerDTC { public: DTC(const edm::ParameterSet& iConfig, const tt::Setup* setup, + const trackerTFP::DataFormats* dataFormats, const LayerEncoding* layerEncoding, int dtcId, const std::vector>& stubsDTC); @@ -43,6 +45,8 @@ namespace trackerDTC { Stub* pop_front(Stubs& stubs); // helper class to store configurations const tt::Setup* setup_; + // provides dataformats + const trackerTFP::DataFormats* dataFormats_; // enables emulation of truncation bool enableTruncation_; // outer tracker detector region [0-8] diff --git a/L1Trigger/TrackerDTC/interface/LayerEncoding.h b/L1Trigger/TrackerDTC/interface/LayerEncoding.h index 7e18cff679ba8..e1352f27859cc 100644 --- a/L1Trigger/TrackerDTC/interface/LayerEncoding.h +++ b/L1Trigger/TrackerDTC/interface/LayerEncoding.h @@ -5,7 +5,6 @@ #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 +18,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_); } diff --git a/L1Trigger/TrackerDTC/interface/Stub.h b/L1Trigger/TrackerDTC/interface/Stub.h index 1dde69828ff57..37d06f774ccd4 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,20 +17,30 @@ 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 edm::ParameterSet&, + 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: + public: // truncates double precision to f/w integer equivalent double digi(double value, double precision) const; // 64 bit stub in hybrid data format @@ -39,12 +49,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_; + const TTStubRef ttStubRef_; // chosen TT algorithm bool hybrid_; // passes pt and eta cut @@ -73,12 +85,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/ProducerED.cc b/L1Trigger/TrackerDTC/plugins/ProducerDTC.cc similarity index 56% rename from L1Trigger/TrackerDTC/plugins/ProducerED.cc rename to L1Trigger/TrackerDTC/plugins/ProducerDTC.cc index 8017496fc3358..299b2aec86c29 100644 --- a/L1Trigger/TrackerDTC/plugins/ProducerED.cc +++ b/L1Trigger/TrackerDTC/plugins/ProducerDTC.cc @@ -16,6 +16,7 @@ #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 @@ -26,18 +27,19 @@ using namespace std; using namespace edm; using namespace tt; +using namespace trackerTFP; namespace trackerDTC { - /*! \class trackerDTC::ProducerED + /*! \class trackerDTC::ProducerDTC * \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<> { + class ProducerDTC : public stream::EDProducer<> { public: - explicit ProducerED(const ParameterSet&); - ~ProducerED() override {} + explicit ProducerDTC(const ParameterSet&); + ~ProducerDTC() override {} private: void beginRun(const Run&, const EventSetup&) override; @@ -45,6 +47,8 @@ namespace trackerDTC { void endJob() {} // helper class to store configurations const Setup* setup_ = nullptr; + // helper class to extract structured data from tt::Frames + const DataFormats* dataFormats_ = nullptr; // class to encode layer ids used between DTC and TFP in Hybrid const LayerEncoding* layerEncoding_ = nullptr; // ED input token of TTStubs @@ -55,13 +59,15 @@ namespace trackerDTC { EDPutTokenT edPutTokenLost_; // Setup token ESGetToken esGetTokenSetup_; + // DataFormats token + ESGetToken esGetTokenDataFormats_; // LayerEncoding token ESGetToken esGetTokenLayerEncoding_; // configuration ParameterSet iConfig_; }; - ProducerED::ProducerED(const ParameterSet& iConfig) : iConfig_(iConfig) { + ProducerDTC::ProducerDTC(const ParameterSet& iConfig) : iConfig_(iConfig) { // book in- and output ED products const auto& inputTag = iConfig.getParameter("InputTag"); const auto& branchAccepted = iConfig.getParameter("BranchAccepted"); @@ -71,54 +77,49 @@ namespace trackerDTC { edPutTokenLost_ = produces(branchLost); // book ES products esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); esGetTokenLayerEncoding_ = esConsumes(); } - void ProducerED::beginRun(const Run& iRun, const EventSetup& iSetup) { + void ProducerDTC::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_); layerEncoding_ = &iSetup.getData(esGetTokenLayerEncoding_); } - void ProducerED::produce(Event& iEvent, const EventSetup& iSetup) { + void ProducerDTC::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); - } + // 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_, 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)); + iEvent.emplace(edPutTokenAccepted_, move(productAccepted)); + iEvent.emplace(edPutTokenLost_, move(productLost)); } } // namespace trackerDTC -DEFINE_FWK_MODULE(trackerDTC::ProducerED); +DEFINE_FWK_MODULE(trackerDTC::ProducerDTC); diff --git a/L1Trigger/TrackerDTC/plugins/ProducerLayerEncoding.cc b/L1Trigger/TrackerDTC/plugins/ProducerLayerEncoding.cc index 2adbd96ce57fd..89dedb601c2c0 100644 --- a/L1Trigger/TrackerDTC/plugins/ProducerLayerEncoding.cc +++ b/L1Trigger/TrackerDTC/plugins/ProducerLayerEncoding.cc @@ -26,18 +26,17 @@ namespace trackerDTC { unique_ptr produce(const LayerEncodingRcd& rcd); private: - const ParameterSet iConfig_; ESGetToken esGetToken_; }; - ProducerLayerEncoding::ProducerLayerEncoding(const ParameterSet& iConfig) : iConfig_(iConfig) { + ProducerLayerEncoding::ProducerLayerEncoding(const 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); + return 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..4576ecac6515a 100644 --- a/L1Trigger/TrackerDTC/python/Customize_cff.py +++ b/L1Trigger/TrackerDTC/python/Customize_cff.py @@ -1,14 +1,22 @@ +# function to manipilate TrackerDTC emulator to match TMTT configuration and support TMTT data formats + import FWCore.ParameterSet.Config as cms 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 + TrackerDTC_params.UseHybrid = False + process.TrackTriggerSetup.TrackFinding.MinPt = 3.0 + process.TrackTriggerSetup.TrackFinding.MaxEta = 2.4 + process.TrackTriggerSetup.TrackFinding.ChosenRofPhi = 67.24 + 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 + TrackerDTC_params.UseHybrid = False + process.TrackTriggerSetup.TrackFinding.MinPt = 3.0 + process.TrackTriggerSetup.TrackFinding.MaxEta = 2.4 + process.TrackTriggerSetup.TrackFinding.ChosenRofPhi = 67.24 + 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/ProducerED_cfi.py b/L1Trigger/TrackerDTC/python/DTC_cfi.py similarity index 77% rename from L1Trigger/TrackerDTC/python/ProducerED_cfi.py rename to L1Trigger/TrackerDTC/python/DTC_cfi.py index ba6303791d629..cdf8c69bc7075 100644 --- a/L1Trigger/TrackerDTC/python/ProducerED_cfi.py +++ b/L1Trigger/TrackerDTC/python/DTC_cfi.py @@ -1,11 +1,12 @@ +# configuration for ProducerDTC + import FWCore.ParameterSet.Config as cms -TrackerDTCProducer_params = cms.PSet ( +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 - 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/LayerEncoding_cff.py b/L1Trigger/TrackerDTC/python/LayerEncoding_cff.py new file mode 100644 index 0000000000000..5f8ec932fb2d2 --- /dev/null +++ b/L1Trigger/TrackerDTC/python/LayerEncoding_cff.py @@ -0,0 +1,3 @@ +import FWCore.ParameterSet.Config as cms + +TrackerDTCLayerEncoding = cms.ESProducer("trackerDTC::ProducerLayerEncoding") \ No newline at end of file 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..5884cc8efb2e7 100644 --- a/L1Trigger/TrackerDTC/src/DTC.cc +++ b/L1Trigger/TrackerDTC/src/DTC.cc @@ -8,15 +8,18 @@ using namespace std; using namespace edm; using namespace tt; +using namespace trackerTFP; namespace trackerDTC { DTC::DTC(const ParameterSet& iConfig, const Setup* setup, + const DataFormats* dataFormats, const LayerEncoding* layerEncoding, int dtcId, - const std::vector>& stubsDTC) + const vector>& stubsDTC) : setup_(setup), + dataFormats_(dataFormats), enableTruncation_(iConfig.getParameter("EnableTruncation")), region_(dtcId / setup->numDTCsPerRegion()), board_(dtcId % setup->numDTCsPerRegion()), @@ -33,7 +36,7 @@ namespace trackerDTC { if (ttStubRefs.empty()) continue; // Module which produced this ttStubRefs - SensorModule* module = modules_.at(modId); + const 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,7 +44,7 @@ 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(iConfig, setup, dataFormats, layerEncoding, module, ttStubRef); Stub& stub = stubs_.back(); if (stub.valid()) // passed pt and eta cut @@ -120,8 +123,8 @@ namespace trackerDTC { output.push_back(nullptr); } // truncate if desired - if (enableTruncation_ && (int)output.size() > setup_->numFramesIO()) { - const auto limit = next(output.begin(), setup_->numFramesIO()); + if (enableTruncation_ && (int)output.size() > setup_->numFramesIOHigh()) { + const auto limit = next(output.begin(), setup_->numFramesIOHigh()); copy_if(limit, output.end(), back_inserter(lost), [](Stub* stub) { return stub; }); output.erase(limit, output.end()); } @@ -151,9 +154,7 @@ 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) : FrameStub(); }; for (const Stubs& stubs : stubss) { StreamStub stream; stream.reserve(stubs.size()); diff --git a/L1Trigger/TrackerDTC/src/LayerEncoding.cc b/L1Trigger/TrackerDTC/src/LayerEncoding.cc index c72d8968c038e..4802bdca31dca 100644 --- a/L1Trigger/TrackerDTC/src/LayerEncoding.cc +++ b/L1Trigger/TrackerDTC/src/LayerEncoding.cc @@ -13,8 +13,7 @@ using namespace tt; namespace trackerDTC { - LayerEncoding::LayerEncoding(const ParameterSet& iConfig, const Setup* setup) - : setup_(setup), numDTCsPerRegion_(setup->numDTCsPerRegion()) { + LayerEncoding::LayerEncoding(const Setup* setup) : setup_(setup), numDTCsPerRegion_(setup->numDTCsPerRegion()) { encodingsLayerId_.reserve(numDTCsPerRegion_); for (int dtcInRegion = 0; dtcInRegion < setup->numDTCsPerRegion(); dtcInRegion++) { set encodingLayerId; @@ -36,7 +35,7 @@ namespace trackerDTC { } // decode layer id for given sensor module - int LayerEncoding::decode(SensorModule* sm) const { + int LayerEncoding::decode(const 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); diff --git a/L1Trigger/TrackerDTC/src/Stub.cc b/L1Trigger/TrackerDTC/src/Stub.cc index 3d8fda73d2574..7775e53277f74 100644 --- a/L1Trigger/TrackerDTC/src/Stub.cc +++ b/L1Trigger/TrackerDTC/src/Stub.cc @@ -8,129 +8,128 @@ using namespace edm; using namespace std; using namespace tt; +using namespace trackerTFP; 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 DataFormats* dataFormats, const 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()); + hybrid_(false), + valid_(true), + regions_(0, setup_->numOverlappingRegions()) { + const DataFormat& dfR = dataFormats_->format(Variable::r, Process::dtc); + const DataFormat& dfPhi = dataFormats_->format(Variable::phi, Process::dtc); + const DataFormat& dfZ = dataFormats_->format(Variable::z, Process::dtc); + const DataFormat& dfInv2R = dataFormats_->format(Variable::inv2R, 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_ = (int)floor(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_ = (int)floor(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_ = (int)floor(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_ = (int)floor((double)row_ / 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) * 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(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() + atan2(x0, d_); + const double phi1 = sm_->phi() + 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); + //static const double maxInv2R = dfInv2R.limit(); + static 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 = max(inv2R_.first, -maxInv2R); + inv2R_.second = 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); - 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 ParameterSet& iConfig, + const Setup* setup, + const DataFormats* dataFormats, + const LayerEncoding* layerEncoding, + const SensorModule* sm, + const TTStubRef& ttStubRef) + : setup_(setup), + dataFormats_(dataFormats), + layerEncoding_(layerEncoding), + sm_(sm), + ttStubRef_(ttStubRef), + hybrid_(iConfig.getParameter("UseHybrid")) { + 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 DataFormat& dfZT = dataFormats->format(Variable::zT, 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() * abs(1. - ratioRZ); + zT_ = {zT - dZT, zT + dZT}; + //if (abs(zT) > dfZT.limit() + dZT) + if (abs(zT) > dfZT.range() / 2. + dZT) + valid_ = false; // apply data format specific manipulations if (!hybrid_) 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) { @@ -138,7 +137,6 @@ namespace trackerDTC { 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())); @@ -147,13 +145,14 @@ namespace trackerDTC { } // 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(); } + FrameStub Stub::frame(int region) const { + return make_pair(ttStubRef_, hybrid_ ? 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 (floor(value / precision + 1.e-12) + .5) * precision; + } // returns 64 bit stub in hybrid data format Frame Stub::formatHybrid(int region) const { @@ -162,11 +161,10 @@ namespace trackerDTC { 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 == SensorModule::BarrelPS || type == 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); @@ -179,74 +177,33 @@ namespace trackerDTC { } 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()); + static const DataFormat& dfInv2R = dataFormats_->format(Variable::inv2R, Process::ht); + static const DataFormat& dfPhiT = dataFormats_->format(Variable::phiT, Process::gp); + static const DataFormat& dfZT = dataFormats_->format(Variable::zT, 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(Variable::layer, Process::dtc)); + if (sm_->barrel()) { + layer.set(4); + if (sm_->tilted()) + layer.set(3); + } else if (sm_->psModule()) + layer.set(3); + int phiTMin = max(dfPhiT.integer(phiT_.first - offset), -setup_->gpNumBinsPhiT() / 2); + int phiTMax = 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 = max(dfZT.integer(zT_.first), -setup_->gpNumBinsZT() / 2); + const int zTMax = min(dfZT.integer(zT_.second), setup_->gpNumBinsZT() / 2 - 1); + const int inv2RMin = max(dfInv2R.integer(inv2R_.first), -setup_->htNumBinsInv2R() / 2); + const int inv2RMax = min(dfInv2R.integer(inv2R_.second), setup_->htNumBinsInv2R() / 2 - 1); + const 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..e84af94d70646 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" @@ -48,9 +45,6 @@ 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}; @@ -77,51 +71,27 @@ namespace trackerDTC { 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>&); // 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 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_; + 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_; + EDGetTokenT edGetTokenTTDTCLost_; + // 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 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 Setup* setup_; // enables analyze of TPs bool useMCTruth_; // specifies used TT algorithm @@ -154,15 +124,13 @@ namespace trackerDTC { // book in- and output ED products const auto& inputTagAccepted = iConfig.getParameter("InputTagAccepted"); const auto& inputTagLost = iConfig.getParameter("InputTagLost"); - getTokenTTDTCAccepted_ = consumes(inputTagAccepted); - getTokenTTDTCLost_ = consumes(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(); @@ -174,42 +142,130 @@ namespace trackerDTC { void Analyzer::beginRun(const Run& iEvent, const EventSetup& iSetup) { // helper class to store configurations setup_ = &iSetup.getData(esGetToken_); - // configuring track particle selector - configTPSelector(); // book histograms - 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)); + } } void Analyzer::analyze(const Event& iEvent, const EventSetup& iSetup) { - // read in TrackingParticle - map> mapAllStubsTPs; - 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()); - } // read in dtc products Handle handleTTDTCAccepted; - iEvent.getByToken(getTokenTTDTCAccepted_, handleTTDTCAccepted); + iEvent.getByToken(edGetTokenTTDTCAccepted_, 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); + iEvent.getByToken(edGetTokenTTDTCLost_, handleTTDTCLost); + // read in MCTruth + const StubAssociation* selection = nullptr; + const StubAssociation* reconstructable = nullptr; + if (useMCTruth_) { + Handle handleSelection; + iEvent.getByToken(edGetTokenSelection_, handleSelection); + selection = handleSelection.product(); + 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_); + } + // analyze dtc products and find still reconstrucable TrackingParticles + set tpPtrs; + for (int region = 0; region < setup_->numRegions(); region++) { + int nStubs(0); + int nLost(0); + map> mapTPsTTStubs; + for (int channel = 0; channel < setup_->numDTCsPerTFP(); channel++) { + const StreamStub& accepted = handleTTDTCAccepted->stream(region, channel); + const 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 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, 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_++; } @@ -235,86 +291,7 @@ namespace trackerDTC { // 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()); + LogPrint(moduleDescription().moduleName()) << log_.str(); } // fills kinematic tp histograms @@ -332,37 +309,8 @@ namespace trackerDTC { 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) { + void Analyzer::fill(const StreamStub& stream, int region, int channel, int& sum, TH2F* th2f) { for (const FrameStub& frame : stream) { if (frame.first.isNull()) continue; @@ -379,27 +327,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); @@ -416,13 +344,13 @@ namespace trackerDTC { 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 + log_ << " Monte Carlo 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; + << 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 @@ -451,90 +379,6 @@ namespace trackerDTC { 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)); - } - } - } // namespace trackerDTC DEFINE_FWK_MODULE(trackerDTC::Analyzer); 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..9dd4b5415f83b 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 \ No newline at end of file diff --git a/L1Trigger/TrackerTFP/interface/CleanTrackBuilder.h b/L1Trigger/TrackerTFP/interface/CleanTrackBuilder.h new file mode 100644 index 0000000000000..46759124c401b --- /dev/null +++ b/L1Trigger/TrackerTFP/interface/CleanTrackBuilder.h @@ -0,0 +1,138 @@ +#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 edm::ParameterSet& iConfig, + 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; + // true if truncation is enbaled + bool enableTruncation_; + // 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_; + }; + +} // namespace trackerTFP + +#endif \ No newline at end of file diff --git a/L1Trigger/TrackerTFP/interface/DataFormats.h b/L1Trigger/TrackerTFP/interface/DataFormats.h index 054f97807e20f..5efe028546e24 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,41 +24,12 @@ 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 @@ -72,7 +42,10 @@ namespace trackerTFP { //Base class representing format of a variable class DataFormat { public: - DataFormat(bool twos) : twos_(twos), width_(0), base_(1.), range_(0.) {} + 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) {} ~DataFormat() {} // converts int to bitvector TTBV ttBV(int i) const { return TTBV(i, width_, twos_); } @@ -84,12 +57,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 +77,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.; } @@ -133,80 +110,70 @@ namespace trackerTFP { template class Format : public DataFormat { public: - Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format(const tt::Setup* setup); ~Format() {} }; 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); + Format::Format(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); + template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); + template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); + template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); + template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); + template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); + template <> - Format::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup); + Format::Format(const tt::Setup* setup); /*! \class trackerTFP::DataFormats * \brief Class to calculate and provide dataformats used by Track Trigger emulator @@ -217,295 +184,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(const tt::Setup* setup); ~DataFormats() {} - // bool indicating if hybrid or tmtt being used - bool hybrid() const { return iConfig_.getParameter("UseHybrid"); } // 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,16 +373,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; + 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); + } // configuration during construction edm::ParameterSet iConfig_; // stored run-time constants @@ -545,11 +417,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 +428,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()), 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 +451,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 +462,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_); }; - // 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(); - }; - - // class to represent stubs generated by process z hough transform - class StubZHT : 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_); } + // 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_); } - // 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_; + int zT() const { return std::get<5>(data_); }; }; - // class to represent stubs generated by process kfin - class StubKFin : public Stub { + // class to represent stubs generated by process CTB + class StubCTB : 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 +597,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 +618,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 +646,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()), 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 +668,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 +681,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..7f23fc960ef80 100644 --- a/L1Trigger/TrackerTFP/interface/Demonstrator.h +++ b/L1Trigger/TrackerTFP/interface/Demonstrator.h @@ -12,8 +12,8 @@ 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 { @@ -27,15 +27,17 @@ namespace trackerTFP { 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 +47,10 @@ namespace trackerTFP { std::string dirIPBB_; // runtime in ms double runTime_; + // + const std::vector linkMappingIn_; + // + const std::vector linkMappingOut_; // path to input text file std::string dirIn_; // path to output text file diff --git a/L1Trigger/TrackerTFP/interface/DuplicateRemoval.h b/L1Trigger/TrackerTFP/interface/DuplicateRemoval.h new file mode 100644 index 0000000000000..4ba4de46f9d51 --- /dev/null +++ b/L1Trigger/TrackerTFP/interface/DuplicateRemoval.h @@ -0,0 +1,58 @@ +#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 edm::ParameterSet& iConfig, + 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_; + }; + // true if truncation is enbaled + bool enableTruncation_; + // 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_; + }; + +} // namespace trackerTFP + +#endif \ No newline at end of file diff --git a/L1Trigger/TrackerTFP/interface/GeometricProcessor.h b/L1Trigger/TrackerTFP/interface/GeometricProcessor.h index 07fc8858c872f..97ef1a2882b35 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 @@ -16,33 +18,29 @@ namespace trackerTFP { GeometricProcessor(const edm::ParameterSet& iConfig, 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_; }; } // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/interface/HoughTransform.h b/L1Trigger/TrackerTFP/interface/HoughTransform.h index 680a76b325aa9..af13c702a6092 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,45 @@ 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 edm::ParameterSet& iConfig, + 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; - + void readOut(const std::vector& input, std::deque& output) const; + // + bool noTrack(const TTBV& pattern, int zT) const; // true if truncation is enbaled bool enableTruncation_; // 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_; }; } // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/interface/KalmanFilter.h b/L1Trigger/TrackerTFP/interface/KalmanFilter.h index d875f6ad7756f..8d148ce2515f8 100644 --- a/L1Trigger/TrackerTFP/interface/KalmanFilter.h +++ b/L1Trigger/TrackerTFP/interface/KalmanFilter.h @@ -3,48 +3,123 @@ #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: + typedef State::Stub Stub; KalmanFilter(const edm::ParameterSet& iConfig, 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); @@ -54,59 +129,20 @@ namespace trackerTFP { 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..1e3a35e1dee66 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,6 +61,22 @@ namespace trackerTFP { C22, C23, C33, + r0Shifted, + r1Shifted, + r02, + r12, + chi20, + chi21, + dH, + invdH, + invdH2, + H2, + Hm0, + Hm1, + Hv0, + Hv1, + H2v0, + H2v1, end, x }; @@ -67,26 +85,51 @@ namespace trackerTFP { class DataFormatKF { public: - DataFormatKF(const VariableKF& v, bool twos); + DataFormatKF(const VariableKF& v, bool twos, const edm::ParameterSet& iConfig); 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_; + }; + + class KalmanFilterFormats { + public: + KalmanFilterFormats(const edm::ParameterSet& iConfig); + ~KalmanFilterFormats() {} + void beginRun(const DataFormats* dataFormats); + const tt::Setup* setup() const { return dataFormats_->setup(); } + const DataFormats* dataFormats() const { return dataFormats_; } + DataFormatKF& format(VariableKF v) { return formats_[+v]; } + void endJob(); + + private: + template + void fillFormats(); + const edm::ParameterSet iConfig_; + const DataFormats* dataFormats_; + std::vector formats_; }; template @@ -97,6 +140,7 @@ namespace trackerTFP { private: void calcRange() { range_ = base_ * pow(2, width_); } + void calcWidth() { width_ = ceil(log2(range_ / base_) - 1.e-11); } }; template <> @@ -132,6 +176,14 @@ namespace trackerTFP { template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); @@ -171,30 +223,40 @@ namespace trackerTFP { FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& 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(); - - private: - template - void fillFormats(); - const edm::ParameterSet iConfig_; - const DataFormats* dataFormats_; - const tt::Setup* setup_; - std::vector formats_; - }; + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& 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..ef2642d4d2803 100644 --- a/L1Trigger/TrackerTFP/interface/LayerEncoding.h +++ b/L1Trigger/TrackerTFP/interface/LayerEncoding.h @@ -12,7 +12,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 +21,14 @@ 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; private: // helper class providing run-time constants @@ -44,13 +37,12 @@ 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 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..fcc67c4146def --- /dev/null +++ b/L1Trigger/TrackerTFP/interface/TrackFindingProcessor.h @@ -0,0 +1,89 @@ +#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 edm::ParameterSet& iConfig, + 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: + // + static constexpr int partial_width = 32; + // + static constexpr int partial_in = 3; + // + static constexpr int partial_out = 2; + // + typedef std::bitset PartialFrame; + // + typedef std::pair PartialFrameTrack; + // + 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; + // true if truncation is enbaled + bool enableTruncation_; + // 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_; + }; + +} // namespace trackerTFP + +#endif \ No newline at end of file diff --git a/L1Trigger/TrackerTFP/interface/TrackQuality.h b/L1Trigger/TrackerTFP/interface/TrackQuality.h new file mode 100644 index 0000000000000..276edae490a11 --- /dev/null +++ b/L1Trigger/TrackerTFP/interface/TrackQuality.h @@ -0,0 +1,160 @@ +/* +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 "L1Trigger/TrackerTFP/interface/TrackQualityRcd.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) { return VariableTQ(+v + 1); } + + // class representing format of a specific variable + template + class FormatTQ : public DataFormat { + public: + FormatTQ(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + ~FormatTQ() {} + + private: + void calcRange() { range_ = base_ * pow(2, width_); } + void calcWidth() { width_ = ceil(log2(range_ / base_) - 1.e-11); } + void calcBase() { base_ = range_ * pow(2, -width_); } + }; + template <> + FormatTQ::FormatTQ(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatTQ::FormatTQ(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatTQ::FormatTQ(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatTQ::FormatTQ(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatTQ::FormatTQ(const DataFormats* dataFormats, const edm::ParameterSet& iConfig); + template <> + FormatTQ::FormatTQ(const DataFormats* dataFormats, const edm::ParameterSet& 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 edm::ParameterSet& 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 edm::ParameterSet& 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_; + // + 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::TrackQualityRcd); + +#endif diff --git a/L1Trigger/TrackerTFP/interface/TrackQualityRcd.h b/L1Trigger/TrackerTFP/interface/TrackQualityRcd.h new file mode 100644 index 0000000000000..d65bd922c9393 --- /dev/null +++ b/L1Trigger/TrackerTFP/interface/TrackQualityRcd.h @@ -0,0 +1,17 @@ +#ifndef L1Trigger_TrackerTFP_TrackQualityRcd_h +#define L1Trigger_TrackerTFP_TrackQualityRcd_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 RcdsTrackQuality; + + // record of trackerTFP::TrackQuality + class TrackQualityRcd : public edm::eventsetup::DependentRecordImplementation {}; + +} // namespace trackerTFP + +#endif \ No newline at end of file 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..0f866014e1a4b --- /dev/null +++ b/L1Trigger/TrackerTFP/plugins/ProducerCTB.cc @@ -0,0 +1,246 @@ +#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 + +using namespace std; +using namespace edm; +using namespace tt; + +namespace trackerTFP { + + /*! \class trackerTFP::ProducerCTB + * \brief clean HT tracks and rrestructures them + * \author Thomas Schuh + * \date 2020, July + */ + class ProducerCTB : public stream::EDProducer<> { + public: + explicit ProducerCTB(const ParameterSet&); + ~ProducerCTB() override {} + + private: + void beginRun(const Run&, const EventSetup&) override; + void produce(Event&, const EventSetup&) override; + virtual void endJob() {} + // ED input token of Stubs + EDGetTokenT edGetToken_; + // ED output token for TTTracks + EDPutTokenT edPutTokenTTTracks_; + // ED output token for stubs + EDPutTokenT edPutTokenStubs_; + // ED output token for tracks + EDPutTokenT edPutTokenTracks_; + // 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; + // + const LayerEncoding* layerEncoding_ = nullptr; + // + bool enableTruncation_; + // + DataFormat cot_; + }; + + ProducerCTB::ProducerCTB(const ParameterSet& iConfig) : iConfig_(iConfig) { + const string& label = iConfig.getParameter("InputLabelCTB"); + const string& branchStubs = iConfig.getParameter("BranchStubs"); + const string& branchTracks = iConfig.getParameter("BranchTracks"); + // book in- and output ED products + edGetToken_ = consumes(InputTag(label, branchStubs)); + edPutTokenStubs_ = produces(branchStubs); + edPutTokenTTTracks_ = produces(branchTracks); + edPutTokenTracks_ = produces(branchTracks); + // book ES products + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + esGetTokenLayerEncoding_ = esConsumes(); + // + enableTruncation_ = iConfig.getParameter("EnableTruncation"); + } + + void ProducerCTB::beginRun(const Run& iRun, 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_); + // + layerEncoding_ = &iSetup.getData(esGetTokenLayerEncoding_); + // + 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 = ceil(log2(range / baseZ * baseR / setup_->ctbNumBinsCot())); + const int width = ceil(log2(setup_->ctbNumBinsCot())); + const double base = baseZ / baseR * pow(2, baseShift); + cot_ = DataFormat(true, width, base, range); + } + + void ProducerCTB::produce(Event& iEvent, const EventSetup& iSetup) { + static const int numChannelIn = dataFormats_->numChannel(Process::ht); + static const int numChannelOut = dataFormats_->numChannel(Process::ctb); + static const int numRegions = setup_->numRegions(); + static const int numLayers = setup_->numLayers(); + // empty output products + StreamsTrack acceptedTracks(numRegions * numChannelOut); + StreamsStub acceptedStubs(numRegions * numChannelOut * numLayers); + vector>> streamsTracks(numRegions, vector>(numChannelOut)); + vector>>> streamsStubs( + numRegions, vector>>(numChannelOut, vector>(numLayers))); + // read input Product and produce output product + Handle handleGet; + iEvent.getByToken(edGetToken_, handleGet); + const StreamsStub& streamsStub = *handleGet.product(); + // count stubs + int nStubsHT(0); + auto validFrame = [](int sum, const FrameStub& frame) { return sum += (frame.first.isNonnull() ? 1 : 0); }; + for (const StreamStub& stream : streamsStub) + nStubsHT += accumulate(stream.begin(), stream.end(), 0, validFrame); + // create input objects and count tracks + vector stubsHT; + stubsHT.reserve(nStubsHT); + // count stubs + int nTracksHT(0); + for (const StreamStub& stream : streamsStub) { + pair trackId({setup_->htNumBinsPhiT(), setup_->gpNumBinsZT()}); + for (const 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 + vector stubsCTB; + vector tracksCTB; + tracksCTB.reserve(nTracksHT); + stubsCTB.reserve(nStubsHT); + CleanTrackBuilder ctb(iConfig_, 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 + vector> streamsIn(numChannelIn); + for (int channelIn = 0; channelIn < numChannelIn; channelIn++) { + const StreamStub& channelStubs = streamsStub[offsetIn + channelIn]; + vector& stream = streamsIn[channelIn]; + stream.reserve(channelStubs.size()); + for (const FrameStub& frame : channelStubs) + stream.push_back(frame.first.isNull() ? nullptr : &stubsHT[iStub++]); + } + // empty h/w liked organized pointer to output data + vector>& regionTracks = streamsTracks[region]; + 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 vector>& channelStubs = regionStubs[channelOut]; + for (int layer = 0; layer < numLayers; layer++) { + StreamStub& accepted = acceptedStubs[offset + layer]; + const deque& layerStubs = channelStubs[layer]; + accepted.reserve(layerStubs.size()); + for (StubCTB* stub : layerStubs) + accepted.emplace_back(stub ? stub->frame() : FrameStub()); + } + } + } + // store TTTracks + int nTracks(0); + auto valid = [](int sum, TrackCTB* track) { return sum += (track ? 1 : 0); }; + for (const vector>& region : streamsTracks) + for (const deque& channel : region) + nTracks += accumulate(channel.begin(), channel.end(), 0, valid); + TTTracks ttTracks; + ttTracks.reserve(nTracks); + for (int region = 0; region < numRegions; region++) { + const vector>& regionTracks = streamsTracks[region]; + const vector>>& regionStubs = streamsStubs[region]; + for (int channelOut = 0; channelOut < numChannelOut; channelOut++) { + const deque& channelTracks = regionTracks[channelOut]; + const vector>& channelStubs = regionStubs[channelOut]; + for (int frame = 0; frame < (int)channelTracks.size(); frame++) { + TrackCTB* track = channelTracks[frame]; + if (!track) + continue; + const auto begin = next(channelTracks.begin(), frame); + const auto end = find_if(begin + 1, channelTracks.end(), [](TrackCTB* track) { return track; }); + const int size = distance(begin, end); + vector> stubs(numLayers); + for (int layer = 0; layer < numLayers; layer++) { + const deque& layerStubs = channelStubs[layer]; + 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 OrphanHandle handle = iEvent.emplace(edPutTokenTTTracks_, move(ttTracks)); + // add TTTrackRefs + int iTrk(0); + int iChan(0); + for (const vector>& region : streamsTracks) { + for (const deque& stream : region) { + StreamTrack& streamTrack = acceptedTracks[iChan++]; + for (TrackCTB* track : stream) { + if (!track) { + streamTrack.emplace_back(FrameTrack()); + continue; + } + FrameTrack frame = track->frame(); + frame.first = TTTrackRef(handle, iTrk++); + streamTrack.emplace_back(frame); + } + } + } + // store tracks + iEvent.emplace(edPutTokenTracks_, move(acceptedTracks)); + // store stubs + iEvent.emplace(edPutTokenStubs_, move(acceptedStubs)); + } + +} // namespace trackerTFP + +DEFINE_FWK_MODULE(trackerTFP::ProducerCTB); \ No newline at end of file diff --git a/L1Trigger/TrackerTFP/plugins/ProducerDR.cc b/L1Trigger/TrackerTFP/plugins/ProducerDR.cc new file mode 100644 index 0000000000000..3f4e07d945f11 --- /dev/null +++ b/L1Trigger/TrackerTFP/plugins/ProducerDR.cc @@ -0,0 +1,188 @@ +#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 + +using namespace std; +using namespace edm; +using namespace tt; + +namespace trackerTFP { + + /*! \class trackerTFP::ProducerDR + * \brief L1TrackTrigger duplicate removal emulator + * \author Thomas Schuh + * \date 2023, Feb + */ + class ProducerDR : public stream::EDProducer<> { + public: + explicit ProducerDR(const ParameterSet&); + ~ProducerDR() override {} + + private: + void beginRun(const Run&, const EventSetup&) override; + void produce(Event&, const EventSetup&) override; + void endStream() override {} + // ED input token of sf stubs and tracks + EDGetTokenT edGetTokenStubs_; + EDGetTokenT edGetTokenTracks_; + // ED output token for accepted stubs and tracks + EDPutTokenT edPutTokenStubs_; + EDPutTokenT edPutTokenTracks_; + // 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; + }; + + ProducerDR::ProducerDR(const ParameterSet& iConfig) : iConfig_(iConfig) { + const string& label = iConfig.getParameter("InputLabelDR"); + const string& branchStubs = iConfig.getParameter("BranchStubs"); + const string& branchTracks = iConfig.getParameter("BranchTracks"); + // book in- and output ED products + edGetTokenStubs_ = consumes(InputTag(label, branchStubs)); + edGetTokenTracks_ = consumes(InputTag(label, branchTracks)); + edPutTokenStubs_ = produces(branchStubs); + edPutTokenTracks_ = produces(branchTracks); + // book ES products + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + } + + void ProducerDR::beginRun(const Run& iRun, 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_); + } + + void ProducerDR::produce(Event& iEvent, const EventSetup& iSetup) { + static const int numChannelIn = dataFormats_->numChannel(Process::kf); + static const int numChannelOut = dataFormats_->numChannel(Process::dr); + static const int numRegions = setup_->numRegions(); + static const int numLayers = setup_->numLayers(); + // empty DR products + StreamsStub acceptedStubs(numRegions * numChannelOut * numLayers); + StreamsTrack acceptedTracks(numRegions * numChannelOut); + // read in KF Product and produce DR product + Handle handleStubs; + iEvent.getByToken(edGetTokenStubs_, handleStubs); + const StreamsStub& allStubs = *handleStubs; + Handle handleTracks; + iEvent.getByToken(edGetTokenTracks_, handleTracks); + const StreamsTrack& allTracks = *handleTracks; + // helper + auto validFrameT = [](int sum, const FrameTrack& frame) { return sum += (frame.first.isNonnull() ? 1 : 0); }; + auto validFrameS = [](int sum, const FrameStub& frame) { return sum += (frame.first.isNonnull() ? 1 : 0); }; + auto putT = [](const vector& objects, StreamTrack& stream) { + auto toFrame = [](TrackDR* object) { return object ? object->frame() : FrameTrack(); }; + stream.reserve(objects.size()); + transform(objects.begin(), objects.end(), back_inserter(stream), toFrame); + }; + auto putS = [](const vector& objects, StreamStub& stream) { + auto toFrame = [](StubDR* object) { return object ? object->frame() : FrameStub(); }; + stream.reserve(objects.size()); + transform(objects.begin(), objects.end(), 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 StreamTrack& tracks = allTracks[index]; + nTracks += accumulate(tracks.begin(), tracks.end(), 0, validFrameT); + for (int layer = 0; layer < numLayers; layer++) { + const StreamStub& stubs = allStubs[offset + layer]; + nStubs += accumulate(stubs.begin(), stubs.end(), 0, validFrameS); + } + } + // storage of input data + vector tracksKF; + tracksKF.reserve(nTracks); + vector stubsKF; + stubsKF.reserve(nStubs); + // h/w liked organized pointer to input data + vector> regionTracks(numChannelIn); + 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 StreamTrack& streamTrack = allTracks[index]; + vector& tracks = regionTracks[channelIn]; + tracks.reserve(streamTrack.size()); + for (const 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 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 + vector tracksDR; + tracksDR.reserve(nTracks); + vector stubsDR; + stubsDR.reserve(nStubs); + // object to remove duplicates in a processing region + DuplicateRemoval dr(iConfig_, setup_, dataFormats_, tracksDR, stubsDR); + // empty h/w liked organized pointer to output data + vector> streamsTrack(numChannelOut); + 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_, move(acceptedStubs)); + iEvent.emplace(edPutTokenTracks_, move(acceptedTracks)); + } + +} // namespace trackerTFP + +DEFINE_FWK_MODULE(trackerTFP::ProducerDR); \ No newline at end of file diff --git a/L1Trigger/TrackerTFP/plugins/ProducerES.cc b/L1Trigger/TrackerTFP/plugins/ProducerDataFormats.cc similarity index 67% rename from L1Trigger/TrackerTFP/plugins/ProducerES.cc rename to L1Trigger/TrackerTFP/plugins/ProducerDataFormats.cc index 4e308c80851ad..2dbf3922af8f1 100644 --- a/L1Trigger/TrackerTFP/plugins/ProducerES.cc +++ b/L1Trigger/TrackerTFP/plugins/ProducerDataFormats.cc @@ -14,15 +14,15 @@ 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 ESProducer { public: - ProducerES(const ParameterSet& iConfig); - ~ProducerES() override {} + ProducerDataFormats(const ParameterSet& iConfig); + ~ProducerDataFormats() override {} unique_ptr produce(const DataFormatsRcd& rcd); private: @@ -30,16 +30,16 @@ namespace trackerTFP { ESGetToken esGetToken_; }; - ProducerES::ProducerES(const ParameterSet& iConfig) : iConfig_(iConfig) { + ProducerDataFormats::ProducerDataFormats(const ParameterSet& iConfig) { auto cc = setWhatProduced(this); esGetToken_ = cc.consumes(); } - unique_ptr ProducerES::produce(const DataFormatsRcd& rcd) { + unique_ptr ProducerDataFormats::produce(const DataFormatsRcd& rcd) { const Setup* setup = &rcd.get(esGetToken_); - return make_unique(iConfig_, setup); + return 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..894cd93eca986 100644 --- a/L1Trigger/TrackerTFP/plugins/ProducerDemonstrator.cc +++ b/L1Trigger/TrackerTFP/plugins/ProducerDemonstrator.cc @@ -13,7 +13,8 @@ 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 */ 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..0cb5e0ada264a 100644 --- a/L1Trigger/TrackerTFP/plugins/ProducerGP.cc +++ b/L1Trigger/TrackerTFP/plugins/ProducerGP.cc @@ -10,14 +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 +#include +#include +#include +#include +#include using namespace std; using namespace edm; @@ -39,69 +43,113 @@ namespace trackerTFP { 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_; + // ED input token of pp objects + EDGetTokenT edGetToken_; + // ED output token for accepted objects + EDPutTokenT edPutToken_; // Setup token ESGetToken esGetTokenSetup_; // DataFormats token ESGetToken esGetTokenDataFormats_; + // LayerEncoding token + ESGetToken esGetTokenLayerEncoding_; // 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; + // helper class to encode layer + const LayerEncoding* layerEncoding_ = nullptr; }; 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"); + const string& label = iConfig.getParameter("InputLabelGP"); + const string& branch = iConfig.getParameter("BranchStubs"); // book in- and output ED products - edGetToken_ = consumes(InputTag(label, branchAccepted)); - edPutTokenAccepted_ = produces(branchAccepted); - edPutTokenLost_ = produces(branchLost); + edGetToken_ = consumes(InputTag(label, branch)); + edPutToken_ = produces(branch); // book ES products 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_); + // helper class to encode layer + layerEncoding_ = &iSetup.getData(esGetTokenLayerEncoding_); } void ProducerGP::produce(Event& iEvent, const EventSetup& iSetup) { + static const int numChannelIn = dataFormats_->numChannel(Process::pp); + static const int numChannelOut = dataFormats_->numChannel(Process::gp); + static const int numRegions = setup_->numRegions(); // empty GP products - StreamsStub accepted(dataFormats_->numStreams(Process::gp)); - StreamsStub lost(dataFormats_->numStreams(Process::gp)); + 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); + Handle handle; + iEvent.getByToken(edGetToken_, handle); + const StreamsStub& streamsStub = *handle.product(); + // helper + auto validFrame = [](int sum, const 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() : 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 StreamStub& stream = streamsStub[offsetIn + channelIn]; + nStubsPP += accumulate(stream.begin(), stream.end(), 0, validFrame); + } + // storage of input data + vector stubsPP; + stubsPP.reserve(nStubsPP); + // h/w liked organized pointer to input data + vector> streamsIn(numChannelIn); + // read input data + for (int channelIn = 0; channelIn < numChannelIn; channelIn++) { + const StreamStub& streamStub = streamsStub[offsetIn + channelIn]; + vector& stream = streamsIn[channelIn]; + stream.reserve(streamStub.size()); + for (const 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 = accumulate(stubsPP.begin(), stubsPP.end(), 0, nSectors); + // container of GP stubs + vector stubsGP; + stubsGP.reserve(nStubsGP); + // object to route Stubs of one region to one stream per sector + GeometricProcessor gp(iConfig_, setup_, dataFormats_, layerEncoding_, stubsGP); + // empty h/w liked organized pointer to output data + vector> streamsOut(numChannelOut); + // fill output data + gp.produce(streamsIn, streamsOut); + // convert data to ed products + for (int channelOut = 0; channelOut < numChannelOut; channelOut++) { + const deque& objects = streamsOut[channelOut]; + StreamStub& stream = accepted[offsetOut + channelOut]; + stream.reserve(objects.size()); + transform(objects.begin(), objects.end(), back_inserter(stream), toFrame); } } // store products - iEvent.emplace(edPutTokenAccepted_, std::move(accepted)); - iEvent.emplace(edPutTokenLost_, std::move(lost)); + iEvent.emplace(edPutToken_, move(accepted)); } } // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/plugins/ProducerHT.cc b/L1Trigger/TrackerTFP/plugins/ProducerHT.cc index 15a9701b7ac14..c509f04679078 100644 --- a/L1Trigger/TrackerTFP/plugins/ProducerHT.cc +++ b/L1Trigger/TrackerTFP/plugins/ProducerHT.cc @@ -13,10 +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 +#include +#include using namespace std; using namespace edm; @@ -38,71 +43,107 @@ namespace trackerTFP { 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_; + EDPutTokenT edPutToken_; // 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; + // + const LayerEncoding* layerEncoding_ = nullptr; }; 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"); + const string& label = iConfig.getParameter("InputLabelHT"); + const string& branch = iConfig.getParameter("BranchStubs"); // book in- and output ED products - edGetToken_ = consumes(InputTag(label, branchAccepted)); - edPutTokenAccepted_ = produces(branchAccepted); - edPutTokenLost_ = produces(branchLost); + edGetToken_ = consumes(InputTag(label, branch)); + edPutToken_ = produces(branch); // book ES products esGetTokenSetup_ = esConsumes(); esGetTokenDataFormats_ = esConsumes(); + esGetTokenLayerEncoding_ = esConsumes(); } void ProducerHT::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_); + // + layerEncoding_ = &iSetup.getData(esGetTokenLayerEncoding_); } void ProducerHT::produce(Event& iEvent, const EventSetup& iSetup) { + static const int numChannelIn = dataFormats_->numChannel(Process::gp); + static const int numChannelOut = dataFormats_->numChannel(Process::ht); + static const int numRegions = setup_->numRegions(); // empty HT products - StreamsStub accepted(dataFormats_->numStreams(Process::ht)); - StreamsStub lost(dataFormats_->numStreams(Process::ht)); + 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); + Handle handle; + iEvent.getByToken(edGetToken_, handle); + const StreamsStub& streamsStub = *handle.product(); + // helper + auto validFrame = [](int sum, const FrameStub& frame) { return sum += (frame.first.isNonnull() ? 1 : 0); }; + auto toFrame = [](StubHT* object) { return object ? object->frame() : 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 StreamStub& stream = streamsStub[offsetIn + channelIn]; + nStubsGP += accumulate(stream.begin(), stream.end(), 0, validFrame); + } + // storage of input data + vector stubsGP; + stubsGP.reserve(nStubsGP); + // h/w liked organized pointer to input data + vector> streamsIn(numChannelIn); + // read input data + for (int channelIn = 0; channelIn < numChannelIn; channelIn++) { + const StreamStub& streamStub = streamsStub[offsetIn + channelIn]; + vector& stream = streamsIn[channelIn]; + stream.reserve(streamStub.size()); + for (const 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 + vector stubsHT; + // object to find initial rough candidates in r-phi in a region + HoughTransform ht(iConfig_, setup_, dataFormats_, layerEncoding_, stubsHT); + // empty h/w liked organized pointer to output data + vector> streamsOut(numChannelOut); + // fill output data + ht.produce(streamsIn, streamsOut); + // convert data to ed products + for (int channelOut = 0; channelOut < numChannelOut; channelOut++) { + const deque& objects = streamsOut[channelOut]; + StreamStub& stream = accepted[offsetOut + channelOut]; + stream.reserve(objects.size()); + transform(objects.begin(), objects.end(), back_inserter(stream), toFrame); } } // store products - iEvent.emplace(edPutTokenAccepted_, std::move(accepted)); - iEvent.emplace(edPutTokenLost_, std::move(lost)); + iEvent.emplace(edPutToken_, move(accepted)); } } // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/plugins/ProducerKF.cc b/L1Trigger/TrackerTFP/plugins/ProducerKF.cc index ce123005215ae..1f603c11c32cd 100644 --- a/L1Trigger/TrackerTFP/plugins/ProducerKF.cc +++ b/L1Trigger/TrackerTFP/plugins/ProducerKF.cc @@ -18,6 +18,8 @@ #include "L1Trigger/TrackerTFP/interface/KalmanFilter.h" #include +#include +#include using namespace std; using namespace edm; @@ -36,111 +38,182 @@ namespace trackerTFP { ~ProducerKF() override {} private: + typedef State::Stub Stub; void beginRun(const Run&, const EventSetup&) override; void produce(Event&, const EventSetup&) override; void endStream() override { if (printDebug_) - kalmanFilterFormats_->endJob(); + kalmanFilterFormats_.endJob(); } - // ED input token of sf stubs and tracks EDGetTokenT edGetTokenStubs_; 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_; + EDPutTokenT edPutTokenStubs_; + EDPutTokenT edPutTokenTracks_; // ED output token for number of accepted and lost States - EDPutTokenT edPutTokenNumAcceptedStates_; - EDPutTokenT edPutTokenNumLostStates_; + EDPutTokenT edPutTokenNumStatesAccepted_; + EDPutTokenT edPutTokenNumStatesTruncated_; + // ED output token for chi2s in r-phi and r-z plane + EDPutTokenT>> edPutTokenChi2s_; // Setup token ESGetToken esGetTokenSetup_; // DataFormats token ESGetToken esGetTokenDataFormats_; - // KalmanFilterFormats token - ESGetToken esGetTokenKalmanFilterFormats_; + // 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 - KalmanFilterFormats* kalmanFilterFormats_ = nullptr; + // helper class to encode layer + const LayerEncoding* layerEncoding_ = nullptr; + // helper class to tune internal kf variables + KalmanFilterFormats kalmanFilterFormats_; // print end job internal unused MSB bool printDebug_; }; - ProducerKF::ProducerKF(const ParameterSet& iConfig) : iConfig_(iConfig) { + ProducerKF::ProducerKF(const ParameterSet& iConfig) : iConfig_(iConfig), kalmanFilterFormats_(iConfig) { 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 string& label = iConfig.getParameter("InputLabelKF"); + const string& branchStubs = iConfig.getParameter("BranchStubs"); + const string& branchTracks = iConfig.getParameter("BranchTracks"); + const 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(InputTag(label, branchStubs)); + edGetTokenTracks_ = consumes(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(); + 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_)); + // helper class to encode layer + layerEncoding_ = &iSetup.getData(esGetTokenLayerEncoding_); + // helper class to tune internal kf variables + kalmanFilterFormats_.beginRun(dataFormats_); } void ProducerKF::produce(Event& iEvent, const EventSetup& iSetup) { + static const int numChannel = dataFormats_->numChannel(Process::kf); + static const int numRegions = setup_->numRegions(); + static const int numLayers = setup_->numLayers(); // 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); + StreamsStub acceptedStubs(numRegions * numChannel * numLayers); + StreamsTrack acceptedTracks(numRegions * numChannel); + int numStatesAccepted(0); + int numStatesTruncated(0); + 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); + Handle handleStubs; + iEvent.getByToken(edGetTokenStubs_, handleStubs); + const StreamsStub& allStubs = *handleStubs; + Handle handleTracks; + iEvent.getByToken(edGetTokenTracks_, handleTracks); + const StreamsTrack& allTracks = *handleTracks; + // helper + auto validFrameT = [](int sum, const FrameTrack& frame) { return sum += (frame.first.isNonnull() ? 1 : 0); }; + auto validFrameS = [](int sum, const FrameStub& frame) { return sum += (frame.first.isNonnull() ? 1 : 0); }; + auto putT = [](const vector& objects, StreamTrack& stream) { + auto toFrame = [](TrackKF* object) { return object ? object->frame() : FrameTrack(); }; + stream.reserve(objects.size()); + transform(objects.begin(), objects.end(), back_inserter(stream), toFrame); + }; + auto putS = [](const vector& objects, StreamStub& stream) { + auto toFrame = [](StubKF* object) { return object ? object->frame() : FrameStub(); }; + stream.reserve(objects.size()); + transform(objects.begin(), objects.end(), 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 StreamTrack& tracks = allTracks[index]; + nTracks += accumulate(tracks.begin(), tracks.end(), 0, validFrameT); + for (int layer = 0; layer < numLayers; layer++) { + const StreamStub& stubs = allStubs[offsetStubs + layer]; + nStubs += accumulate(stubs.begin(), stubs.end(), 0, validFrameS); + } + } + // storage of input data + vector tracksCTB; + tracksCTB.reserve(nTracks); + vector stubs; + stubs.reserve(nStubs); + // h/w liked organized pointer to input data + vector> regionTracks(numChannel); + 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 StreamTrack& streamTrack = allTracks[index]; + vector& tracks = regionTracks[channel]; + tracks.reserve(streamTrack.size()); + for (const 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 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 + vector tracksKF; + tracksKF.reserve(nTracks); + vector stubsKF; + stubsKF.reserve(nStubs); + // object to fit tracks in a processing region + KalmanFilter kf(iConfig_, setup_, dataFormats_, layerEncoding_, &kalmanFilterFormats_, tracksKF, stubsKF); + // empty h/w liked organized pointer to output data + vector> streamsTrack(numChannel); + vector>> streamsStub(numChannel, 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_, move(acceptedStubs)); + iEvent.emplace(edPutTokenTracks_, 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/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..374b6f7430de7 --- /dev/null +++ b/L1Trigger/TrackerTFP/plugins/ProducerPP.cc @@ -0,0 +1,81 @@ +#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 + +using namespace std; +using namespace edm; +using namespace tt; + +namespace trackerTFP { + + /*! \class trackerTFP::ProducerPP + * \brief L1TrackTrigger PatchPanel between DTC and TFP emulator + * \author Thomas Schuh + * \date 2023, April + */ + class ProducerPP : public stream::EDProducer<> { + public: + explicit ProducerPP(const ParameterSet&); + ~ProducerPP() 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 edPutToken_; + // Setup token + ESGetToken esGetTokenSetup_; + // configuration + ParameterSet iConfig_; + // helper classe to store configurations + const Setup* setup_ = nullptr; + }; + + ProducerPP::ProducerPP(const ParameterSet& iConfig) : iConfig_(iConfig) { + const string& label = iConfig.getParameter("InputLabelPP"); + const string& branch = iConfig.getParameter("BranchStubs"); + // book in- and output ED products + edGetToken_ = consumes(InputTag(label, branch)); + edPutToken_ = produces(branch); + // book ES products + esGetTokenSetup_ = esConsumes(); + } + + void ProducerPP::beginRun(const Run& iRun, const EventSetup& iSetup) { setup_ = &iSetup.getData(esGetTokenSetup_); } + + void ProducerPP::produce(Event& iEvent, const EventSetup& iSetup) { + // empty GP products + StreamsStub stubs(setup_->numRegions() * setup_->numDTCsPerTFP()); + // read in DTC Product and produce TFP product + Handle handle; + iEvent.getByToken(edGetToken_, handle); + const TTDTC& ttDTC = *handle.product(); + 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_, move(stubs)); + } + +} // namespace trackerTFP + +DEFINE_FWK_MODULE(trackerTFP::ProducerPP); \ No newline at end of file diff --git a/L1Trigger/TrackerTFP/plugins/ProducerTFP.cc b/L1Trigger/TrackerTFP/plugins/ProducerTFP.cc new file mode 100644 index 0000000000000..7351fa40af5b1 --- /dev/null +++ b/L1Trigger/TrackerTFP/plugins/ProducerTFP.cc @@ -0,0 +1,120 @@ +#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 + +using namespace std; +using namespace edm; +using namespace tt; + +namespace trackerTFP { + + /*! \class trackerTFP::ProducerTFP + * \brief L1TrackTrigger final TFP output formatter + * \author Thomas Schuh + * \date 2023, June + */ + class ProducerTFP : public stream::EDProducer<> { + public: + explicit ProducerTFP(const ParameterSet&); + ~ProducerTFP() override {} + + private: + void beginRun(const Run&, const EventSetup&) override; + void produce(Event&, const EventSetup&) override; + void endStream() override {} + // ED input token of stubs and tracks + EDGetTokenT edGetTokenTracks_; + EDGetTokenT edGetTokenStubs_; + // ED output token for accepted stubs and tracks + EDPutTokenT edPutTokenTTTracks_; + EDPutTokenT edPutTokenTracks_; + // Setup token + ESGetToken esGetTokenSetup_; + // DataFormats token + ESGetToken esGetTokenDataFormats_; + // TrackQuality token + ESGetToken esGetTokenTrackQuality_; + // 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 determine track quality + const TrackQuality* trackQuality_ = nullptr; + }; + + ProducerTFP::ProducerTFP(const ParameterSet& iConfig) : iConfig_(iConfig) { + const string& labelTracks = iConfig.getParameter("InputLabelTFP"); + const string& labelStubs = iConfig.getParameter("InputLabelTQ"); + const string& branchTracks = iConfig.getParameter("BranchTracks"); + const string& branchTTTracks = iConfig.getParameter("BranchTTTracks"); + const string& branchStubs = iConfig.getParameter("BranchStubs"); + // book in- and output ED products + edGetTokenTracks_ = consumes(InputTag(labelTracks, branchTracks)); + edGetTokenStubs_ = consumes(InputTag(labelStubs, branchStubs)); + edPutTokenTTTracks_ = produces(branchTTTracks); + edPutTokenTracks_ = produces(branchTracks); + // book ES products + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + esGetTokenTrackQuality_ = esConsumes(); + } + + void ProducerTFP::beginRun(const Run& iRun, 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 determine track quality + trackQuality_ = &iSetup.getData(esGetTokenTrackQuality_); + } + + void ProducerTFP::produce(Event& iEvent, const EventSetup& iSetup) { + // empty TFP products + TTTracks ttTracks; + StreamsTrack streamsTrack(setup_->numRegions() * setup_->tfpNumChannel()); + // read in TQ Products + Handle handleTracks; + iEvent.getByToken(edGetTokenTracks_, handleTracks); + Handle handleStubs; + iEvent.getByToken(edGetTokenStubs_, handleStubs); + // produce TTTracks + TrackFindingProcessor tfp(iConfig_, setup_, dataFormats_, trackQuality_); + tfp.produce(*handleTracks, *handleStubs, ttTracks, streamsTrack); + // put TTTRacks and produce TTTRackRefs + const int nTrks = ttTracks.size(); + const OrphanHandle oh = iEvent.emplace(edPutTokenTTTracks_, move(ttTracks)); + 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_, move(streamsTrack)); + } + +} // namespace trackerTFP + +DEFINE_FWK_MODULE(trackerTFP::ProducerTFP); \ No newline at end of file diff --git a/L1Trigger/TrackerTFP/plugins/ProducerTQ.cc b/L1Trigger/TrackerTFP/plugins/ProducerTQ.cc new file mode 100644 index 0000000000000..59f09e078ce93 --- /dev/null +++ b/L1Trigger/TrackerTFP/plugins/ProducerTQ.cc @@ -0,0 +1,154 @@ +#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 + +using namespace std; +using namespace edm; +using namespace tt; +using namespace trackerTFP; + +namespace trackerTFP { + + /*! \class trackerTFP::ProducerTQ + * \brief Bit accurate emulation of the track quality BDT + * \author Thomas Schuh + * \date 2024, Aug + */ + class ProducerTQ : public stream::EDProducer<> { + public: + explicit ProducerTQ(const ParameterSet&); + ~ProducerTQ() override {} + void beginRun(const Run&, const EventSetup&) override; + void produce(Event&, const EventSetup&) override; + void endJob() {} + + private: + typedef TrackQuality::Track Track; + // ED input token of kf stubs + EDGetTokenT edGetTokenStubs_; + // ED input token of kf tracks + EDGetTokenT edGetTokenTracks_; + // ED output token for tracks + EDPutTokenT edPutTokenTracks_; + // ED output token for additional track variables + EDPutTokenT edPutTokenTracksAdd_; + // ED output token for stubs + EDPutTokenT edPutTokenStubs_; + // Setup token + ESGetToken esGetTokenSetup_; + // DataFormats token + ESGetToken esGetTokenDataFormats_; + // TrackQuality token + ESGetToken esGetTokenTrackQuality_; + // 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 determine Track Quality + const TrackQuality* trackQuality_ = nullptr; + }; + + ProducerTQ::ProducerTQ(const ParameterSet& iConfig) { + const string& label = iConfig.getParameter("InputLabelTQ"); + const string& branchStubs = iConfig.getParameter("BranchStubs"); + const string& branchTracks = iConfig.getParameter("BranchTracks"); + // book in- and output ED products + edGetTokenStubs_ = consumes(InputTag(label, branchStubs)); + edGetTokenTracks_ = consumes(InputTag(label, branchTracks)); + edPutTokenTracks_ = produces(branchTracks); + edPutTokenTracksAdd_ = produces(branchTracks); + edPutTokenStubs_ = produces(branchStubs); + // book ES products + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + esGetTokenTrackQuality_ = esConsumes(); + } + + void ProducerTQ::beginRun(const Run& iRun, 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 determine Track Quality + trackQuality_ = &iSetup.getData(esGetTokenTrackQuality_); + } + + void ProducerTQ::produce(Event& iEvent, const EventSetup& iSetup) { + static const int numRegions = setup_->numRegions(); + static const int numLayers = setup_->numLayers(); + auto valid = [](int sum, const FrameTrack& frame) { return sum += (frame.first.isNull() ? 0 : 1); }; + // empty TQ product + StreamsTrack outputTracks(numRegions); + Streams outputTracksAdd(numRegions); + StreamsStub outputStubs(numRegions * numLayers); + // read in KF Product and produce TQ product + Handle handleStubs; + iEvent.getByToken(edGetTokenStubs_, handleStubs); + const StreamsStub& streamsStubs = *handleStubs.product(); + Handle handleTracks; + iEvent.getByToken(edGetTokenTracks_, handleTracks); + const StreamsTrack& streamsTracks = *handleTracks.product(); + for (int region = 0; region < numRegions; region++) { + // calculate track quality + const int offsetLayer = region * numLayers; + const StreamTrack& streamTrack = streamsTracks[region]; + const int nTracks = accumulate(streamTrack.begin(), streamTrack.end(), 0, valid); + vector tracks; + tracks.reserve(nTracks); + vector stream; + stream.reserve(streamTrack.size()); + for (int frame = 0; frame < (int)streamTrack.size(); frame++) { + const FrameTrack& frameTrack = streamTrack[frame]; + if (frameTrack.first.isNull()) { + stream.push_back(nullptr); + continue; + } + StreamStub streamStub; + streamStub.reserve(numLayers); + for (int layer = 0; layer < 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(FrameTrack()); + outputTracksAdd[region].emplace_back(Frame()); + for (int layer = 0; layer < setup_->numLayers(); layer++) + outputStubs[offsetLayer + layer].emplace_back(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_, move(outputTracks)); + iEvent.emplace(edPutTokenTracksAdd_, 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..048e97a01d5df --- /dev/null +++ b/L1Trigger/TrackerTFP/plugins/ProducerTrackQuality.cc @@ -0,0 +1,39 @@ +#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 + +using namespace std; +using namespace edm; + +namespace trackerTFP { + + /*! \class trackerTFP::ProducerTrackQuality + * \brief Class to produce TrackQuality of Track Trigger emulators + * \author Thomas Schuh + * \date 2024, July + */ + class ProducerTrackQuality : public ESProducer { + public: + ProducerTrackQuality(const ParameterSet& iConfig) : iConfig_(iConfig) { + auto cc = setWhatProduced(this); + esGetToken_ = cc.consumes(); + } + ~ProducerTrackQuality() override {} + unique_ptr produce(const TrackQualityRcd& trackQualityRcd) { + const DataFormats* dataFormats = &trackQualityRcd.get(esGetToken_); + return make_unique(iConfig_, dataFormats); + } + + private: + const ParameterSet iConfig_; + 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..ba543b4b0c36f 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 + process.TrackTriggerSetup.TMTT.WidthPhi = 14 + process.TrackTriggerSetup.TMTT.WidthZ = 13 + process.TrackTriggerSetup.TrackFinding.MinPt = 3.0 + process.TrackTriggerSetup.TrackFinding.MaxEta = 2.4 + process.TrackTriggerSetup.TrackFinding.ChosenRofPhi = 67.24 + process.TrackTriggerSetup.TrackFinding.NumLayers = 8 + process.TrackTriggerSetup.GeometricProcessor.ChosenRofZ = 57.76 + process.TrackTriggerSetup.HoughTransform.MinLayers = 5 + process.TrackTriggerSetup.CleanTrackBuilder.MaxStubs = 4 + process.TrackTriggerSetup.KalmanFilter.NumWorker = 4 + process.TrackTriggerSetup.KalmanFilter.MaxLayers = 8 + process.TrackTriggerSetup.KalmanFilter.MaxSeedingLayer = 3 + process.TrackTriggerSetup.KalmanFilter.MaxGaps = 2 + process.TrackTriggerSetup.KalmanFilter.ShiftChi20 = 0 + process.TrackTriggerSetup.KalmanFilter.ShiftChi21 = 0 + process.TrackTriggerSetup.KalmanFilter.CutChi2 = 2.0 + +def simUseTMTT(process): + process.StubAssociator.MinPt = 3.0 + + return process diff --git a/L1Trigger/TrackerTFP/python/DataFormats_cff.py b/L1Trigger/TrackerTFP/python/DataFormats_cff.py new file mode 100644 index 0000000000000..095cdd6771103 --- /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") \ No newline at end of file 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..fa695a4a0cdb2 100644 --- a/L1Trigger/TrackerTFP/python/KalmanFilterFormats_cfi.py +++ b/L1Trigger/TrackerTFP/python/KalmanFilterFormats_cfi.py @@ -6,70 +6,63 @@ TrackTriggerKalmanFilterFormats_params = cms.PSet ( - 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 ) - ), + EnableIntegerEmulation = cms.bool( True ), - 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 ) - ), + WidthR00 = cms.int32( 20 ), + WidthR11 = cms.int32( 20 ), + + WidthC00 = cms.int32( 20 ), + WidthC01 = cms.int32( 20 ), + WidthC11 = cms.int32( 20 ), + WidthC22 = cms.int32( 20 ), + WidthC23 = cms.int32( 20 ), + WidthC33 = cms.int32( 20 ), + + 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 ), + + 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 ), + + 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..7bc742aac993a --- /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") \ No newline at end of file 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..7a6880dc42e4a 100644 --- a/L1Trigger/TrackerTFP/python/Producer_cfi.py +++ b/L1Trigger/TrackerTFP/python/Producer_cfi.py @@ -1,24 +1,22 @@ +# 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 + EnableTruncation = cms.bool ( True ), # enable emulation of truncation, lost stubs are filled in BranchLost + 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..133389c0e6a34 --- /dev/null +++ b/L1Trigger/TrackerTFP/python/TrackQuality_cff.py @@ -0,0 +1,12 @@ +# 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) + +fakeTrackTriggerTrackQualitySource = cms.ESSource("EmptyESSource", + recordName = cms.string('trackerTFP::TrackQualityRcd'), + iovIsRunNotTime = cms.bool(True), + firstValid = cms.vuint32(1) +) 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..e798decedcd31 --- /dev/null +++ b/L1Trigger/TrackerTFP/src/CleanTrackBuilder.cc @@ -0,0 +1,489 @@ +#include "L1Trigger/TrackerTFP/interface/CleanTrackBuilder.h" + +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace edm; +using namespace tt; + +namespace trackerTFP { + + CleanTrackBuilder::CleanTrackBuilder(const ParameterSet& iConfig, + const Setup* setup, + const DataFormats* dataFormats, + const LayerEncoding* layerEncoding, + const DataFormat& cot, + vector& stubs, + vector& tracks) + : enableTruncation_(iConfig.getParameter("EnableTruncation")), + setup_(setup), + dataFormats_(dataFormats), + layerEncoding_(layerEncoding), + cot_(cot), + stubsCTB_(stubs), + tracksCTB_(tracks) { + stubs_.reserve(stubs.capacity()); + tracks_.reserve(tracks.capacity()); + } + + // fill output products + void CleanTrackBuilder::produce(const vector>& streamsIn, + vector>& regionTracks, + vector>>& regionStubs) { + static const int numChannelIn = dataFormats_->numChannel(Process::ht); + static const int numChannelOut = dataFormats_->numChannel(Process::ctb); + static const int numChannel = numChannelIn / numChannelOut; + static const int numLayers = setup_->numLayers(); + // loop over worker + for (int channelOut = 0; channelOut < numChannelOut; channelOut++) { + //if (channelOut != 3) + //continue; + // clean input tracks + vector> streamsT(numChannel); + vector> streamsS(numChannel); + for (int cin = 0; cin < numChannel; cin++) { + //if (cin != 1) + //continue; + const int index = numChannel * cin + channelOut; + cleanStream(streamsIn[index], streamsT[cin], streamsS[cin], index); + } + // route + deque tracks; + vector> stubs(numLayers); + route(streamsT, tracks); + route(streamsS, stubs); + // sort + sort(tracks, stubs); + // convert + deque& channelTracks = regionTracks[channelOut]; + vector>& channelStubs = regionStubs[channelOut]; + convert(tracks, stubs, channelTracks, channelStubs); + } + } + + // + void CleanTrackBuilder::cleanStream(const vector& input, + deque& tracks, + deque& stubs, + int channelId) { + static 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) { + 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(); + }; + 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 = find_if(start, input.end(), different); + const vector track(start, end); + // restore clock accurancy + delta += (int)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 vector& track, deque& tracks, deque& stubs, double inv2R, int zT, int trackId) { + static const int wlayer = dataFormats_->width(Variable::layer, Process::ctb); + static const DataFormat& dfR = dataFormats_->format(Variable::r, Process::ctb); + static const DataFormat& dfPhi = dataFormats_->format(Variable::phi, Process::ctb); + static const DataFormat& dfZ = dataFormats_->format(Variable::z, Process::ctb); + static const DataFormat& dfPhiT = dataFormats_->format(Variable::phiT, Process::ctb); + static const DataFormat& dfZT = dataFormats_->format(Variable::zT, Process::ctb); + static const int numBinsInv2R = setup_->ctbNumBinsInv2R(); + static const int numBinsPhiT = setup_->ctbNumBinsPhiT(); + static const int numBinsCot = setup_->ctbNumBinsCot(); + static const int numBinsZT = setup_->ctbNumBinsZT(); + static const double baseInv2R = dataFormats_->base(Variable::inv2R, Process::ctb) / numBinsInv2R; + static const double basePhiT = dfPhiT.base() / numBinsPhiT; + static const double baseCot = cot_.base(); + static const double baseZT = dfZT.base() / numBinsZT; + 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 < setup_->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 = [](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) * abs(inv2R); + return dfPhi.digi(dPhi / 2.); + }; + auto toDZ = [this](StubHT* stub) { + static const double m = setup_->tiltApproxSlope(); + static 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 = dfZT.floating(stub->zT()); + const double cot = abs(zT) / setup_->chosenRofZ(); + const double dZ = (barrel ? (tilt ? m * cot + c : 1.) : cot) * pitchCol; + return dfZ.digi(dZ / 2.); + }; + vector tStubs; + tStubs.reserve(track.size()); + vector hitPatternPhi(numBinsInv2R * numBinsPhiT, TTBV(0, setup_->numLayers())); + vector hitPatternZ(numBinsCot * numBinsZT, TTBV(0, setup_->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 = floor(*min_element(phiTs.begin(), phiTs.end()) / basePhiT + 1.e-11) + numBinsPhiT / 2; + const int binPhiTMax = floor(*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 = dfR.digi(stub->r() + dfR.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 = floor(*min_element(zTs.begin(), zTs.end()) / baseZT + 1.e-11) + numBinsZT / 2; + const int binZTMax = floor(*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, 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 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) { + vector stubIds(setup->numLayers(), 0); + for (Stub* stub : stubs_) + stub->update(hitsPhi_, hitsZ_, stubIds, setup->ctbMaxStubs()); + const int nLayer = + accumulate(stubIds.begin(), stubIds.end(), 0, [](int sum, int i) { return sum += (i > 0 ? 1 : 0); }); + if (nLayer < setup->ctbMinLayers()) + valid_ = false; + size_ = *max_element(stubIds.begin(), stubIds.end()); + } + + // + void CleanTrackBuilder::route(vector>& input, vector>& outputs) const { + for (int channelOut = 0; channelOut < (int)outputs.size(); channelOut++) { + deque& output = outputs[channelOut]; + vector> inputs(input); + for (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); + } + 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 (!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(); })) { + // fill input fifos + for (int channel = 0; channel < (int)input.size(); channel++) { + deque& stack = stacks[channel]; + Stub* stub = pop_front(inputs[channel]); + if (stub) { + if (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 < (int)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(vector>& inputs, deque& output) const { + 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 (!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 < (int)inputs.size(); channel++) { + deque& stack = stacks[channel]; + Track* track = pop_front(inputs[channel]); + if (track && track->valid_) { + if (enableTruncation_ && (int)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 < (int)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(deque& tracks, vector>& stubs) const { + // aplly truncation + if (enableTruncation_) { + if ((int)tracks.size() > setup_->numFramesHigh()) + tracks.resize(setup_->numFramesHigh()); + for (deque& stream : stubs) + if ((int)stream.size() > setup_->numFramesHigh()) + stream.resize(setup_->numFramesHigh()); + } + // cycle event, remove all gaps + tracks.erase(remove(tracks.begin(), tracks.end(), nullptr), tracks.end()); + for (deque& stream : stubs) + stream.erase(remove(stream.begin(), stream.end(), nullptr), stream.end()); + // prepare sort according to track id arrival order + vector trackIds; + trackIds.reserve(tracks.size()); + transform(tracks.begin(), tracks.end(), back_inserter(trackIds), [](Track* track) { return track->trackId_; }); + auto cleaned = [&trackIds](Stub* stub) { + return find(trackIds.begin(), trackIds.end(), stub->trackId_) == trackIds.end(); + }; + 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 distance(r, l) < 0; + }; + for (deque& stream : stubs) { + // remove stubs from removed tracks + stream.erase(remove_if(stream.begin(), stream.end(), cleaned), stream.end()); + // sort according to stub id on layer + stable_sort(stream.begin(), stream.end(), [](Stub* lhs, Stub* rhs) { return lhs->stubId_ < rhs->stubId_; }); + // sort according to track id arrival order + stable_sort(stream.begin(), stream.end(), order); + } + // add all gaps + const int size = + 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(next(tracks.begin(), frame + 1), length - 1, nullptr); + for (int layer = 0; layer < setup_->numLayers(); layer++) { + deque& stream = stubs[layer]; + if (frame >= (int)stream.size()) { + stream.insert(stream.end(), length, nullptr); + continue; + } + const auto begin = next(stream.begin(), frame); + const auto end = find_if(begin, stream.end(), [trackId](Stub* stub) { return stub->trackId_ != trackId; }); + stream.insert(end, length - distance(begin, end), nullptr); + } + frame += length; + } + } + + // + void CleanTrackBuilder::convert(const deque& iTracks, + const vector>& iStubs, + deque& oTracks, + vector>& oStubs) { + for (int iFrame = 0; iFrame < (int)iTracks.size();) { + Track* track = iTracks[iFrame]; + if (!track) { + oTracks.push_back(nullptr); + for (deque& stubs : oStubs) + stubs.push_back(nullptr); + iFrame++; + continue; + } + StubHT* s = nullptr; + for (int layer = 0; layer < setup_->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(deque& ts) const { + T* t = nullptr; + if (!ts.empty()) { + t = ts.front(); + ts.pop_front(); + } + return t; + } + + void CleanTrackBuilder::put(TrackCTB* track, + const vector>& stubs, + int region, + TTTracks& ttTracks) const { + static const double dPhi = dataFormats_->format(Variable::phiT, Process::ctb).range(); + const double invR = -track->inv2R() * 2.; + const double phi0 = deltaPhi(track->phiT() - track->inv2R() * setup_->chosenRofPhi() + region * dPhi); + const double zT = track->zT(); + const double cot = zT / setup_->chosenRofZ(); + TTBV hits(0, setup_->numLayers()); + double chi2phi(0.); + double chi2z(0.); + const int nStubs = accumulate( + stubs.begin(), stubs.end(), 0, [](int sum, const vector& layer) { return sum += layer.size(); }); + vector ttStubRefs; + ttStubRefs.reserve(nStubs); + for (int layer = 0; layer < setup_->numLayers(); layer++) { + for (StubCTB* stub : stubs[layer]) { + hits.set(layer); + chi2phi += pow(stub->phi(), 2) / pow(stub->dPhi(), 2); + chi2z += 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..044adc5d7a61b 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,6 +9,7 @@ #include #include #include +#include using namespace std; using namespace edm; @@ -16,17 +17,16 @@ using namespace tt; 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); } @@ -43,8 +43,7 @@ namespace trackerTFP { } // proper constructor - DataFormats::DataFormats(const ParameterSet& iConfig, const Setup* setup) : DataFormats() { - iConfig_ = iConfig; + DataFormats::DataFormats(const Setup* setup) : DataFormats() { setup_ = setup; fillDataFormats(); for (const Process p : Processes) @@ -57,31 +56,24 @@ 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(Format(setup_)); fillFormats(); } if constexpr (++p != Process::end) @@ -100,802 +92,207 @@ namespace trackerTFP { 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; - } - 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())); + Format::Format(const Setup* setup) : DataFormat(true) { + width_ = TTTrack_TrackWord::TrackBitWidths::kRinvSize; + range_ = -2. * TTTrack_TrackWord::minRinv; + base_ = range_ * pow(2, -width_); } - 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())); + Format::Format(const Setup* setup) : DataFormat(true) { + width_ = TTTrack_TrackWord::TrackBitWidths::kPhiSize; + range_ = -2. * TTTrack_TrackWord::minPhi0; + base_ = range_ * pow(2, -width_); } - 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())); + Format::Format(const Setup* setup) : DataFormat(true) { + width_ = TTTrack_TrackWord::TrackBitWidths::kTanlSize; + range_ = -2. * TTTrack_TrackWord::minTanl; + base_ = range_ * pow(2, -width_); } - 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())); + Format::Format(const Setup* setup) : DataFormat(true) { + width_ = TTTrack_TrackWord::TrackBitWidths::kZ0Size; + range_ = -2. * TTTrack_TrackWord::minZ0; + base_ = range_ * pow(2, -width_); } template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { - const double chosenRofPhi = - iConfig.getParameter("UseHybrid") ? setup->hybridChosenRofPhi() : setup->chosenRofPhi(); + Format::Format(const Setup* setup) : DataFormat(true) { + const Format phiT(setup); + const Format inv2R(setup); width_ = setup->tmttWidthR(); - range_ = 2. * max(abs(setup->outerRadius() - chosenRofPhi), abs(setup->innerRadius() - chosenRofPhi)); - const Format phiT(iConfig, setup); - const Format inv2R(iConfig, setup); + range_ = 2. * setup->maxRphi(); base_ = phiT.base() / inv2R.base(); - const int shift = ceil(log2(range_ / base_ / pow(2., width_))); + const int shift = ceil(log2(range_ / base_)) - width_; base_ *= pow(2., shift); } - - 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_)); - } - template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) { + Format::Format(const Setup* setup) : DataFormat(true) { + const Format phiT(setup); + const Format inv2R(setup); 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_))); + range_ = phiT.range() + inv2R.range() * setup->maxRphi(); + const int shift = ceil(log2(range_ / phiT.base())) - width_; base_ = phiT.base() * pow(2., shift); } - 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_)); + Format::Format(const Setup* setup) : DataFormat(true) { + const Format zT(setup); + width_ = setup->tmttWidthZ(); + range_ = 2. * setup->halfLength(); + const int shift = ceil(log2(range_ / zT.base())) - width_; + base_ = zT.base() * pow(2., shift); } - 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_)); + Format::Format(const Setup* setup) : DataFormat(false) { + width_ = 5; } 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(); + Format::Format(const Setup* setup) : DataFormat(true) { + const Format phi(setup); + const Format inv2R(setup); + const Format phiT(setup); base_ = phi.base(); + range_ = phiT.base() + inv2R.range() * setup->maxRphi(); width_ = ceil(log2(range_ / base_)); } - 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); + Format::Format(const Setup* setup) : DataFormat(true) { + const Format z(setup); + const Format zT(setup); + const double rangeCot = (zT.base() + 2. * setup->beamWindowZ()) / setup->chosenRofZ(); + base_ = z.base(); + range_ = zT.base() + rangeCot * setup->maxRz(); + width_ = ceil(log2(range_ / base_)); } - 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_)); + Format::Format(const Setup* setup) : DataFormat(true) { + range_ = 2. * M_PI / setup->numRegions(); + width_ = ceil(log2(setup->gpNumBinsPhiT())); + base_ = range_ / pow(2., width_); } - 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); + Format::Format(const Setup* setup) : DataFormat(true) { + range_ = 2. * sinh(setup->maxEta()) * setup->chosenRofZ(); + base_ = range_ / setup->gpNumBinsZT(); + width_ = ceil(log2(setup->gpNumBinsZT())); } - 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); + Format::Format(const Setup* setup) : DataFormat(true) { + const Format zT(setup); + const Format r(setup); + width_ = setup->widthDSPbb(); + range_ = (zT.range() - zT.base() + 2. * setup->beamWindowZ()) / setup->chosenRofZ(); + base_ = zT.base() / r.base(); + const int baseShift = ceil(log2(range_ / base_)) - width_; + base_ *= pow(2, baseShift); } - 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();*/ + Format::Format(const Setup* setup) : DataFormat(false) { + width_ = 6; } 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(); + Format::Format(const Setup* setup) : DataFormat(true) { + const Format phi(setup); + const Format phiT(setup); + const Format inv2R(setup); + range_ = phiT.base() + setup->maxRphi() * inv2R.base(); + base_ = phi.base(); width_ = ceil(log2(range_ / base_)); } - 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(); + Format::Format(const Setup* setup) : DataFormat(true) { + range_ = 2. * setup->invPtToDphi() / setup->minPt(); + base_ = range_ / (double)setup->htNumBinsInv2R(); + width_ = ceil(log2(setup->htNumBinsInv2R())); + } + template <> + Format::Format(const Setup* setup) : DataFormat(true) { + const Format phiT(setup); + range_ = phiT.range(); + base_ = phiT.base() / (double)setup->htNumBinsPhiT(); 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(); + Format::Format(const Setup* setup) : DataFormat(false) { + const Format phi(setup); + const Format inv2R(setup); + const double sigma = setup->pitchRowPS() / 2. / setup->innerRadius(); + const double pt = (setup->pitchCol2S() + setup->scattering()) / 2. * inv2R.range() / 2.; + range_ = sigma + pt; + base_ = phi.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(); + Format::Format(const Setup* setup) : DataFormat(false) { + const Format z(setup); + range_ = setup->pitchCol2S() / 2. * sinh(setup->maxEta()); 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) { + Format::Format(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_)); - } - - template <> - Format::Format(const ParameterSet& iConfig, const Setup* setup) - : DataFormat(false) { - range_ = setup->numSectorsPhi(); - width_ = setup->numSectorsPhi(); - } - - 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); - } - - 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); - } - - 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); - } - - 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(); + Format::Format(const Setup* setup) : DataFormat(true) { + const Format tfp(setup); + const Format ht(setup); + range_ = ht.range() + 2. * ht.base(); + base_ = ht.base() * pow(2., floor(log2(.5 * tfp.base() / ht.base()))); width_ = ceil(log2(range_ / base_)); } - 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(); + Format::Format(const Setup* setup) : DataFormat(true) { + const Format tfp(setup); + const Format ht(setup); + range_ = ht.range() + 2. * ht.base(); + base_ = ht.base() * pow(2., floor(log2(tfp.base() / ht.base()))); width_ = ceil(log2(range_ / base_)); } - 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(); + Format::Format(const Setup* setup) : DataFormat(true) { + const Format tfp(setup); + const Format zT(setup); + const Format r(setup); + range_ = (zT.base() + 2. * setup->beamWindowZ()) / setup->chosenRofZ(); + base_ = zT.base() / r.base() * pow(2., floor(log2(tfp.base() / zT.base() * r.base()))); width_ = ceil(log2(range_ / base_)); } - 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(); + Format::Format(const Setup* setup) : DataFormat(true) { + const Format tfp(setup); + const Format gp(setup); + range_ = gp.range(); + base_ = gp.base() * pow(2., floor(log2(tfp.base() / gp.base()))); width_ = ceil(log2(range_ / base_)); } - template <> - Format::Format(const edm::ParameterSet& iConfig, const Setup* setup) - : DataFormat(false) { - const Format phi(iConfig, setup); - range_ = setup->maxdPhi(); + Format::Format(const Setup* setup) : DataFormat(true) { + const Format phi(setup); + const Format phiT(setup); + const Format inv2R(setup); + range_ = phiT.base() + setup->maxRphi() * inv2R.base(); base_ = phi.base(); width_ = ceil(log2(range_ / base_)); } + template <> + Format::Format(const Setup* setup) : DataFormat(false) { + width_ = 1; + } template <> - Format::Format(const edm::ParameterSet& iConfig, const Setup* setup) - : DataFormat(false) { - const Format z(iConfig, setup); - range_ = setup->maxdZ(); - base_ = z.base(); + Format::Format(const Setup* setup) : DataFormat(true) { + const Format kf(setup); + const Format zT(setup); + range_ = (zT.range() + 2. * setup->beamWindowZ()) / setup->chosenRofZ(); + base_ = kf.base(); width_ = ceil(log2(range_ / base_)); } diff --git a/L1Trigger/TrackerTFP/src/Demonstrator.cc b/L1Trigger/TrackerTFP/src/Demonstrator.cc index 86a6e5d727246..a1c6433f60d76 100644 --- a/L1Trigger/TrackerTFP/src/Demonstrator.cc +++ b/L1Trigger/TrackerTFP/src/Demonstrator.cc @@ -1,9 +1,11 @@ #include "L1Trigger/TrackerTFP/interface/Demonstrator.h" #include +#include #include #include #include +#include using namespace std; using namespace edm; @@ -14,54 +16,79 @@ namespace trackerTFP { Demonstrator::Demonstrator(const ParameterSet& iConfig, const Setup* setup) : dirIPBB_(iConfig.getParameter("DirIPBB")), runTime_(iConfig.getParameter("RunTime")), + linkMappingIn_(iConfig.getParameter>("LinkMappingIn")), + linkMappingOut_(iConfig.getParameter>("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; + // default link mapping + auto linkMapping = [this](const vector& mapC, vector& map, const vector>& data) { + if (mapC.empty()) { + map.resize((int)data.size() / numRegions_); + iota(map.begin(), map.end(), 0); + } else + map = mapC; + }; // converts input into stringstream - convert(input, ss); + stringstream ss; + 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 vector>& bits, stringstream& ss, const 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; + set quads; + for (int channel : mapping) + quads.insert(channel / quad); + 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 " << string(TTBV::S_ / 4, '0'); + else { + const vector& bvs = bits[offset + distance(mapping.begin(), channel)]; + ss << (frame < (int)bvs.size() ? hex(bvs[frame], first) : hex(Frame(), first)); + } } - for (int channel = 0; channel < voidChannel; channel++) - ss << " 0000 " << string(TTBV::S_ / 4, '0'); ss << endl; first = false; } @@ -107,15 +134,15 @@ namespace trackerTFP { } // creates emp file header - string Demonstrator::header(int numLinks) const { + string Demonstrator::header(const vector& links) const { stringstream ss; // file header - ss << "Board CMSSW" << endl + ss << "Id: CMSSW" << endl << "Metadata: (strobe,) start of orbit, start of packet, end of packet, valid" << endl << endl; // link header ss << " Link "; - for (int link = 0; link < numLinks; link++) + for (int link : links) ss << " " << setfill('0') << setw(3) << link << " "; ss << endl; return ss.str(); diff --git a/L1Trigger/TrackerTFP/src/DuplicateRemoval.cc b/L1Trigger/TrackerTFP/src/DuplicateRemoval.cc new file mode 100644 index 0000000000000..14cec5751399e --- /dev/null +++ b/L1Trigger/TrackerTFP/src/DuplicateRemoval.cc @@ -0,0 +1,142 @@ +#include "L1Trigger/TrackerTFP/interface/DuplicateRemoval.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace edm; +using namespace tt; + +namespace trackerTFP { + + DuplicateRemoval::DuplicateRemoval(const ParameterSet& iConfig, + const Setup* setup, + const DataFormats* dataFormats, + vector& tracks, + vector& stubs) + : enableTruncation_(iConfig.getParameter("EnableTruncation")), + setup_(setup), + dataFormats_(dataFormats), + tracks_(tracks), + stubs_(stubs) {} + + // fill output products + void DuplicateRemoval::produce(const vector>& tracksIn, + const vector>& stubsIn, + vector>& tracksOut, + vector>& stubsOut) { + static const int numChannel = dataFormats_->numChannel(Process::kf); + static const int numLayers = setup_->numLayers(); + static const int numInv2R = setup_->htNumBinsInv2R() + 2; + static const int numPhiT = setup_->htNumBinsPhiT() * setup_->gpNumBinsPhiT(); + static const int numZT = setup_->gpNumBinsZT(); + int nTracks(0); + for (const vector& tracks : tracksIn) + nTracks += + accumulate(tracks.begin(), tracks.end(), 0, [](int sum, TrackKF* track) { return sum += track ? 1 : 0; }); + vector tracks; + tracks.reserve(nTracks); + deque stream; + // merge 4 channel to 1 + //for (int channel = 0; channel < numChannel; channel++ ) { + for (int channel = numChannel - 1; channel >= 0; channel--) { + const int offset = channel * numLayers; + const vector& tracksChannel = tracksIn[channel]; + for (int frame = 0; frame < (int)tracksChannel.size(); frame++) { + TrackKF* track = tracksChannel[frame]; + if (!track) { + stream.push_back(nullptr); + continue; + } + 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 (enableTruncation_ && (int)stream.size() > setup_->numFramesHigh()) { + const auto limit = next(stream.begin(), setup_->numFramesHigh()); + stream.erase(limit, stream.end()); + } + // remove duplicates + vector killed; + killed.reserve(stream.size()); + vector> hits(numZT, 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 (enableTruncation_ && (int)stream.size() > setup_->numFramesHigh()) { + const auto limit = 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 (vector& layer : stubsOut) + layer.reserve(stream.size()); + for (Track* track : stream) { + if (!track) { + tracksOut[0].push_back(nullptr); + for (vector& layer : stubsOut) + layer.push_back(nullptr); + continue; + } + static 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++) { + 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 \ No newline at end of file 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..ce4c6a786d677 --- /dev/null +++ b/L1Trigger/TrackerTFP/src/ES_TrackQuality.cc @@ -0,0 +1,5 @@ +#include "FWCore/Utilities/interface/typelookup.h" +#include "L1Trigger/TrackerTFP/interface/TrackQuality.h" + +TYPELOOKUP_DATA_REG(trackerTFP::TrackQuality); +TYPELOOKUP_DATA_REG(trackerTFP::TrackQualityRcd); diff --git a/L1Trigger/TrackerTFP/src/GeometricProcessor.cc b/L1Trigger/TrackerTFP/src/GeometricProcessor.cc index fd0ffaa44a084..f17d9177ade63 100644 --- a/L1Trigger/TrackerTFP/src/GeometricProcessor.cc +++ b/L1Trigger/TrackerTFP/src/GeometricProcessor.cc @@ -15,108 +15,108 @@ namespace trackerTFP { GeometricProcessor::GeometricProcessor(const ParameterSet& iConfig, const Setup* setup, const DataFormats* dataFormats, - int region) + const LayerEncoding* layerEncoding, + std::vector& stubs) : 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); - } + layerEncoding_(layerEncoding), + stubs_(stubs) {} // 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 vector>& streamsIn, vector>& streamsOut) { + static const int numChannelIn = dataFormats_->numChannel(Process::pp); + static const int numChannelOut = dataFormats_->numChannel(Process::gp); + 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 + vector> inputs(numChannelIn); + for (int channelIn = 0; channelIn < numChannelIn; channelIn++) { + const vector& streamIn = streamsIn[channelIn]; + transform(streamIn.begin(), streamIn.end(), back_inserter(inputs[channelIn]), valid); + } + // fifo for each stream + vector> stacks(streamsIn.size()); + // output stream + 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(); })) { // 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++) { + deque& stack = stacks[channelIn]; + StubPP* stub = pop_front(inputs[channelIn]); if (stub) { - stubsGP_.emplace_back(*stub, sectorPhi, sectorEta); + // convert stub + StubGP* stubGP = produce(*stub, phiT, zT); + // buffer overflow if (enableTruncation_ && (int)stack.size() == setup_->gpDepthMemory() - 1) - lostSector.push_back(pop_front(stack)); - stack.push_back(&stubsGP_.back()); + 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 = numChannelIn - 1; channelIn >= 0; channelIn--) { + 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 (enableTruncation_ && (int)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) { + static const DataFormat& dfPhiT = dataFormats_->format(Variable::phiT, Process::gp); + static const DataFormat& dfZT = dataFormats_->format(Variable::zT, Process::gp); + static const DataFormat& dfCot = dataFormats_->format(Variable::cot, Process::gp); + static const DataFormat& dfR = dataFormats_->format(Variable::r, Process::gp); + static const DataFormat& dfL = dataFormats_->format(Variable::layer, Process::gp); + const double cot = dfCot.digi(dfZT.floating(zT) / setup_->chosenRofZ()); + // determine kf layer id + const vector& le = layerEncoding_->layerEncoding(zT); + const int layerId = setup_->layerId(stub.frame().first); + const auto it = find(le.begin(), le.end(), layerId); + const int kfLayerId = min((int)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 { diff --git a/L1Trigger/TrackerTFP/src/HoughTransform.cc b/L1Trigger/TrackerTFP/src/HoughTransform.cc index 5995285b06a9c..c6da54733705b 100644 --- a/L1Trigger/TrackerTFP/src/HoughTransform.cc +++ b/L1Trigger/TrackerTFP/src/HoughTransform.cc @@ -5,8 +5,6 @@ #include #include #include -#include -#include #include using namespace std; @@ -18,186 +16,197 @@ namespace trackerTFP { HoughTransform::HoughTransform(const ParameterSet& iConfig, const Setup* setup, const DataFormats* dataFormats, - int region) + const LayerEncoding* layerEncoding, + vector& stubs) : enableTruncation_(iConfig.getParameter("EnableTruncation")), 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) {} // 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 vector>& streamsIn, vector>& streamsOut) { + static const int numChannelIn = dataFormats_->numChannel(Process::gp); + static const int numChannelOut = dataFormats_->numChannel(Process::ht); + static const int chan = setup_->kfNumWorker(); + static const int mux = numChannelOut / chan; + // 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 vector& input : streamsIn) + nStubs += 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); + deque& output = streamsOut[channelOut]; + for (int channelIn = numChannelIn - 1; channelIn >= 0; channelIn--) { + const vector& input = streamsIn[channelIn]; + 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 (enableTruncation_ && (int)stubs.size() > setup_->numFramesHigh()) + stubs.resize(setup_->numFramesHigh()); + // ht collects all stubs before readout starts -> remove all gaps + stubs.erase(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 (enableTruncation_ && (int)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 vector& input, vector& output) { + static 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](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 + deque delay(latency, nullptr); // fifo, used to store stubs which belongs to a second possible track deque stack; + // stream of incroming stubs + deque stream; + transform(input.begin(), input.end(), 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() || + !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 ((int)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 (enableTruncation_ && (int)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 vector& input, deque& output) const { + auto toBinPhiT = [this](StubHT* stub) { + static 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) { + static 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()); + // found phiTs, ordered in time + 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, this](StubHT* stub) { return toBinPhiT(stub) == phiT; }; + // read out stubs in reverse order to emulate f/w (backtracking linked list) + copy_if(input.rbegin(), input.rend(), 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 @@ -211,4 +220,4 @@ namespace trackerTFP { return t; } -} // namespace trackerTFP +} // namespace trackerTFP \ No newline at end of file diff --git a/L1Trigger/TrackerTFP/src/KalmanFilter.cc b/L1Trigger/TrackerTFP/src/KalmanFilter.cc index 7b64f0a1f00e9..853da1da4f123 100644 --- a/L1Trigger/TrackerTFP/src/KalmanFilter.cc +++ b/L1Trigger/TrackerTFP/src/KalmanFilter.cc @@ -18,192 +18,282 @@ namespace trackerTFP { KalmanFilter::KalmanFilter(const ParameterSet& iConfig, const Setup* setup, const DataFormats* dataFormats, + const LayerEncoding* layerEncoding, KalmanFilterFormats* kalmanFilterFormats, - int region) + vector& tracks, + vector& stubs) : enableTruncation_(iConfig.getParameter("EnableTruncation")), 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 vector>& tracksIn, + const vector>& stubsIn, + vector>& tracksOut, + 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, + deque>& chi2s) { for (int channel = 0; channel < dataFormats_->numChannel(Process::kf); channel++) { deque stream; - deque lost; // 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 (enableTruncation_ && (int)stream.size() > setup_->numFramesHigh()) + stream.resize(setup_->numFramesHigh()); + // cycle event, remove gaps + stream.erase(remove(stream.begin(), stream.end(), nullptr), stream.end()); // store number of states which got taken into account - numAcceptedStates += numTruncatedStates; + numAcceptedStates += (int)stream.size(); // store number of states which got not taken into account due to truncation - numLostStates += numUntruncatedStates - numTruncatedStates; + numLostStates += nStates - (int)stream.size(); + // apply final cuts + vector finals; + finals.reserve(stream.size()); + finalize(stream, finals); + // best track per candidate selection + 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 + vector& tracks = tracksOut[channel]; + vector>& stubs = stubsOut[channel]; + conv(best, tracks, stubs); + } + } + + // create Proto States + void KalmanFilter::createProtoStates(const std::vector>& tracksIn, + const std::vector>& stubsIn, + int channel, + deque& stream) { + static const int numLayers = setup_->numLayers(); + const int offsetL = channel * numLayers; + const vector& tracksChannel = tracksIn[channel]; + int trackId(0); + for (int frame = 0; frame < (int)tracksChannel.size();) { + TrackCTB* track = tracksChannel[frame]; + if (!track) { + frame++; + continue; + } + const auto begin = next(tracksChannel.begin(), frame); + const auto end = find_if(begin + 1, tracksChannel.end(), [](TrackCTB* track) { return track; }); + const int size = distance(begin, end); + vector> stubs(numLayers); + for (vector& layer : stubs) + layer.reserve(size); + for (int layer = 0; layer < numLayers; layer++) { + const vector& layerAll = stubsIn[layer + offsetL]; + 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(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); + // cut on eta sector boundaries + /*const bool invalidX3 = abs(x3) > zT.base() / 2.; + // cut on triple found inv2R window + const bool invalidX0 = abs(x0) > 1.5 * inv2R.base(); + // cut on triple found phiT window + const bool invalidX1 = abs(x1) > 1.5 * phiT.base(); + // cot cut + const bool invalidX2 = abs(x2) > maxCot; + if (invalidX3 || invalidX0 || invalidX1 || invalidX2) { + state = nullptr; + continue; + }*/ + // create updated state + static const double chi20 = digi(VariableKF::chi20, 0.); + static 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 deque& stream, vector& finals) { + for (State* state : stream) { + TrackCTB* track = state->track(); + int numConsistent(0); + int numConsistentPS(0); + TTBV hitPattern = state->hitPattern(); + vector stubs; + vector phis; + 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 (abs(phi) <= s->dPhi() && 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 vector& best, vector& tracks, vector>& stubs) { + static const DataFormat& dfInv2R = dataFormats_->format(Variable::inv2R, Process::ht); + static const DataFormat& dfPhiT = dataFormats_->format(Variable::phiT, Process::ht); + tracks.reserve(best.size()); + for (vector& layer : stubs) + layer.reserve(best.size()); + for (Track* track : best) { + const 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()); } } @@ -216,7 +306,7 @@ namespace trackerTFP { // Memory stack used to handle combinatorics deque stack; // static delay container - vector delay(latency, nullptr); + 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() || @@ -228,8 +318,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,195 +327,233 @@ 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(deque& stream) { + // Latency of KF Associator block firmware + static constexpr int latency = 5; + // dynamic state container for clock accurate emulation + deque streamOutput; + // Memory stack used to handle combinatorics + deque stack; + // static delay container + 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; })) { + 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(vector& finals, vector& best) { + // create container of pointer to make sorts less CPU intense + //for (Track& track : finals) + //best.push_back(&track); + transform(finals.begin(), finals.end(), back_inserter(best), [](Track& track) { return &track; }); + // prepare arrival order + vector trackIds; + trackIds.reserve(best.size()); + for (Track* track : best) { + const int trackId = track->trackId_; + if (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_; }; + 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_; }; + 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_; }; + 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 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(); }); + 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(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 = max(0, (int)ceil(log2(R00 / base(VariableKF::R00)))); + const int msb1 = max(0, (int)ceil(log2(R11 / base(VariableKF::R11)))); + const int shift0 = width(VariableKF::R00) - msb0; + const int shift1 = width(VariableKF::R11) - msb1; + const double R00Shifted = R00 * pow(2., shift0); + const double R11Shifted = R11 * 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 * pow(2., shift0), base(VariableKF::S00Shifted)); + const double S01Shifted = digiShifted(S01 * pow(2., shift0), base(VariableKF::S01Shifted)); + const double S12Shifted = digiShifted(S12 * pow(2., shift1), base(VariableKF::S12Shifted)); + const double S13Shifted = digiShifted(S13 * 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 * pow(2., shift0), base(VariableKF::r0Shifted)); + const double r1Shifted = digiShifted(r1 * 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 @@ -440,15 +567,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..ee765f153c8d2 100644 --- a/L1Trigger/TrackerTFP/src/KalmanFilterFormats.cc +++ b/L1Trigger/TrackerTFP/src/KalmanFilterFormats.cc @@ -16,36 +16,33 @@ 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"}; + "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() { const int wName = strlen(*max_element(variableKFstrs_.begin(), variableKFstrs_.end(), [](const auto& a, const auto& b) { return strlen(a) < 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())); + cout << setw(wName) << *next(variableKFstrs_.begin(), +v) << ": "; + cout << setw(3) << (delta == -2147483648 ? "-" : to_string(delta)) << endl; } } - KalmanFilterFormats::KalmanFilterFormats() : iConfig_(), dataFormats_(nullptr), setup_(nullptr) { + KalmanFilterFormats::KalmanFilterFormats(const ParameterSet& iConfig) : iConfig_(iConfig) { 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) { + dataFormats_ = dataFormats; fillFormats(); } @@ -56,13 +53,16 @@ namespace trackerTFP { fillFormats<++it>(); } - DataFormatKF::DataFormatKF(const VariableKF& v, bool twos) + DataFormatKF::DataFormatKF(const VariableKF& v, bool twos, const ParameterSet& iConfig) : v_(v), twos_(twos), + enableIntegerEmulation_(iConfig.getParameter("EnableIntegerEmulation")), width_(0), base_(1.), range_(0.), - rangeActual_(numeric_limits::max(), numeric_limits::lowest()) {} + min_(numeric_limits::max()), + abs_(numeric_limits::max()), + max_(numeric_limits::lowest()) {} // returns false if data format would oferflow for this double value bool DataFormatKF::inRange(double d) const { @@ -72,22 +72,25 @@ namespace trackerTFP { } void DataFormatKF::updateRangeActual(double d) { - rangeActual_ = make_pair(min(rangeActual_.first, d), max(rangeActual_.second, d)); - if (!inRange(d)) { + min_ = std::min(min_, d); + abs_ = std::min(abs_, std::abs(d)); + max_ = std::max(max_, d); + if (enableIntegerEmulation_ && !inRange(d)) { string v = *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; 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(VariableKF::x0, true, iConfig) { const DataFormat& input = dataFormats->format(Variable::inv2R, Process::kf); const int baseShift = iConfig.getParameter("BaseShiftx0"); base_ = pow(2, baseShift) * input.base(); @@ -97,7 +100,7 @@ namespace trackerTFP { template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::x1, true) { + : DataFormatKF(VariableKF::x1, true, iConfig) { const DataFormat& input = dataFormats->format(Variable::phiT, Process::kf); const int baseShift = iConfig.getParameter("BaseShiftx1"); base_ = pow(2, baseShift) * input.base(); @@ -107,7 +110,7 @@ namespace trackerTFP { template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::x2, true) { + : DataFormatKF(VariableKF::x2, true, iConfig) { const DataFormat& input = dataFormats->format(Variable::cot, Process::kf); const int baseShift = iConfig.getParameter("BaseShiftx2"); base_ = pow(2, baseShift) * input.base(); @@ -117,7 +120,7 @@ namespace trackerTFP { template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::x3, true) { + : DataFormatKF(VariableKF::x3, true, iConfig) { const DataFormat& input = dataFormats->format(Variable::zT, Process::kf); const int baseShift = iConfig.getParameter("BaseShiftx3"); base_ = pow(2, baseShift) * input.base(); @@ -127,64 +130,65 @@ namespace trackerTFP { 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(VariableKF::H00, true, iConfig) { + const DataFormat& ctb = dataFormats->format(Variable::r, Process::ctb); + base_ = ctb.base(); + width_ = ctb.width(); + calcRange(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::H12, true) { + : DataFormatKF(VariableKF::H12, true, iConfig) { 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())); + const DataFormat& ctb = dataFormats->format(Variable::r, Process::ctb); + base_ = ctb.base(); + range_ = 2. * setup->maxRz(); width_ = ceil(log2(range_ / base_)); + calcRange(); } 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(VariableKF::m0, true, iConfig) { + const DataFormat& ctb = dataFormats->format(Variable::phi, Process::ctb); + base_ = ctb.base(); + width_ = ctb.width(); + calcRange(); } 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(VariableKF::m1, true, iConfig) { + const DataFormat& ctb = dataFormats->format(Variable::z, Process::ctb); + base_ = ctb.base(); + width_ = ctb.width(); + calcRange(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::v0, false) { - 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(); + : DataFormatKF(VariableKF::v0, false, iConfig) { + const DataFormat& dPhi = dataFormats->format(Variable::dPhi, Process::ctb); + const FormatKF S01(dataFormats, iConfig); + range_ = dPhi.range() * dPhi.range() * 4.; + base_ = S01.base(); + calcWidth(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::v1, true) { - 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(); + : DataFormatKF(VariableKF::v1, false, iConfig) { + const DataFormat& dZ = dataFormats->format(Variable::dZ, Process::ctb); + const FormatKF S13(dataFormats, iConfig); + range_ = dZ.range() * dZ.range() * 4.; + base_ = S13.base(); + calcWidth(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::r0, true) { + : DataFormatKF(VariableKF::r0, true, iConfig) { const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); const int baseShift = iConfig.getParameter("BaseShiftr0"); base_ = pow(2., baseShift) * x1.base(); @@ -194,7 +198,7 @@ namespace trackerTFP { template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::r1, true) { + : DataFormatKF(VariableKF::r1, true, iConfig) { const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); const int baseShift = iConfig.getParameter("BaseShiftr1"); base_ = pow(2., baseShift) * x3.base(); @@ -204,129 +208,171 @@ namespace trackerTFP { template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::S00, true) { + : DataFormatKF(VariableKF::S00, true, 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(); + width_ = dataFormats->setup()->widthDSPab(); calcRange(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::S01, true) { + : DataFormatKF(VariableKF::S01, true, 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(); + width_ = dataFormats->setup()->widthDSPab(); calcRange(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::S12, true) { + : DataFormatKF(VariableKF::S12, true, 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(); + width_ = dataFormats->setup()->widthDSPab(); calcRange(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::S13, true) { + : DataFormatKF(VariableKF::S13, true, 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(); + width_ = dataFormats->setup()->widthDSPab(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) + : DataFormatKF(VariableKF::S00Shifted, true, iConfig) { + const DataFormat& x0 = dataFormats->format(Variable::inv2R, Process::kf); + const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.getParameter("BaseShiftS00Shifted"); + base_ = pow(2., baseShift) * x0.base() * x1.base(); + width_ = dataFormats->setup()->widthDSPab(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) + : DataFormatKF(VariableKF::S01Shifted, true, iConfig) { + const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.getParameter("BaseShiftS01Shifted"); + base_ = pow(2., baseShift) * x1.base() * x1.base(); + width_ = dataFormats->setup()->widthDSPab(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) + : DataFormatKF(VariableKF::S12Shifted, true, iConfig) { + const DataFormat& x2 = dataFormats->format(Variable::cot, Process::kf); + const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.getParameter("BaseShiftS12Shifted"); + base_ = pow(2., baseShift) * x2.base() * x3.base(); + width_ = dataFormats->setup()->widthDSPab(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) + : DataFormatKF(VariableKF::S13Shifted, true, iConfig) { + const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.getParameter("BaseShiftS13Shifted"); + base_ = pow(2., baseShift) * x3.base() * x3.base(); + width_ = dataFormats->setup()->widthDSPab(); calcRange(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::K00, true) { + : DataFormatKF(VariableKF::K00, true, 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(); + width_ = dataFormats->setup()->widthDSPbb(); calcRange(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::K10, true) { + : DataFormatKF(VariableKF::K10, true, iConfig) { const int baseShift = iConfig.getParameter("BaseShiftK10"); base_ = pow(2., baseShift); - width_ = dataFormats->setup()->widthDSPab(); + width_ = dataFormats->setup()->widthDSPbb(); calcRange(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::K21, true) { + : DataFormatKF(VariableKF::K21, true, 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(); + width_ = dataFormats->setup()->widthDSPbb(); calcRange(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::K31, true) { + : DataFormatKF(VariableKF::K31, true, iConfig) { const int baseShift = iConfig.getParameter("BaseShiftK31"); base_ = pow(2., baseShift); - width_ = dataFormats->setup()->widthDSPab(); + width_ = dataFormats->setup()->widthDSPbb(); calcRange(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::R00, false) { + : DataFormatKF(VariableKF::R00, false, iConfig) { const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); const int baseShift = iConfig.getParameter("BaseShiftR00"); + width_ = iConfig.getParameter("WidthR00"); base_ = pow(2., baseShift) * x1.base() * x1.base(); - width_ = dataFormats->setup()->widthDSPbu(); calcRange(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::R11, false) { + : DataFormatKF(VariableKF::R11, false, iConfig) { const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); const int baseShift = iConfig.getParameter("BaseShiftR11"); + width_ = iConfig.getParameter("WidthR11"); base_ = pow(2., baseShift) * x3.base() * x3.base(); - width_ = dataFormats->setup()->widthDSPbu(); calcRange(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::R00Rough, false) { + : DataFormatKF(VariableKF::R00Rough, false, iConfig) { const FormatKF R00(dataFormats, iConfig); width_ = dataFormats->setup()->widthAddrBRAM18(); range_ = R00.range(); - const int baseShift = R00.width() - width_; + const int baseShift = R00.width() - width_ - 1; base_ = pow(2., baseShift) * R00.base(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::R11Rough, false) { + : DataFormatKF(VariableKF::R11Rough, false, iConfig) { const FormatKF R11(dataFormats, iConfig); width_ = dataFormats->setup()->widthAddrBRAM18(); range_ = R11.range(); - const int baseShift = R11.width() - width_; + const int baseShift = R11.width() - width_ - 1; base_ = pow(2., baseShift) * R11.base(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::invR00Approx, false) { + : DataFormatKF(VariableKF::invR00Approx, false, iConfig) { const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); const int baseShift = iConfig.getParameter("BaseShiftInvR00Approx"); base_ = pow(2., baseShift) / x1.base() / x1.base(); @@ -336,7 +382,7 @@ namespace trackerTFP { template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::invR11Approx, false) { + : DataFormatKF(VariableKF::invR11Approx, false, iConfig) { const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); const int baseShift = iConfig.getParameter("BaseShiftInvR11Approx"); base_ = pow(2., baseShift) / x3.base() / x3.base(); @@ -346,102 +392,256 @@ namespace trackerTFP { template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::invR00Cor, false) { + : DataFormatKF(VariableKF::invR00Cor, false, iConfig) { const int baseShift = iConfig.getParameter("BaseShiftInvR00Cor"); base_ = pow(2., baseShift); - width_ = dataFormats->setup()->widthDSPbu(); + width_ = dataFormats->setup()->widthDSPau(); calcRange(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::invR11Cor, false) { + : DataFormatKF(VariableKF::invR11Cor, false, iConfig) { const int baseShift = iConfig.getParameter("BaseShiftInvR11Cor"); base_ = pow(2., baseShift); - width_ = dataFormats->setup()->widthDSPbu(); + width_ = dataFormats->setup()->widthDSPau(); calcRange(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::invR00, false) { + : DataFormatKF(VariableKF::invR00, false, 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(); + width_ = dataFormats->setup()->widthDSPbu(); calcRange(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::invR11, false) { + : DataFormatKF(VariableKF::invR11, false, 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(); + width_ = dataFormats->setup()->widthDSPbu(); calcRange(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::C00, false) { + : DataFormatKF(VariableKF::C00, false, iConfig) { const DataFormat& x0 = dataFormats->format(Variable::inv2R, Process::kf); const int baseShift = iConfig.getParameter("BaseShiftC00"); + width_ = iConfig.getParameter("WidthC00"); base_ = pow(2., baseShift) * x0.base() * x0.base(); - width_ = dataFormats->setup()->widthDSPbu(); calcRange(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::C01, true) { + : DataFormatKF(VariableKF::C01, true, 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"); + width_ = iConfig.getParameter("WidthC01"); base_ = pow(2., baseShift) * x0.base() * x1.base(); - width_ = dataFormats->setup()->widthDSPbb(); calcRange(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::C11, false) { + : DataFormatKF(VariableKF::C11, false, iConfig) { const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); const int baseShift = iConfig.getParameter("BaseShiftC11"); + width_ = iConfig.getParameter("WidthC11"); base_ = pow(2., baseShift) * x1.base() * x1.base(); - width_ = dataFormats->setup()->widthDSPbu(); calcRange(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::C22, false) { + : DataFormatKF(VariableKF::C22, false, iConfig) { const DataFormat& x2 = dataFormats->format(Variable::cot, Process::kf); const int baseShift = iConfig.getParameter("BaseShiftC22"); + width_ = iConfig.getParameter("WidthC22"); base_ = pow(2., baseShift) * x2.base() * x2.base(); - width_ = dataFormats->setup()->widthDSPbu(); calcRange(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::C23, true) { + : DataFormatKF(VariableKF::C23, true, 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"); + width_ = iConfig.getParameter("WidthC23"); base_ = pow(2., baseShift) * x2.base() * x3.base(); - width_ = dataFormats->setup()->widthDSPbb(); calcRange(); } template <> FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) - : DataFormatKF(VariableKF::C33, false) { + : DataFormatKF(VariableKF::C33, false, iConfig) { const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); const int baseShift = iConfig.getParameter("BaseShiftC33"); + width_ = iConfig.getParameter("WidthC33"); + base_ = pow(2., baseShift) * x3.base() * x3.base(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) + : DataFormatKF(VariableKF::r0Shifted, true, iConfig) { + const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.getParameter("BaseShiftr0Shifted"); + base_ = pow(2., baseShift) * x1.base(); + width_ = dataFormats->setup()->widthDSPbb(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) + : DataFormatKF(VariableKF::r1Shifted, true, iConfig) { + const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.getParameter("BaseShiftr1Shifted"); + base_ = pow(2., baseShift) * x3.base(); + width_ = dataFormats->setup()->widthDSPbb(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) + : DataFormatKF(VariableKF::r02, false, iConfig) { + const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf); + const int baseShift = iConfig.getParameter("BaseShiftr02"); + base_ = pow(2., baseShift) * x1.base() * x1.base(); + width_ = dataFormats->setup()->widthDSPbu(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) + : DataFormatKF(VariableKF::r12, false, iConfig) { + const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf); + const int baseShift = iConfig.getParameter("BaseShiftr12"); base_ = pow(2., baseShift) * x3.base() * x3.base(); width_ = dataFormats->setup()->widthDSPbu(); calcRange(); } + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) + : DataFormatKF(VariableKF::chi20, false, iConfig) { + const int baseShift = iConfig.getParameter("BaseShiftchi20"); + base_ = pow(2., baseShift); + width_ = dataFormats->setup()->widthDSPbu(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) + : DataFormatKF(VariableKF::chi21, false, iConfig) { + const int baseShift = iConfig.getParameter("BaseShiftchi21"); + base_ = pow(2., baseShift); + width_ = dataFormats->setup()->widthDSPbu(); + calcRange(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::end, false, iConfig) { + const Setup* setup = dataFormats->setup(); + const DataFormat& ctb = dataFormats->format(Variable::r, Process::ctb); + width_ = setup->widthAddrBRAM18(); + range_ = setup->outerRadius() - setup->innerRadius(); + base_ = ctb.base() * pow(2, ceil(log2(range_ / ctb.base())) - width_); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::end, false, iConfig) { + const FormatKF H00(dataFormats, iConfig); + const Setup* setup = dataFormats->setup(); + width_ = setup->widthDSPbu(); + range_ = 1. / setup->kfMinSeedDeltaR(); + const int baseShift = ceil(log2(range_ * pow(2., -width_) * H00.base())); + base_ = pow(2., baseShift) / H00.base(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::end, false, iConfig) { + const FormatKF H00(dataFormats, iConfig); + const Setup* setup = dataFormats->setup(); + width_ = setup->widthDSPbu(); + range_ = 1. / pow(setup->kfMinSeedDeltaR(), 2); + const double baseH2 = H00.base() * H00.base(); + const int baseShift = ceil(log2(range_ * pow(2., -width_) * baseH2)); + base_ = pow(2., baseShift) / baseH2; + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::end, false, iConfig) { + const FormatKF H00(dataFormats, iConfig); + base_ = H00.base() * H00.base(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::end, true, iConfig) { + const FormatKF H00(dataFormats, iConfig); + const FormatKF m0(dataFormats, iConfig); + base_ = H00.base() * m0.base(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::end, true, iConfig) { + const FormatKF H12(dataFormats, iConfig); + const FormatKF m1(dataFormats, iConfig); + base_ = H12.base() * m1.base(); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::end, false, iConfig) { + const Setup* setup = dataFormats->setup(); + const FormatKF H00(dataFormats, iConfig); + const FormatKF v0(dataFormats, iConfig); + width_ = setup->widthDSPab(); + base_ = H00.base() * v0.base() * pow(2, H00.width() + v0.width() - width_); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::end, false, iConfig) { + const FormatKF H12(dataFormats, iConfig); + const Setup* setup = dataFormats->setup(); + const FormatKF v1(dataFormats, iConfig); + width_ = setup->widthDSPab(); + base_ = H12.base() * v1.base() * pow(2, H12.width() + v1.width() - width_); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::end, false, iConfig) { + const Setup* setup = dataFormats->setup(); + const FormatKF H00(dataFormats, iConfig); + const FormatKF v0(dataFormats, iConfig); + width_ = setup->widthDSPau(); + base_ = H00.base() * H00.base() * v0.base() * pow(2, 2 * H00.width() + v0.width() - width_); + } + + template <> + FormatKF::FormatKF(const DataFormats* dataFormats, const ParameterSet& iConfig) + : DataFormatKF(VariableKF::end, false, iConfig) { + const Setup* setup = dataFormats->setup(); + const FormatKF H12(dataFormats, iConfig); + const FormatKF v1(dataFormats, iConfig); + width_ = setup->widthDSPau(); + base_ = H12.base() * H12.base() * v1.base() * pow(2, 2 * H12.width() + v1.width() - width_); + } + } // 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..9fb9da96bb725 100644 --- a/L1Trigger/TrackerTFP/src/LayerEncoding.cc +++ b/L1Trigger/TrackerTFP/src/LayerEncoding.cc @@ -15,17 +15,15 @@ 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_(vector>(pow(2, zT_->width()))), + maybePattern_(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 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; @@ -38,136 +36,85 @@ namespace trackerTFP { auto equalRZ = [](const SensorModule* lhs, const SensorModule* rhs) { return abs(lhs->r() - rhs->r()) < delta && abs(lhs->z() - rhs->z()) < delta; }; + stable_sort(sensorModules.begin(), sensorModules.end(), smallerZ); stable_sort(sensorModules.begin(), sensorModules.end(), smallerR); + sensorModules.erase(unique(sensorModules.begin(), sensorModules.end(), equalRZ), sensorModules.end()); stable_sort(sensorModules.begin(), sensorModules.end(), smallerZ); sensorModules.erase(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 < 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 vector zTs = {zT - zT_->base() / 2., zT + zT_->base() / 2.}; + 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 + vector> layers(boundaries); + // 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 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 (abs(d) < sm->numColumns() * sm->pitchCol() / 2.) + layers[i].insert(sm->layerId()); } } + // mayber layers are given by layer ids crossed by only one boundary + 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 boundary + set layerEncoding; + set_union(layers[0].begin(), + layers[0].end(), + layers[1].begin(), + layers[1].end(), + inserter(layerEncoding, layerEncoding.end())); + // fill layerEncoding_ + vector& le = layerEncoding_[binZT]; + le = vector(layerEncoding.begin(), layerEncoding.end()); + le.resize(setup_->numLayers(), -1); + // fill maybePattern_ + TTBV& mp = maybePattern_[binZT]; + for (int m : maybeLayer) + mp.set(min((int)distance(le.begin(), 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 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 vector& LayerEncoding::layerEncoding(double zT) const { + const int binZT = zT_->integer(zT); + return layerEncoding(binZT); + } + + // 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 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 zT in cm + const TTBV& LayerEncoding::maybePattern(double zT) const { + const int binZT = zT_->integer(zT); + return maybePattern(binZT); } } // namespace trackerTFP 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..11ff8b0bef933 100644 --- a/L1Trigger/TrackerTFP/src/State.cc +++ b/L1Trigger/TrackerTFP/src/State.cc @@ -5,121 +5,183 @@ 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 FrameStub& frame) : stubCTB_(frame, formats->dataFormats()) { + const Setup* setup = formats->setup(); + H12_ = formats->format(VariableKF::H12).digi(stubCTB_.r() + setup->chosenRofPhi() - setup->chosenRofZ()); + v0_ = formats->format(VariableKF::v0).digi(pow(2. * stubCTB_.dPhi(), 2)); + v1_ = formats->format(VariableKF::v1).digi(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 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 vector& stubs : stubs_) { + if (!stubs.empty()) + trackPattern_.set(layer_); + layer_++; + } + layer_ = trackPattern_.plEncode(); + stub_ = stubs_[layer_].front(); + hitPattern_.set(layer_); } // updated state constructor - State::State(State* state, const std::vector& doubles) : State(state) { + State::State(State* state, const vector& doubles) : State(state) { parent_ = state; // updated track parameter and uncertainties x0_ = doubles[0]; 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_); + } + + // 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(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(deque& states, int layer) { + // handle trivial state + if (!hitPattern_.test(layer) || hitPattern_.count() > setup_->kfNumSeedStubs()) + return nullptr; + // pick next stub on layer + const vector& stubs = stubs_[layer]; + const int pos = distance(stubs.begin(), find(stubs.begin(), stubs.end(), stub_)) + 1; + if (pos < (int)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; } - // 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(); + // + State* State::comb(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 vector& stubs = stubs_[layer]; + const int pos = distance(stubs.begin(), find(stubs.begin(), stubs.end(), stub_)) + 1; + if (pos < (int)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..4e99ea42035e5 --- /dev/null +++ b/L1Trigger/TrackerTFP/src/TrackFindingProcessor.cc @@ -0,0 +1,278 @@ +#include "L1Trigger/TrackerTFP/interface/TrackFindingProcessor.h" +#include "L1Trigger/TrackTrigger/interface/StubPtConsistency.h" + +#include +#include +#include +#include +#include + +using namespace std; +using namespace edm; +using namespace tt; + +namespace trackerTFP { + + TrackFindingProcessor::TrackFindingProcessor(const ParameterSet& iConfig, + const Setup* setup, + const DataFormats* dataFormats, + const TrackQuality* trackQuality) + : enableTruncation_(iConfig.getParameter("EnableTruncation")), + setup_(setup), + dataFormats_(dataFormats), + trackQuality_(trackQuality) {} + + // + TrackFindingProcessor::Track::Track(const FrameTrack& frameTrack, + const Frame& frameTQ, + const vector& ttStubRefs, + const TrackQuality* tq) + : ttTrackRef_(frameTrack.first), ttStubRefs_(ttStubRefs), valid_(true) { + partials_.reserve(partial_in); + // convert bits into nice formats + const DataFormats* df = tq->dataFormats(); + const Setup* setup = df->setup(); + const TrackDR trackDR(frameTrack, df); + inv2R_ = trackDR.inv2R(); + phiT_ = trackDR.phiT(); + cot_ = trackDR.cot(); + zT_ = trackDR.zT(); + const double d0 = max(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; + static const double rangeInvR = -2. * TTTrack_TrackWord::minRinv; + static const double rangePhi0 = -2. * TTTrack_TrackWord::minPhi0; + static const double rangeCot = -2. * TTTrack_TrackWord::minTanl; + static const double rangeZ0 = -2. * TTTrack_TrackWord::minZ0; + static const double rangeD0 = -2. * TTTrack_TrackWord::minD0; + if (abs(invR) > rangeInvR / 2.) + valid_ = false; + if (abs(phi0) > rangePhi0 / 2.) + valid_ = false; + if (abs(cot_) > rangeCot / 2.) + valid_ = false; + if (abs(z0) > rangeZ0 / 2.) + valid_ = false; + if (abs(d0) > rangeD0 / 2.) + valid_ = false; + if (!valid_) + return; + static const double baseInvR = rangeInvR / pow(2., TTTrack_TrackWord::TrackBitWidths::kRinvSize); + static const double basePhi0 = rangePhi0 / pow(2., TTTrack_TrackWord::TrackBitWidths::kPhiSize); + static const double baseCot = rangeCot / pow(2., TTTrack_TrackWord::TrackBitWidths::kTanlSize); + static const double baseZ0 = rangeZ0 / pow(2., TTTrack_TrackWord::TrackBitWidths::kZ0Size); + static const double baseD0 = rangeD0 / pow(2., TTTrack_TrackWord::TrackBitWidths::kD0Size); + static constexpr int nLayers = TTTrack_TrackWord::TrackBitWidths::kHitPatternSize; + static const TTBV Other_MVAs(0, 2 * TTTrack_TrackWord::TrackBitWidths::kMVAQualitySize); + const TTBV MVA_quality(mva_, TTTrack_TrackWord::TrackBitWidths::kMVAQualitySize); + const TTBV hit_pattern(hitPattern_.resize(nLayers).val(), nLayers); + static const TTBV chi2bend(0, TTTrack_TrackWord::TrackBitWidths::kBendChi2Size); + static 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); + static const TTBV valid(1, TTTrack_TrackWord::TrackBitWidths::kValidSize); + 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 StreamsTrack& inputs, + const StreamsStub& stubs, + TTTracks& ttTracks, + StreamsTrack& outputs) { + // organize input tracks + 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 StreamsTrack& inputs, + const StreamsStub& stubs, + vector>& outputs) { + // count input objects + int nTracks(0); + auto valid = [](int sum, const FrameTrack& frame) { return sum += (frame.first.isNonnull() ? 1 : 0); }; + for (const StreamTrack& tracks : inputs) + nTracks += 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 StreamTrack& streamDR = inputs[offsetTQ]; + const StreamTrack& streamTQ = inputs[offsetTQ + 1]; + for (int channel = 0; channel < setup_->tfpNumChannel(); channel++) + outputs[offsetTFP + channel] = deque(streamDR.size(), nullptr); + for (int frame = 0; frame < (int)streamDR.size(); frame++) { + const FrameTrack& frameTrack = streamDR[frame]; + const Frame& frameTQ = streamTQ[frame].second; + if (frameTrack.first.isNull()) + continue; + 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++) { + 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(vector>& inputs, StreamsTrack& outputs) const { + for (int channel = 0; channel < (int)inputs.size(); channel++) { + deque& input = inputs[channel]; + deque stack; + 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(FrameTrack()); + 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 (enableTruncation_ && (int)output.size() > setup_->numFramesIOHigh()) + output.resize(setup_->numFramesIOHigh()); + outputs[channel] = StreamTrack(output.begin(), output.end()); + } + } + + // produce TTTracks + void TrackFindingProcessor::produce(const StreamsTrack& inputs, TTTracks& outputs) const { + // collect input TTTrackRefs + vector ttTrackRefs; + ttTrackRefs.reserve(tracks_.size()); + const TTTrack* last = nullptr; + for (const StreamTrack& stream : inputs) { + for (const 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 + static 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 = find_if(tracks_.begin(), tracks_.end(), match); + // TTTrack conversion + const int region = ttTrackRef->phiSector(); + const double aRinv = -2. * it->inv2R_; + const double aphi = 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(); + static const double Bfield = setup_->bField(); + 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 vector& inputs, StreamsTrack& outputs) const { + int iTrk(-1); + const TTTrack* last = nullptr; + for (StreamTrack& stream : outputs) { + for (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(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..2b85ed39bd90c --- /dev/null +++ b/L1Trigger/TrackerTFP/src/TrackQuality.cc @@ -0,0 +1,283 @@ +/* +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" + +using namespace std; +using namespace edm; +using namespace tt; + +namespace trackerTFP { + + TrackQuality::TrackQuality(const ParameterSet& iConfig, const DataFormats* dataFormats) + : dataFormats_(dataFormats), + model_(iConfig.getParameter("Model")), + featureNames_(iConfig.getParameter>("FeatureNames")), + baseShiftCot_(iConfig.getParameter("BaseShiftCot")), + baseShiftZ0_(iConfig.getParameter("BaseShiftZ0")), + baseShiftAPfixed_(iConfig.getParameter("BaseShiftAPfixed")), + chi2rphiConv_(iConfig.getParameter("Chi2rphiConv")), + chi2rzConv_(iConfig.getParameter("Chi2rzConv")), + weightBinFraction_(iConfig.getParameter("WeightBinFraction")), + dzTruncation_(iConfig.getParameter("DzTruncation")), + dphiTruncation_(iConfig.getParameter("DphiTruncation")) { + dataFormatsTQ_.reserve(+VariableTQ::end); + fillDataFormats(iConfig); + } + + // constructs TQ data formats + template + void TrackQuality::fillDataFormats(const ParameterSet& iConfig) { + dataFormatsTQ_.emplace_back(FormatTQ(dataFormats_, iConfig)); + if constexpr (++v != VariableTQ::end) + fillDataFormats<++v>(iConfig); + } + + // TQ MVA bin conversion LUT + constexpr array TrackQuality::mvaPreSigBins() const { + 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 < (int)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 array bins = mvaPreSigBins(); + return toBin(bins, mva); + } + + // Helper function to convert chi2B to bin + int TrackQuality::toBinChi2B(double chi2B) const { + static const array bins = TTTrack_TrackWord::bendChi2Bins; + return toBin(bins, chi2B); + } + + // Helper function to convert chi2rphi to bin + int TrackQuality::toBinchi2rphi(double chi2rphi) const { + static const 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 array bins = TTTrack_TrackWord::chi2RZBins; + double chi2 = chi2rz * chi2rzConv_; + return toBin(bins, chi2); + } + + TrackQuality::Track::Track(const FrameTrack& frameTrack, const StreamStub& streamStub, const TrackQuality* tq) + : frameTrack_(frameTrack), streamStub_(streamStub) { + static const DataFormats* df = tq->dataFormats(); + static const Setup* setup = df->setup(); + const TrackDR track(frameTrack, df); + double trackchi2rphi(0.); + double trackchi2rz(0.); + TTBV hitPattern(0, streamStub.size()); + vector ttStubRefs; + ttStubRefs.reserve(setup->numLayers()); + for (int layer = 0; layer < (int)streamStub.size(); layer++) { + const 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(pow(stub.phi(), 2)); + const double m21 = tq->format(VariableTQ::m21).digi(pow(stub.z(), 2)); + const double invV0 = tq->format(VariableTQ::invV0).digi(1. / pow(stub.dPhi(), 2)); + const double invV1 = tq->format(VariableTQ::invV1).digi(1. / 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 = 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 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 <> + FormatTQ::FormatTQ(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) + : DataFormat(false) { + const Format phi(dataFormats->setup()); + width_ = iConfig.getParameter("WidthM20"); + base_ = pow(phi.base(), 2) * pow(2., width_ - phi.width()); + calcRange(); + } + template <> + FormatTQ::FormatTQ(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) + : DataFormat(false) { + const Format z(dataFormats->setup()); + width_ = iConfig.getParameter("WidthM21"); + base_ = pow(z.base(), 2) * pow(2., width_ - z.width()); + calcRange(); + } + template <> + FormatTQ::FormatTQ(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) + : DataFormat(false) { + const Format dPhi(dataFormats->setup()); + width_ = iConfig.getParameter("WidthInvV0"); + range_ = 4.0 / pow(dPhi.base(), 2); + calcBase(); + } + template <> + FormatTQ::FormatTQ(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) + : DataFormat(false) { + const Format dZ(dataFormats->setup()); + width_ = iConfig.getParameter("WidthInvV1"); + range_ = 4.0 / pow(dZ.base(), 2); + calcBase(); + } + template <> + FormatTQ::FormatTQ(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) + : DataFormat(false) { + const FormatTQ m20(dataFormats, iConfig); + const FormatTQ invV0(dataFormats, iConfig); + const int shift = iConfig.getParameter("BaseShiftchi2rphi"); + width_ = iConfig.getParameter("Widthchi2rphi"); + base_ = pow(2., shift); + calcRange(); + } + template <> + FormatTQ::FormatTQ(const DataFormats* dataFormats, const edm::ParameterSet& iConfig) + : DataFormat(false) { + const FormatTQ m21(dataFormats, iConfig); + const FormatTQ invV1(dataFormats, iConfig); + const int shift = iConfig.getParameter("BaseShiftchi2rz"); + width_ = iConfig.getParameter("Widthchi2rz"); + base_ = pow(2., shift); + calcRange(); + } + + // Controls the conversion between TTTrack features and ML model training features + vector TrackQuality::featureTransform(TTTrack& aTrack, + 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 + vector transformedFeatures; + // Define feature map, filled as features are generated + 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 + 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 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 + vector inputs = featureTransform(aTrack, this->featureNames_); + 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/AnalyzerKFin.cc b/L1Trigger/TrackerTFP/test/AnalyzerCTB.cc similarity index 58% rename from L1Trigger/TrackerTFP/test/AnalyzerKFin.cc rename to L1Trigger/TrackerTFP/test/AnalyzerCTB.cc index 14a821ff226fc..374c5f7c5f92e 100644 --- a/L1Trigger/TrackerTFP/test/AnalyzerKFin.cc +++ b/L1Trigger/TrackerTFP/test/AnalyzerCTB.cc @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -28,19 +29,18 @@ 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 + /*! \class trackerTFP::AnalyzerCTB + * \brief Class to analyze hardware like structured TTStub Collection generated by Clean Track Builder * \author Thomas Schuh * \date 2020, April */ - class AnalyzerKFin : public one::EDAnalyzer { + class AnalyzerCTB : public one::EDAnalyzer { public: - AnalyzerKFin(const ParameterSet& iConfig); + AnalyzerCTB(const ParameterSet& iConfig); void beginJob() override {} void beginRun(const Run& iEvent, const EventSetup& iSetup) override; void analyze(const Event& iEvent, const EventSetup& iSetup) override; @@ -55,15 +55,10 @@ namespace trackerTFP { int channel) const; // void associate(const vector>& tracks, const StubAssociation* ass, set& tps, int& sum) const; - // ED input token of stubs - EDGetTokenT edGetTokenAcceptedStubs_; + 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_; + EDGetTokenT edGetTokenTracks_; // ED input token of TTStubRef to TPPtr association for tracking efficiency EDGetTokenT edGetTokenSelection_; // ED input token of TTStubRef to recontructable TPPtr association @@ -84,25 +79,34 @@ namespace trackerTFP { // Histograms TProfile* prof_; - TProfile* profChannel_; - TH1F* hisChannel_; + 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 stringstream log_; }; - AnalyzerKFin::AnalyzerKFin(const ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { + AnalyzerCTB::AnalyzerCTB(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)); + const string& label = iConfig.getParameter("OutputLabelCTB"); + const string& branchStubs = iConfig.getParameter("BranchStubs"); + const string& branchTracks = iConfig.getParameter("BranchTracks"); + edGetTokenStubs_ = consumes(InputTag(label, branchStubs)); + edGetTokenTracks_ = consumes(InputTag(label, branchTracks)); if (useMCTruth_) { const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); @@ -117,7 +121,7 @@ namespace trackerTFP { log_.precision(4); } - void AnalyzerKFin::beginRun(const Run& iEvent, const EventSetup& iSetup) { + void AnalyzerCTB::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 @@ -125,38 +129,62 @@ namespace trackerTFP { // book histograms Service fs; TFileDirectory dir; - dir = fs->mkdir("KFin"); + 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(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); + 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 AnalyzerKFin::analyze(const Event& iEvent, const EventSetup& iSetup) { + void AnalyzerCTB::analyze(const Event& iEvent, const 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 - 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; + Handle handleStubs; + iEvent.getByToken(edGetTokenStubs_, handleStubs); + const StreamsStub& acceptedStubs = *handleStubs; + Handle handleTracks; + iEvent.getByToken(edGetTokenTracks_, handleTracks); + const StreamsTrack& acceptedTracks = *handleTracks; // read in MCTruth const StubAssociation* selection = nullptr; const StubAssociation* reconstructable = nullptr; @@ -168,98 +196,101 @@ namespace trackerTFP { 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 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); + const int offsetTrack = region * dataFormats_->numChannel(Process::ctb); int nStubs(0); int nTracks(0); - int nLost(0); - for (int channel = 0; channel < dataFormats_->numChannel(Process::kf); channel++) { + 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 StreamStub& stream = acceptedStubs[offsetStub + layer]; + const int nStubs = accumulate(stream.begin(), stream.end(), 0, [](int sum, const FrameStub& frame) { + return sum += (frame.first.isNonnull() ? 1 : 0); + }); + hisStubs_->Fill(nStubs); + profStubs_->Fill(channel * setup_->numLayers() + layer, nStubs); + } vector> tracks; - formTracks(acceptedTracks, acceptedStubs, tracks, offset + channel); - vector> lost; - formTracks(lostTracks, lostStubs, lost, offset + channel); + formTracks(acceptedTracks, acceptedStubs, tracks, indexTrack); + hisTracks_->Fill(tracks.size()); + profTracks_->Fill(channel, tracks.size()); 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); + 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()); - prof_->Fill(8, tpPtrsLost.size()); nEvents_++; } - void AnalyzerKFin::endJob() { + void AnalyzerCTB::endJob() { if (nEvents_ == 0) return; - // printout SF summary + // 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 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 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_ << " KFin SUMMARY " << endl; + log_ << " CTB 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(); + LogPrint(moduleDescription().moduleName()) << log_.str(); } // - void AnalyzerKFin::formTracks(const StreamsTrack& streamsTrack, - const StreamsStub& streamsStubs, - vector>& tracks, - int channel) const { + void AnalyzerCTB::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) { @@ -284,22 +315,33 @@ namespace trackerTFP { } 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 FrameStub& stub = streamsStubs[offset + layer][f]; - if (stub.first.isNonnull()) + 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 AnalyzerKFin::associate(const vector>& tracks, - const StubAssociation* ass, - set& tps, - int& sum) const { + void AnalyzerCTB::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()) @@ -311,4 +353,4 @@ namespace trackerTFP { } // namespace trackerTFP -DEFINE_FWK_MODULE(trackerTFP::AnalyzerKFin); +DEFINE_FWK_MODULE(trackerTFP::AnalyzerCTB); diff --git a/L1Trigger/TrackFindingTracklet/test/AnalyzerKFin.cc b/L1Trigger/TrackerTFP/test/AnalyzerDR.cc similarity index 58% rename from L1Trigger/TrackFindingTracklet/test/AnalyzerKFin.cc rename to L1Trigger/TrackerTFP/test/AnalyzerDR.cc index bc9503631e16e..4ad0fdda6c133 100644 --- a/L1Trigger/TrackFindingTracklet/test/AnalyzerKFin.cc +++ b/L1Trigger/TrackerTFP/test/AnalyzerDR.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/TrackFindingTracklet/interface/ChannelAssignment.h" #include #include @@ -29,19 +28,18 @@ using namespace std; using namespace edm; -using namespace trackerTFP; using namespace tt; -namespace trklet { +namespace trackerTFP { - /*! \class trklet::AnalyzerKFin - * \brief Class to analyze hardware like structured TTStub Collection generated by Tracklet + /*! \class trackerTFP::AnalyzerDR + * \brief Class to analyze hardware like structured track Collection generated by Duplicate Removal * \author Thomas Schuh - * \date 2020, Nov + * \date 2023, Feb */ - class AnalyzerKFin : public one::EDAnalyzer { + class AnalyzerDR : public one::EDAnalyzer { public: - AnalyzerKFin(const ParameterSet& iConfig); + AnalyzerDR(const ParameterSet& iConfig); void beginJob() override {} void beginRun(const Run& iEvent, const EventSetup& iSetup) override; void analyze(const Event& iEvent, const EventSetup& iSetup) override; @@ -59,15 +57,11 @@ namespace trklet { const StubAssociation* ass, set& tps, int& sum, - bool perfect = false) const; + bool perfect = true) const; // ED input token of stubs - EDGetTokenT edGetTokenAcceptedStubs_; + 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_; + EDGetTokenT edGetTokenTracks_; // ED input token of TTStubRef to TPPtr association for tracking efficiency EDGetTokenT edGetTokenSelection_; // ED input token of TTStubRef to recontructable TPPtr association @@ -89,24 +83,22 @@ namespace trklet { TProfile* prof_; TProfile* profChannel_; + TProfile* profTracks_; TH1F* hisChannel_; + TH1F* hisTracks_; // printout stringstream log_; }; - AnalyzerKFin::AnalyzerKFin(const ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { + AnalyzerDR::AnalyzerDR(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)); + const string& label = iConfig.getParameter("OutputLabelDR"); + const string& branchStubs = iConfig.getParameter("BranchStubs"); + const string& branchTracks = iConfig.getParameter("BranchTracks"); + edGetTokenStubs_ = consumes(InputTag(label, branchStubs)); + edGetTokenTracks_ = consumes(InputTag(label, branchTracks)); if (useMCTruth_) { const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); @@ -121,7 +113,7 @@ namespace trklet { log_.precision(4); } - void AnalyzerKFin::beginRun(const Run& iEvent, const EventSetup& iSetup) { + void AnalyzerDR::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 @@ -129,39 +121,35 @@ namespace trklet { // book histograms Service fs; TFileDirectory dir; - dir = fs->mkdir("KFin"); - prof_ = dir.make("Counts", ";", 10, 0.5, 10.5); + 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(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"); + prof_->GetXaxis()->SetBinLabel(10, "states"); + prof_->GetXaxis()->SetBinLabel(12, "max tp"); // channel occupancy constexpr int maxOcc = 180; - const int numChannels = setup_->kfNumWorker(); + 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 AnalyzerKFin::analyze(const Event& iEvent, const EventSetup& iSetup) { + void AnalyzerDR::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; + Handle handleStubs; + iEvent.getByToken(edGetTokenStubs_, handleStubs); + const StreamsStub& acceptedStubs = *handleStubs; + Handle handleTracks; + iEvent.getByToken(edGetTokenTracks_, handleTracks); + const StreamsTrack& acceptedTracks = *handleTracks; // read in MCTruth const StubAssociation* selection = nullptr; const StubAssociation* reconstructable = nullptr; @@ -177,135 +165,111 @@ namespace trklet { // analyze ht products and associate found tracks with reconstrucable TrackingParticles set tpPtrs; set tpPtrsSelection; - set tpPtrsPerfect; - set tpPtrsLost; + set tpPtrsMax; int allMatched(0); int allTracks(0); for (int region = 0; region < setup_->numRegions(); region++) { - const int offset = region * setup_->kfNumWorker(); + const int offset = region * dataFormats_->numChannel(Process::dr); int nStubs(0); int nTracks(0); - int nLost(0); - for (int channel = 0; channel < setup_->kfNumWorker(); channel++) { + for (int channel = 0; channel < dataFormats_->numChannel(Process::dr); channel++) { vector> tracks; formTracks(acceptedTracks, acceptedStubs, tracks, offset + channel); - vector> lost; - formTracks(lostTracks, lostStubs, lost, offset + channel); + hisTracks_->Fill(tracks.size()); + profTracks_->Fill(channel, tracks.size()); nTracks += tracks.size(); nStubs += accumulate(tracks.begin(), tracks.end(), 0, [](int sum, const vector& track) { - return sum + (int)track.size(); + return sum += (int)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; + 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(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()); + prof_->Fill(12, tpPtrsMax.size()); nEvents_++; } - void AnalyzerKFin::endJob() { + void AnalyzerDR::endJob() { if (nEvents_ == 0) return; - // printout SF summary + // printout DR 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 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 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 double effMax = numTPsEffMax / totalTPs; + const double errEffMax = sqrt(effMax * (1. - effMax) / 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_ << " KFin SUMMARY " << endl; + 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_ << " tracking efficiency = " << setw(wNums) << eff << " +- " << setw(wErrs) << errEff << endl; + log_ << " max tracking efficiency = " << setw(wNums) << effMax << " +- " << setw(wErrs) << errEffMax << endl; log_ << " fake rate = " << setw(wNums) << fracFake << endl; log_ << " duplicate rate = " << setw(wNums) << fracDup << endl; log_ << "============================================================="; - LogPrint("L1Trigger/TrackerTFP") << log_.str(); + LogPrint(moduleDescription().moduleName()) << log_.str(); } // - void AnalyzerKFin::formTracks(const StreamsTrack& streamsTrack, - const StreamsStub& streamsStubs, - vector>& tracks, - int channel) const { + void AnalyzerDR::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); + 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()); + deque stubs; for (int layer = 0; layer < setup_->numLayers(); layer++) { const FrameStub& stub = streamsStubs[offset + layer][frame]; if (stub.first.isNonnull()) - ttStubRefs.push_back(stub.first); + stubs.push_back(stub.first); } - tracks.push_back(ttStubRefs); + tracks.emplace_back(stubs.begin(), stubs.end()); } } // - void AnalyzerKFin::associate(const vector>& tracks, - const StubAssociation* ass, - set& tps, - int& sum, - bool perfect) const { + void AnalyzerDR::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()) @@ -315,6 +279,6 @@ namespace trklet { } } -} // namespace trklet +} // namespace trackerTFP -DEFINE_FWK_MODULE(trklet::AnalyzerKFin); +DEFINE_FWK_MODULE(trackerTFP::AnalyzerDR); diff --git a/L1Trigger/TrackerTFP/test/AnalyzerDemonstrator.cc b/L1Trigger/TrackerTFP/test/AnalyzerDemonstrator.cc index 6b65410d03e0f..c2c5761252607 100644 --- a/L1Trigger/TrackerTFP/test/AnalyzerDemonstrator.cc +++ b/L1Trigger/TrackerTFP/test/AnalyzerDemonstrator.cc @@ -21,8 +21,8 @@ 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 */ @@ -64,13 +64,14 @@ namespace trackerTFP { // 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"); + const string& branchStubs = iConfig.getParameter("BranchStubs"); + const string& branchTracks = iConfig.getParameter("BranchTracks"); edGetTokenStubsIn_ = consumes(InputTag(labelIn, branchStubs)); - edGetTokenStubsOut_ = consumes(InputTag(labelOut, branchStubs)); - if (labelIn == "TrackerTFPProducerKFin" || labelIn == "TrackerTFPProducerKF") + if (labelOut != "ProducerTFP") + edGetTokenStubsOut_ = consumes(InputTag(labelOut, branchStubs)); + if (labelIn == "ProducerCTB" || labelIn == "ProducerKF" || labelIn == "ProducerDR") edGetTokenTracksIn_ = consumes(InputTag(labelIn, branchTracks)); - if (labelOut == "TrackerTFPProducerKF" || labelOut == "TrackerTFPProducerDR") + if (labelOut == "ProducerCTB" || labelOut == "ProducerKF" || labelOut == "ProducerDR" || labelOut == "ProducerTFP") edGetTokenTracksOut_ = consumes(InputTag(labelOut, branchTracks)); // book ES products esGetTokenSetup_ = esConsumes(); @@ -85,6 +86,8 @@ namespace trackerTFP { } void AnalyzerDemonstrator::analyze(const Event& iEvent, const EventSetup& iSetup) { + Handle handle; + iEvent.getByToken(edGetTokenStubsIn_, handle); vector> input; vector> output; convert(iEvent, edGetTokenTracksIn_, edGetTokenStubsIn_, input); diff --git a/L1Trigger/TrackerTFP/test/AnalyzerGP.cc b/L1Trigger/TrackerTFP/test/AnalyzerGP.cc index 7a38af978a155..cbec621da5505 100644 --- a/L1Trigger/TrackerTFP/test/AnalyzerGP.cc +++ b/L1Trigger/TrackerTFP/test/AnalyzerGP.cc @@ -14,9 +14,11 @@ #include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" #include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackerTFP/interface/DataFormats.h" #include #include +#include #include #include @@ -45,15 +47,17 @@ namespace trackerTFP { private: // ED input token of stubs - EDGetTokenT edGetTokenAccepted_; - // ED input token of lost stubs - EDGetTokenT edGetTokenLost_; + EDGetTokenT edGetToken_; // ED input token of TTStubRef to TPPtr association for tracking efficiency EDGetTokenT edGetTokenAss_; // Setup token - ESGetToken esGetToken_; + 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_; // @@ -64,6 +68,18 @@ 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_; @@ -72,17 +88,16 @@ namespace trackerTFP { AnalyzerGP::AnalyzerGP(const 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 string& label = iConfig.getParameter("OutputLabelGP"); + const string& branch = iConfig.getParameter("BranchStubs"); + edGetToken_ = consumes(InputTag(label, branch)); if (useMCTruth_) { 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_.precision(4); @@ -90,16 +105,33 @@ namespace trackerTFP { void AnalyzerGP::beginRun(const Run& iEvent, const 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; 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(); @@ -108,11 +140,20 @@ namespace trackerTFP { } void AnalyzerGP::analyze(const Event& iEvent, const 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); + Handle handleStubs; + iEvent.getByToken(edGetToken_, handleStubs); // read in MCTruth const StubAssociation* stubAssociation = nullptr; if (useMCTruth_) { @@ -120,16 +161,17 @@ namespace trackerTFP { 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; for (int region = 0; region < setup_->numRegions(); region++) { int nStubs(0); - int nLost(0); map> mapTPsTTStubs; for (int channel = 0; channel < setup_->numSectors(); channel++) { const int index = region * setup_->numSectors() + channel; - const StreamStub& accepted = handleAccepted->at(index); + const StreamStub& accepted = handleStubs->at(index); hisChannel_->Fill(accepted.size()); profChannel_->Fill(channel, accepted.size()); for (const FrameStub& frame : accepted) { @@ -148,14 +190,14 @@ namespace trackerTFP { 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 +205,31 @@ 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 vector nums = {numStubs}; + const vector errs = {errStubs}; 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; log_ << "============================================================="; - LogPrint("L1Trigger/TrackerTFP") << log_.str(); + LogPrint(moduleDescription().moduleName()) << log_.str(); } } // namespace trackerTFP diff --git a/L1Trigger/TrackerTFP/test/AnalyzerHT.cc b/L1Trigger/TrackerTFP/test/AnalyzerHT.cc index 62b14e8f5aab8..1f337045f973b 100644 --- a/L1Trigger/TrackerTFP/test/AnalyzerHT.cc +++ b/L1Trigger/TrackerTFP/test/AnalyzerHT.cc @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -48,14 +49,12 @@ namespace trackerTFP { private: // - void formTracks(const StreamStub& stream, vector>& tracks, int qOverPt) const; + 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_; + EDGetTokenT edGetToken_; // ED input token of TTStubRef to TPPtr association for tracking efficiency EDGetTokenT edGetTokenSelection_; // ED input token of TTStubRef to recontructable TPPtr association @@ -78,6 +77,21 @@ 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_; @@ -86,11 +100,9 @@ namespace trackerTFP { AnalyzerHT::AnalyzerHT(const 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 string& label = iConfig.getParameter("OutputLabelHT"); + const string& branch = iConfig.getParameter("BranchStubs"); + edGetToken_ = consumes(InputTag(label, branch)); if (useMCTruth_) { const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); @@ -117,26 +129,56 @@ namespace trackerTFP { 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) { + 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); + Handle handleStubs; + iEvent.getByToken(edGetToken_, handleStubs); // read in MCTruth const StubAssociation* selection = nullptr; const StubAssociation* reconstructable = nullptr; @@ -148,110 +190,115 @@ namespace trackerTFP { 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; 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 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); + 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 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_ << " 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; log_ << "============================================================="; - LogPrint("L1Trigger/TrackerTFP") << log_.str(); + LogPrint(moduleDescription().moduleName()) << log_.str(); } // - void AnalyzerHT::formTracks(const StreamStub& stream, vector>& tracks, int inv2R) const { + void AnalyzerHT::formTracks(const StreamStub& stream, 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(); + }; vector stubs; stubs.reserve(stream.size()); for (const FrameStub& frame : stream) - stubs.emplace_back(frame, dataFormats_, inv2R); + 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(); }; + const int id = toTrkId(*it); + auto different = [id, toTrkId](const StubHT& stub) { return id != toTrkId(stub); }; 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(); }); + transform(start, it, 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); } } diff --git a/L1Trigger/TrackerTFP/test/AnalyzerKF.cc b/L1Trigger/TrackerTFP/test/AnalyzerKF.cc index 3f0b215080aca..39e5ee99da9c4 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,6 +27,7 @@ #include #include #include +#include using namespace std; using namespace edm; @@ -51,25 +51,25 @@ namespace trackerTFP { private: // - void associate(const TTTracks& ttTracks, + void associate(const vector& tracks, + const vector>& stubs, + int region, const StubAssociation* ass, set& tps, int& sum, const vector& his, - TProfile* prof) const; - + const vector& prof, + bool perfect = true) const; // ED input token of accepted Tracks - EDGetTokenT edGetTokenAcceptedStubs_; + 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_; + EDGetTokenT edGetTokenTracks_; // ED input token for number of accepted States - EDGetTokenT edGetTokenNumAcceptedStates_; + EDGetTokenT edGetTokenNumStatesAccepted_; // ED input token for number of lost States - EDGetTokenT edGetTokenNumLostStates_; + EDGetTokenT edGetTokenNumStatesTruncated_; + // ED input token for r-phi and r-z plane chi2s + EDGetTokenT>> edGetTokenChi2s_; // ED input token of TTStubRef to TPPtr association for tracking efficiency EDGetTokenT edGetTokenSelection_; // ED input token of TTStubRef to recontructable TPPtr association @@ -78,14 +78,10 @@ namespace trackerTFP { ESGetToken esGetTokenSetup_; // DataFormats token ESGetToken esGetTokenDataFormats_; - // LayerEncoding token - ESGetToken esGetTokenLayerEncoding_; // stores, calculates and provides run-time constants const Setup* setup_ = nullptr; // const DataFormats* dataFormats_ = nullptr; - // - const LayerEncoding* layerEncoding_ = nullptr; // enables analyze of TPs bool useMCTruth_; // @@ -97,37 +93,44 @@ namespace trackerTFP { TProfile* profChannel_; TH1F* hisChannel_; vector hisRes_; - TProfile* profResZ0_; + 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_; }; AnalyzerKF::AnalyzerKF(const ParameterSet& iConfig) - : useMCTruth_(iConfig.getParameter("UseMCTruth")), hisRes_(4) { + : 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 string& label = iConfig.getParameter("OutputLabelKF"); + const string& branchStubs = iConfig.getParameter("BranchStubs"); + const string& branchTracks = iConfig.getParameter("BranchTracks"); + const string& branchTruncated = iConfig.getParameter("BranchTruncated"); + edGetTokenStubs_ = consumes(InputTag(label, branchStubs)); + edGetTokenTracks_ = consumes(InputTag(label, branchTracks)); + edGetTokenNumStatesAccepted_ = consumes(InputTag(label, branchTracks)); + edGetTokenNumStatesTruncated_ = consumes(InputTag(label, branchTruncated)); + edGetTokenChi2s_ = consumes>>(InputTag(label, branchTracks)); if (useMCTruth_) { const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); @@ -137,7 +140,6 @@ namespace trackerTFP { // book ES products esGetTokenSetup_ = esConsumes(); esGetTokenDataFormats_ = esConsumes(); - esGetTokenLayerEncoding_ = esConsumes(); // log config log_.setf(ios::fixed, ios::floatfield); log_.precision(4); @@ -147,70 +149,87 @@ namespace trackerTFP { // helper class to store configurations setup_ = &iSetup.getData(esGetTokenSetup_); dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); - layerEncoding_ = &iSetup.getData(esGetTokenLayerEncoding_); // book histograms 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 vector names = {"phi0", "inv2R", "z0", "cot"}; + static const 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) { + 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); + Handle handleStubs; + iEvent.getByToken(edGetTokenStubs_, handleStubs); + const StreamsStub& allStubs = *handleStubs; + Handle handleTracks; + iEvent.getByToken(edGetTokenTracks_, handleTracks); + const StreamsTrack& allTracks = *handleTracks; + Handle handleNumStatesAccepted; + iEvent.getByToken(edGetTokenNumStatesAccepted_, handleNumStatesAccepted); + Handle handleNumStatesTruncated; + iEvent.getByToken(edGetTokenNumStatesTruncated_, handleNumStatesTruncated); + Handle>> handleChi2s; + iEvent.getByToken>>(edGetTokenChi2s_, handleChi2s); // read in MCTruth const StubAssociation* selection = nullptr; const StubAssociation* reconstructable = nullptr; @@ -223,82 +242,81 @@ namespace trackerTFP { 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 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) { + set tpPtrsMax; + int numMatched(0); + int numTracks(0); + for (int region = 0; region < setup_->numRegions(); region++) { + 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 StreamTrack& channelTracks = allTracks[index]; + hisChannel_->Fill(channelTracks.size()); + profChannel_->Fill(channel, channelTracks.size()); + vector 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); + vector> tracksStubs(channelTracks.size(), 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 cot = tracks.back().zT() / setup_->chosenRofZ(); + int nLs(0); + for (int layer = 0; layer < numLayers; layer++) { + const 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); } - TrackKF track(frameTrack, dataFormats_); - ttTracks.emplace_back(track.ttTrack(stubs)); - pos++; - } - }; - 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; + 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, + vector(), + vector(), + false); + associate(tracks, tracksStubs, region, selection, tpPtrsMax, tmp, vector(), 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 +326,103 @@ 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 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_ << " 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_ << " max tracking efficiency = " << setw(wNums) << effMax << " +- " << setw(wErrs) << errEffMax << endl; log_ << " fake rate = " << setw(wNums) << fracFake << endl; log_ << " duplicate rate = " << setw(wNums) << fracDup << endl; log_ << " state assessment fraction = " << setw(wNums) << fracSatest << endl; + log_ << " number of states per TFP = " << setw(wNums) << (numStates + numStatesLost) / setup_->numRegions() + << endl; log_ << "============================================================="; - LogPrint("L1Trigger/TrackerTFP") << log_.str(); + LogPrint(moduleDescription().moduleName()) << log_.str(); } // - void AnalyzerKF::associate(const TTTracks& ttTracks, + void AnalyzerKF::associate(const vector& tracks, + const vector>& tracksStubs, + int region, const StubAssociation* ass, 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 vector& prof, + bool perfect) const { + for (int frame = 0; frame < (int)tracks.size(); frame++) { + const TrackKF& track = tracks[frame]; + const vector& stubs = tracksStubs[frame]; + 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 vector& tpPtrs = perfect ? ass->associateFinal(ttStubRefs) : ass->associate(ttStubRefs); if (tpPtrs.empty()) continue; sum++; copy(tpPtrs.begin(), tpPtrs.end(), 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 = 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 = 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 = deltaPhi(tpPhi0 - phi0); + const vector ds = {dPhi0, dInv2R / setup_->invPtToDphi(), dZ0, dCot}; + for (int i = 0; i < (int)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/AnalyzerZHT.cc b/L1Trigger/TrackerTFP/test/AnalyzerTFP.cc similarity index 51% rename from L1Trigger/TrackerTFP/test/AnalyzerZHT.cc rename to L1Trigger/TrackerTFP/test/AnalyzerTFP.cc index 6dc5c5a556a29..9a1483884fcd9 100644 --- a/L1Trigger/TrackerTFP/test/AnalyzerZHT.cc +++ b/L1Trigger/TrackerTFP/test/AnalyzerTFP.cc @@ -14,7 +14,6 @@ #include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" #include "L1Trigger/TrackTrigger/interface/Setup.h" -#include "L1Trigger/TrackerTFP/interface/DataFormats.h" #include #include @@ -33,14 +32,14 @@ using namespace tt; namespace trackerTFP { - /*! \class trackerTFP::AnalyzerZHT - * \brief Class to analyze hardware like structured TTStub Collection generated by Z Hough Transform + /*! \class trackerTFP::AnalyzerTFP + * \brief Class to analyze TTTracks found by tfp * \author Thomas Schuh - * \date 2021, May + * \date 20204 Aug */ - class AnalyzerZHT : public one::EDAnalyzer { + class AnalyzerTFP : public one::EDAnalyzer { public: - AnalyzerZHT(const ParameterSet& iConfig); + AnalyzerTFP(const ParameterSet& iConfig); void beginJob() override {} void beginRun(const Run& iEvent, const EventSetup& iSetup) override; void analyze(const Event& iEvent, const EventSetup& iSetup) override; @@ -48,27 +47,23 @@ namespace trackerTFP { 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; + // 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, + int& nMatchTrk, + bool perfect = false) const; - // ED input token of stubs - EDGetTokenT edGetTokenAccepted_; - // ED input token of lost stubs - EDGetTokenT edGetTokenLost_; + // ED input token of tracks + EDGetTokenT edGetToken_; // 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_; // @@ -76,7 +71,9 @@ namespace trackerTFP { // Histograms + // counts per TFP (processing nonant and event) TProfile* prof_; + // no. of tracks per nonant TProfile* profChannel_; TH1F* hisChannel_; TH1F* hisEff_; @@ -87,14 +84,12 @@ namespace trackerTFP { stringstream log_; }; - AnalyzerZHT::AnalyzerZHT(const ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { + AnalyzerTFP::AnalyzerTFP(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)); + const string& label = iConfig.getParameter("OutputLabelTFP"); + const string& branch = iConfig.getParameter("BranchTTTracks"); + edGetToken_ = consumes(InputTag(label, branch)); if (useMCTruth_) { const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); @@ -103,22 +98,19 @@ namespace trackerTFP { } // 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) { + void AnalyzerTFP::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); + 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"); @@ -128,9 +120,10 @@ namespace trackerTFP { 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 = dataFormats_->numChannel(Process::zht); + 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 @@ -139,13 +132,11 @@ namespace trackerTFP { eff_ = dir.make("EffEta", ";", 128, -2.5, 2.5); } - void AnalyzerZHT::analyze(const Event& iEvent, const EventSetup& iSetup) { + void AnalyzerTFP::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 tracklet products + Handle handle; + iEvent.getByToken(edGetToken_, handle); // read in MCTruth const StubAssociation* selection = nullptr; const StubAssociation* reconstructable = nullptr; @@ -160,60 +151,62 @@ namespace trackerTFP { 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); + // + const TTTracks& ttTracks = *handle.product(); + vector> ttTrackRefsRegions(setup_->numRegions()); + 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++) { - 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); - } + const vector& ttTrackRefs = ttTrackRefsRegions[region]; + const int nStubs = + 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); - prof_->Fill(3, nLost); + // 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 + set tpPtrs; + set tpPtrsSelection; + set tpPtrsPerfect; + int nAllMatched(0); + // convert vector of tracks to vector of vector of associated stubs + vector> tracks; + tracks.reserve(ttTracks.size()); + transform( + ttTracks.begin(), ttTracks.end(), 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_); - 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(4, nAllMatched); + prof_->Fill(5, ttTracks.size()); prof_->Fill(6, tpPtrs.size()); prof_->Fill(7, tpPtrsSelection.size()); - prof_->Fill(8, tpPtrsLost.size()); + // no access to lost tp + prof_->Fill(8, 0); + prof_->Fill(10, tpPtrsPerfect.size()); nEvents_++; - //if ((int)tpPtrsSelection.size() != selection->numTPs()) - //throw cms::Exception("..."); } - void AnalyzerZHT::endJob() { + void AnalyzerTFP::endJob() { if (nEvents_ == 0) return; // effi @@ -223,72 +216,50 @@ namespace trackerTFP { 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 vector nums = {numStubs, numTracks, numTracksLost}; - const vector errs = {errStubs, errTracks, errTracksLost}; + 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_ << " 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 + log_ << " TFP 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_ << " 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_ << "max tracking efficiency = " << setw(wNums) << eff << " +- " << setw(wErrs) << errEff << 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); - } + LogPrint(moduleDescription().moduleName()) << log_.str(); } - // - void AnalyzerZHT::associate(const vector>& tracks, + // gets all TPs associated too any of the tracks & number of tracks matching at least one TP + void AnalyzerTFP::associate(const vector>& tracks, const StubAssociation* ass, set& tps, - int& sum) const { + int& nMatchTrk, + bool perfect) const { for (const vector& ttStubRefs : tracks) { - const vector& tpPtrs = ass->associate(ttStubRefs); + const vector& tpPtrs = perfect ? ass->associateFinal(ttStubRefs) : ass->associate(ttStubRefs); if (tpPtrs.empty()) continue; - sum++; + nMatchTrk++; copy(tpPtrs.begin(), tpPtrs.end(), inserter(tps, tps.begin())); } } } // namespace trackerTFP -DEFINE_FWK_MODULE(trackerTFP::AnalyzerZHT); +DEFINE_FWK_MODULE(trackerTFP::AnalyzerTFP); diff --git a/L1Trigger/TrackerTFP/test/AnalyzerMHT.cc b/L1Trigger/TrackerTFP/test/AnalyzerTQ.cc similarity index 53% rename from L1Trigger/TrackerTFP/test/AnalyzerMHT.cc rename to L1Trigger/TrackerTFP/test/AnalyzerTQ.cc index 530e7f59bcc16..35da10dcecba5 100644 --- a/L1Trigger/TrackerTFP/test/AnalyzerMHT.cc +++ b/L1Trigger/TrackerTFP/test/AnalyzerTQ.cc @@ -18,7 +18,6 @@ #include #include -#include #include #include @@ -33,14 +32,14 @@ using namespace tt; namespace trackerTFP { - /*! \class trackerTFP::AnalyzerMHT - * \brief Class to analyze hardware like structured TTStub Collection generated by Mini Hough Transform + /*! \class trackerTFP::AnalyzerTQ + * \brief Class to analyze hardware like structured track Collection generated by Duplicate Removal * \author Thomas Schuh - * \date 2020, Apr + * \date 2023, Feb */ - class AnalyzerMHT : public one::EDAnalyzer { + class AnalyzerTQ : public one::EDAnalyzer { public: - AnalyzerMHT(const ParameterSet& iConfig); + AnalyzerTQ(const ParameterSet& iConfig); void beginJob() override {} void beginRun(const Run& iEvent, const EventSetup& iSetup) override; void analyze(const Event& iEvent, const EventSetup& iSetup) override; @@ -49,14 +48,20 @@ namespace trackerTFP { private: // - void formTracks(const StreamStub& stream, vector>& tracks) const; + 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; - + void associate(const vector>& tracks, + const StubAssociation* ass, + set& tps, + int& sum, + bool perfect = true) const; // ED input token of stubs - EDGetTokenT edGetTokenAccepted_; - // ED input token of lost stubs - EDGetTokenT edGetTokenLost_; + EDGetTokenT edGetTokenStubs_; + // ED input token of tracks + EDGetTokenT edGetTokenTracks_; // ED input token of TTStubRef to TPPtr association for tracking efficiency EDGetTokenT edGetTokenSelection_; // ED input token of TTStubRef to recontructable TPPtr association @@ -78,23 +83,22 @@ namespace trackerTFP { TProfile* prof_; TProfile* profChannel_; + TProfile* profTracks_; TH1F* hisChannel_; - TH1F* hisEff_; - TH1F* hisEffTotal_; - TEfficiency* eff_; + TH1F* hisTracks_; // printout stringstream log_; }; - AnalyzerMHT::AnalyzerMHT(const ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter("UseMCTruth")) { + AnalyzerTQ::AnalyzerTQ(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)); + const string& label = iConfig.getParameter("OutputLabelTQ"); + const string& branchStubs = iConfig.getParameter("BranchStubs"); + const string& branchTracks = iConfig.getParameter("BranchTracks"); + edGetTokenStubs_ = consumes(InputTag(label, branchStubs)); + edGetTokenTracks_ = consumes(InputTag(label, branchTracks)); if (useMCTruth_) { const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); @@ -109,7 +113,7 @@ namespace trackerTFP { log_.precision(4); } - void AnalyzerMHT::beginRun(const Run& iEvent, const EventSetup& iSetup) { + void AnalyzerTQ::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 @@ -117,35 +121,35 @@ namespace trackerTFP { // book histograms Service fs; TFileDirectory dir; - dir = fs->mkdir("MHT"); - prof_ = dir.make("Counts", ";", 9, 0.5, 9.5); + 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(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(12, "max tp"); // channel occupancy constexpr int maxOcc = 180; - const int numChannels = dataFormats_->numChannel(Process::mht); + 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); - // 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); + // track occupancy + hisTracks_ = dir.make("His Track Occupancy", ";", maxOcc, -.5, maxOcc - .5); + profTracks_ = dir.make("Prof Track Occupancy", ";", numChannels, -.5, numChannels - .5); } - void AnalyzerMHT::analyze(const Event& iEvent, const EventSetup& iSetup) { - auto fill = [](const TPPtr& tpPtr, TH1F* his) { his->Fill(tpPtr->eta()); }; + void AnalyzerTQ::analyze(const Event& iEvent, const EventSetup& iSetup) { // read in ht products - Handle handleAccepted; - iEvent.getByToken(edGetTokenAccepted_, handleAccepted); - Handle handleLost; - iEvent.getByToken(edGetTokenLost_, handleLost); + Handle handleStubs; + iEvent.getByToken(edGetTokenStubs_, handleStubs); + const StreamsStub& acceptedStubs = *handleStubs; + Handle handleTracks; + iEvent.getByToken(edGetTokenTracks_, handleTracks); + const StreamsTrack& acceptedTracks = *handleTracks; // read in MCTruth const StubAssociation* selection = nullptr; const StubAssociation* reconstructable = nullptr; @@ -157,129 +161,112 @@ namespace trackerTFP { 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; + set tpPtrsMax; 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); - } + vector> tracks; + formTracks(acceptedTracks, acceptedStubs, tracks, region); + hisTracks_->Fill(tracks.size()); + profTracks_->Fill(region, tracks.size()); + const int nTracks = tracks.size(); + const int nStubs = accumulate(tracks.begin(), tracks.end(), 0, [](int sum, const vector& track) { + return sum += (int)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(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()); + prof_->Fill(12, tpPtrsMax.size()); nEvents_++; } - void AnalyzerMHT::endJob() { + void AnalyzerTQ::endJob() { if (nEvents_ == 0) return; - // effi - eff_->SetPassedHistogram(*hisEff_, "f"); - eff_->SetTotalHistogram(*hisEffTotal_, "f"); - // printout MHT summary + // printout DR 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 vector nums = {numStubs, numTracks, numTracksLost}; - const vector errs = {errStubs, errTracks, errTracksLost}; + const double effMax = numTPsEffMax / totalTPs; + const double errEffMax = sqrt(effMax * (1. - effMax) / 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_ << " MHT SUMMARY " << endl; + log_ << " TQ 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_ << " tracking efficiency = " << setw(wNums) << eff << " +- " << setw(wErrs) << errEff << endl; + log_ << " max tracking efficiency = " << setw(wNums) << effMax << " +- " << setw(wErrs) << errEffMax << endl; log_ << " fake rate = " << setw(wNums) << fracFake << endl; log_ << " duplicate rate = " << setw(wNums) << fracDup << endl; log_ << "============================================================="; - LogPrint("L1Trigger/TrackerTFP") << log_.str(); + LogPrint(moduleDescription().moduleName()) << 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 AnalyzerTQ::formTracks(const StreamsTrack& streamsTrack, + const StreamsStub& streamsStubs, + vector>& tracks, + int region) const { + const int offset = region * setup_->numLayers(); + const StreamTrack& streamTrack = streamsTrack[region]; + 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; + deque stubs; + for (int layer = 0; layer < setup_->numLayers(); layer++) { + const FrameStub& stub = streamsStubs[offset + layer][frame]; + if (stub.first.isNonnull()) + stubs.push_back(stub.first); + } + tracks.emplace_back(stubs.begin(), stubs.end()); } } // - void AnalyzerMHT::associate(const vector>& tracks, - const StubAssociation* ass, - set& tps, - int& sum) const { + void AnalyzerTQ::associate(const vector>& tracks, + const StubAssociation* ass, + set& tps, + int& sum, + bool perfect) const { for (const vector& ttStubRefs : tracks) { - const vector& tpPtrs = ass->associate(ttStubRefs); + const vector& tpPtrs = perfect ? ass->associateFinal(ttStubRefs) : ass->associate(ttStubRefs); if (tpPtrs.empty()) continue; sum++; @@ -289,4 +276,4 @@ namespace trackerTFP { } // namespace trackerTFP -DEFINE_FWK_MODULE(trackerTFP::AnalyzerMHT); +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/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..1b29b3a946a10 100644 --- a/SimTracker/TrackTriggerAssociation/interface/StubAssociation.h +++ b/SimTracker/TrackTriggerAssociation/interface/StubAssociation.h @@ -1,7 +1,9 @@ #ifndef SimTracker_TrackTriggerAssociation_StubAssociation_h #define SimTracker_TrackTriggerAssociation_StubAssociation_h -#include "SimDataFormats/Associations/interface/TTTypes.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "DataFormats/Common/interface/Ptr.h" +#include "SimDataFormats/TrackingAnalysis/interface/TrackingParticle.h" #include "L1Trigger/TrackTrigger/interface/Setup.h" #include @@ -9,6 +11,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 @@ -19,7 +23,7 @@ namespace tt { class StubAssociation { public: StubAssociation() { setup_ = nullptr; } - StubAssociation(const Setup* setup) : setup_(setup) {} + StubAssociation(const edm::ParameterSet& pSet, 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 +51,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..5c06c77956b4c 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,16 +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; @@ -34,12 +33,17 @@ namespace tt { * \author Thomas Schuh * \date 2020, Apr */ - class StubAssociator : public global::EDProducer<> { + class StubAssociator : public stream::EDProducer<> { public: explicit StubAssociator(const ParameterSet&); + ~StubAssociator() override {} private: - void produce(StreamID, Event&, const EventSetup&) const override; + void beginRun(const Run&, const EventSetup&) override; + void produce(Event&, const EventSetup&) override; + void endJob() {} + // helper classe to store configurations + const Setup* setup_; // ED input token of TTStubs EDGetTokenT getTokenTTStubDetSetVec_; // ED input token of TTClusterAssociation @@ -50,25 +54,70 @@ namespace tt { EDPutTokenT putTokenSelection_; // Setup token ESGetToken esGetTokenSetup_; + // + ParameterSet pSet_; + // 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 ParameterSet& iConfig) + : pSet_(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")) { // 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")); // 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 Run& iRun, const EventSetup& iSetup) { + setup_ = &iSetup.getData(esGetTokenSetup_); + maxZT_ = sinh(maxEta0_) * setup_->chosenRofZ(); + // configure TrackingParticleSelector + static constexpr double ptMax = 9.e9; + static constexpr int minHit = 0; + static constexpr bool signalOnly = true; + static constexpr bool intimeOnly = true; + static constexpr bool chargedOnly = true; + static constexpr bool stableOnly = false; + static const double maxEta = asinh((maxZT_ + maxZ0_) / setup_->chosenRofZ()); + tpSelector_ = TrackingParticleSelector( + minPt_, ptMax, -maxEta, maxEta, maxVertR_, maxVertZ_, minHit, signalOnly, intimeOnly, chargedOnly, stableOnly); + } + void StubAssociator::produce(Event& iEvent, const EventSetup& iSetup) { // associate TTStubs with TrackingParticles - Handle handleTTStubDetSetVec = iEvent.getHandle(getTokenTTStubDetSetVec_); - auto const& ttClusterAssMap = iEvent.get(getTokenTTClusterAssMap_); - + Handle handleTTStubDetSetVec; + iEvent.getByToken(getTokenTTStubDetSetVec_, handleTTStubDetSetVec); + Handle handleTTClusterAssMap; + iEvent.getByToken(getTokenTTClusterAssMap_, handleTTClusterAssMap); map> mapTPPtrsTTStubRefs; auto isNonnull = [](const TPPtr& tpPtr) { return tpPtr.isNonnull(); }; for (TTStubDetSetVec::const_iterator ttModule = handleTTStubDetSetVec->begin(); @@ -78,7 +127,8 @@ namespace tt { const TTStubRef ttStubRef = makeRefTo(handleTTStubDetSetVec, ttStub); set tpPtrs; for (unsigned int iClus = 0; iClus < 2; iClus++) { - const vector& assocPtrs = ttClusterAssMap.findTrackingParticlePtrs(ttStubRef->clusterRef(iClus)); + const vector& assocPtrs = + handleTTClusterAssMap->findTrackingParticlePtrs(ttStubRef->clusterRef(iClus)); copy_if(assocPtrs.begin(), assocPtrs.end(), inserter(tpPtrs, tpPtrs.begin()), isNonnull); } for (const TPPtr& tpPtr : tpPtrs) @@ -86,17 +136,30 @@ namespace tt { } } // associate reconstructable TrackingParticles with TTStubs - StubAssociation reconstructable(&setup); - StubAssociation selection(&setup); + StubAssociation reconstructable(pSet_, setup_); + StubAssociation selection(pSet_, setup_); for (const auto& p : mapTPPtrsTTStubRefs) { - if (!setup.useForReconstructable(*p.first) || !setup.reconstructable(p.second)) + // require min layers + 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 ((int)hitPattern.size() < minLayers_ || (int)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 ((abs(p.first->d0()) > maxD0_) || (abs(p.first->z0()) > maxZ0_) || (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)); - iEvent.emplace(putTokenSelection_, std::move(selection)); + iEvent.emplace(putTokenReconstructable_, move(reconstructable)); + iEvent.emplace(putTokenSelection_, move(selection)); } } // namespace tt 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..d8ccdf762211a 100644 --- a/SimTracker/TrackTriggerAssociation/src/StubAssociation.cc +++ b/SimTracker/TrackTriggerAssociation/src/StubAssociation.cc @@ -6,9 +6,17 @@ #include using namespace std; +using namespace edm; namespace tt { + StubAssociation::StubAssociation(const edm::ParameterSet& pSet, const Setup* setup) + : setup_(setup), + minLayersGood_(pSet.getParameter("MinLayersGood")), + minLayersGoodPS_(pSet.getParameter("MinLayersGoodPS")), + maxLayersBad_(pSet.getParameter("MaxLayersBad")), + maxLayersBadPS_(pSet.getParameter("MaxLayersBadPS")) {} + // insert a TPPtr and its associated collection of TTstubRefs into the underlayering maps void StubAssociation::insert(const TPPtr& tpPtr, const vector& ttSTubRefs) { mapTPPtrsTTStubRefs_.insert({tpPtr, ttSTubRefs}); @@ -32,32 +40,32 @@ namespace tt { // 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 { // count associated layer for each TP - map> m; - map> mPS; + map, 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 pair, set>>& p) { + return sum + + ((int)p.second.first.size() < minLayersGood_ || (int)p.second.second.size() < minLayersGoodPS_ ? 0 : 1); }; const int nTPs = accumulate(m.begin(), m.end(), 0, acc); 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 ((int)p.second.first.size() >= minLayersGood_ && (int)p.second.second.size() >= minLayersGoodPS_) tpPtrs.push_back(p.first); return tpPtrs; } // 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 { + vector StubAssociation::associateFinal(const 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); // remove TPs with more then 'tpMaxBadStubs2S' not associated 2S stubs and more then 'tpMaxBadStubsPS' not associated PS stubs @@ -69,9 +77,7 @@ namespace tt { if (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()); return tpPtrs;