diff --git a/DataFormats/L1TrackTrigger/interface/TTTypes.h b/DataFormats/L1TrackTrigger/interface/TTTypes.h index 379cfed2375bc..cd39890561977 100644 --- a/DataFormats/L1TrackTrigger/interface/TTTypes.h +++ b/DataFormats/L1TrackTrigger/interface/TTTypes.h @@ -62,8 +62,10 @@ namespace tt { typedef std::pair FrameTrack; typedef std::vector StreamStub; typedef std::vector StreamTrack; + typedef std::vector Stream; typedef std::vector StreamsStub; typedef std::vector StreamsTrack; + typedef std::vector Streams; typedef std::map TTTrackRefMap; typedef std::vector> TTTracks; } // namespace tt diff --git a/DataFormats/L1TrackTrigger/src/classes_def.xml b/DataFormats/L1TrackTrigger/src/classes_def.xml index 65be8958c272a..2166f4463b5c9 100644 --- a/DataFormats/L1TrackTrigger/src/classes_def.xml +++ b/DataFormats/L1TrackTrigger/src/classes_def.xml @@ -26,8 +26,10 @@ + + diff --git a/L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h b/L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h index 86ac64270cfab..244beaaa7d28a 100644 --- a/L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h +++ b/L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h @@ -26,8 +26,10 @@ namespace trklet { bool channelId(const TTTrackRef& ttTrackRef, int& channelId); // number of used channels int numChannels() const { return numChannels_; } - // sets layerId (0-7 in sequence the seed type projects to) of given TTStubRef and TTTrackRef, returns false if seeed stub - bool layerId(const TTTrackRef& ttTrackRef, const TTStubRef& ttStubRef, int& layerId); + // sets layerId (0-7 in sequence the seed type projects to) of given TTStubRef and seedType, returns false if seeed stub + bool layerId(int seedType, const TTStubRef& ttStubRef, int& layerId); + // return tracklet layerId (barrel: [0-5], endcap: [6-10]) for given TTStubRef + int trackletLayerId(const TTStubRef& ttStubRef) const; // max number layers a sedd type may project to int maxNumProjectionLayers() const { return maxNumProjectionLayers_; } // map of used DTC tfp channels in InputRouter diff --git a/L1Trigger/TrackFindingTracklet/interface/FitTrack.h b/L1Trigger/TrackFindingTracklet/interface/FitTrack.h index e72c4cf664132..72cffa6b842d0 100644 --- a/L1Trigger/TrackFindingTracklet/interface/FitTrack.h +++ b/L1Trigger/TrackFindingTracklet/interface/FitTrack.h @@ -5,8 +5,10 @@ #include "L1Trigger/TrackFindingTracklet/interface/TrackletParametersMemory.h" #include "L1Trigger/TrackFindingTracklet/interface/FullMatchMemory.h" #include "L1Trigger/TrackFindingTracklet/interface/TrackFitMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h" #include +#include namespace trklet { @@ -38,7 +40,10 @@ namespace trklet { std::vector orderedMatches(std::vector& fullmatch); - void execute(unsigned int iSector); + void execute(ChannelAssignment* channelAssignment, + std::deque& streamTrack, + std::vector>& streamsStub, + unsigned int iSector); private: std::vector seedtracklet_; diff --git a/L1Trigger/TrackFindingTracklet/interface/L1TStub.h b/L1Trigger/TrackFindingTracklet/interface/L1TStub.h index 95a85bdaf4f1a..484836bc6aea9 100644 --- a/L1Trigger/TrackFindingTracklet/interface/L1TStub.h +++ b/L1Trigger/TrackFindingTracklet/interface/L1TStub.h @@ -2,6 +2,7 @@ #define L1Trigger_TrackFindingTracklet_interface_L1TStub_h #include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" #include #include @@ -26,7 +27,8 @@ namespace trklet { double z, double bend, double strip, - std::vector tps); + std::vector tps, + const TTStubRef& ttStubRef); ~L1TStub() = default; @@ -107,6 +109,8 @@ namespace trklet { const std::string& stubword() const { return stubword_; } + TTStubRef ttStubRef() const { return ttStubRef_; } + private: int layerdisk_; std::string DTClink_; @@ -131,6 +135,7 @@ namespace trklet { unsigned int isPSmodule_; unsigned int isFlipped_; + TTStubRef ttStubRef_; }; }; // namespace trklet #endif diff --git a/L1Trigger/TrackFindingTracklet/interface/SLHCEvent.h b/L1Trigger/TrackFindingTracklet/interface/SLHCEvent.h index 74dfc0d22d3fd..6e41e3b475bae 100644 --- a/L1Trigger/TrackFindingTracklet/interface/SLHCEvent.h +++ b/L1Trigger/TrackFindingTracklet/interface/SLHCEvent.h @@ -39,7 +39,8 @@ namespace trklet { double z, double bend, double strip, - std::vector tps); + std::vector tpstt, + const TTStubRef& ttStubRef); const L1TStub& lastStub() const { return stubs_.back(); } diff --git a/L1Trigger/TrackFindingTracklet/interface/Sector.h b/L1Trigger/TrackFindingTracklet/interface/Sector.h index ab3d67bdb39e7..99857c44d4980 100644 --- a/L1Trigger/TrackFindingTracklet/interface/Sector.h +++ b/L1Trigger/TrackFindingTracklet/interface/Sector.h @@ -4,6 +4,7 @@ #include "L1Trigger/TrackFindingTracklet/interface/L1TStub.h" #include "L1Trigger/TrackFindingTracklet/interface/SLHCEvent.h" +#include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h" #include #include @@ -114,7 +115,7 @@ namespace trklet { void executeME(); void executeMC(); void executeMP(); - void executeFT(); + void executeFT(ChannelAssignment* channelAssignment, tt::Streams& streamsTrack, tt::StreamsStub& streamsStub); void executePD(std::vector& tracks); std::vector getAllTracklets() const; diff --git a/L1Trigger/TrackFindingTracklet/interface/Settings.h b/L1Trigger/TrackFindingTracklet/interface/Settings.h index 2b2c6254e1d4e..6a9c8eab1269d 100644 --- a/L1Trigger/TrackFindingTracklet/interface/Settings.h +++ b/L1Trigger/TrackFindingTracklet/interface/Settings.h @@ -240,7 +240,11 @@ namespace trklet { bool doKF() const { return doKF_; } bool doMultipleMatches() const { return doMultipleMatches_; } bool fakefit() const { return fakefit_; } + bool emulateTB() const { return emulateTB_; } void setFakefit(bool fakefit) { fakefit_ = fakefit; } + void setEmulateTB(bool emulateTB) { emulateTB_ = emulateTB; } + void setRemovalType(std::string removalType) { removalType_ = removalType; } + void setDoMultipleMatches(bool doMultipleMatches) { doMultipleMatches_ = doMultipleMatches; } // configurable unsigned int nHelixPar() const { return nHelixPar_; } @@ -905,6 +909,8 @@ namespace trklet { // if true, run a dummy fit, producing TTracks directly from output of tracklet pattern reco stage bool fakefit_{false}; + // if true EDProducer prduces additionaly bit and clock accurate TrackBuilder output + bool emulateTB_{false}; unsigned int nHelixPar_{4}; // 4 or 5 param helix fit bool extended_{false}; // turn on displaced tracking diff --git a/L1Trigger/TrackFindingTracklet/interface/TrackletEventProcessor.h b/L1Trigger/TrackFindingTracklet/interface/TrackletEventProcessor.h index 114b2f0e32dc5..4a218341736fe 100644 --- a/L1Trigger/TrackFindingTracklet/interface/TrackletEventProcessor.h +++ b/L1Trigger/TrackFindingTracklet/interface/TrackletEventProcessor.h @@ -3,10 +3,12 @@ #define L1Trigger_TrackFindingTracklet_interface_TrackletEventProcessor_h #include "L1Trigger/TrackFindingTracklet/interface/Timer.h" +#include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h" #include #include #include +#include #include namespace trklet { @@ -24,7 +26,7 @@ namespace trklet { ~TrackletEventProcessor(); - void init(Settings const& theSettings); + void init(Settings const& theSettings, ChannelAssignment* channelAssignment); void event(SLHCEvent& ev); @@ -32,10 +34,13 @@ namespace trklet { const std::vector& tracks() const { return tracks_; } + void produce(tt::Streams& streamsTrack, tt::StreamsStub& streamsStub); + private: void configure(std::istream& inwire, std::istream& inmem, std::istream& inproc); const Settings* settings_{nullptr}; + ChannelAssignment* channelAssignment_{nullptr}; std::unique_ptr globals_; @@ -63,6 +68,8 @@ namespace trklet { Timer PDTimer_; std::vector tracks_; + tt::Streams streamsTrack_; + tt::StreamsStub streamsStub_; }; }; // namespace trklet diff --git a/L1Trigger/TrackFindingTracklet/plugins/L1FPGATrackProducer.cc b/L1Trigger/TrackFindingTracklet/plugins/L1FPGATrackProducer.cc index f724388bc2728..530144534b35f 100644 --- a/L1Trigger/TrackFindingTracklet/plugins/L1FPGATrackProducer.cc +++ b/L1Trigger/TrackFindingTracklet/plugins/L1FPGATrackProducer.cc @@ -83,6 +83,10 @@ #include "L1Trigger/TrackFindingTracklet/interface/Sector.h" #include "L1Trigger/TrackFindingTracklet/interface/Track.h" #include "L1Trigger/TrackFindingTracklet/interface/TrackletEventProcessor.h" +#include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h" +#include "L1Trigger/TrackFindingTracklet/interface/Tracklet.h" +#include "L1Trigger/TrackFindingTracklet/interface/Residual.h" +#include "L1Trigger/TrackFindingTracklet/interface/Stub.h" //////////////// // PHYSICS TOOLS @@ -106,6 +110,8 @@ // NAMESPACES using namespace edm; using namespace std; +using namespace tt; +using namespace trklet; ////////////////////////////// // // @@ -184,6 +190,15 @@ class L1FPGATrackProducer : public edm::one::EDProducer { edm::EDGetTokenT> TrackingParticleToken_; edm::EDGetTokenT tokenDTC_; + // ED output token for clock and bit accurate tracks + EDPutTokenT edPutTokenTracks_; + // ED output token for clock and bit accurate stubs + EDPutTokenT edPutTokenStubs_; + // ChannelAssignment token + ESGetToken esGetTokenChannelAssignment_; + // helper class to assign tracks to channel + ChannelAssignment* channelAssignment_; + // helper class to store DTC configuration tt::Setup setup_; @@ -233,8 +248,15 @@ L1FPGATrackProducer::L1FPGATrackProducer(edm::ParameterSet const& iConfig) tableTREFile = iConfig.getParameter("tableTREFile"); } + // book ED output token for clock and bit accurate tracks + edPutTokenTracks_ = produces("Level1TTTracks"); + // book ED output token for clock and bit accurate stubs + edPutTokenStubs_ = produces("Level1TTTracks"); // book ES product + esGetTokenChannelAssignment_ = esConsumes(); esGetToken_ = esConsumes(); + // initial ES products + channelAssignment_ = nullptr; // -------------------------------------------------------------------------------- // set options in Settings based on inputs from configuration files @@ -250,6 +272,9 @@ L1FPGATrackProducer::L1FPGATrackProducer(edm::ParameterSet const& iConfig) settings.setWiresFile(wiresFile.fullPath()); settings.setFakefit(iConfig.getParameter("Fakefit")); + settings.setEmulateTB(iConfig.getParameter("EmulateTB")); + settings.setRemovalType(iConfig.getParameter("RemovalType")); + settings.setDoMultipleMatches(iConfig.getParameter("DoMultipleMatches")); if (extended_) { settings.setTableTEDFile(tableTEDFile.fullPath()); @@ -281,6 +306,15 @@ L1FPGATrackProducer::L1FPGATrackProducer(edm::ParameterSet const& iConfig) if (trackQuality_) { trackQualityModel_ = std::make_unique(iConfig.getParameter("TrackQualityPSet")); } + if (settings.emulateTB() && (settings.doMultipleMatches() || settings.removalType() != "")) { + cms::Exception exception("ConfigurationNotSupported."); + exception.addContext("L1FPGATrackProducer::produce"); + if (settings.doMultipleMatches()) + exception << "Emulation of TrackBuilder does not support doMultipleMatches."; + if (settings.removalType() != "") + exception << "Emulation of TrackBuilder does not support duplicate removal."; + throw exception; + } } ///////////// @@ -307,9 +341,10 @@ void L1FPGATrackProducer::beginRun(const edm::Run& run, const edm::EventSetup& i settings.setBfield(mMagneticFieldStrength); setup_ = iSetup.getData(esGetToken_); + channelAssignment_ = const_cast(&iSetup.getData(esGetTokenChannelAssignment_)); // initialize the tracklet event processing (this sets all the processing & memory modules, wiring, etc) - eventProcessor.init(settings); + eventProcessor.init(settings, channelAssignment_); } ////////// @@ -548,7 +583,8 @@ void L1FPGATrackProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSe ttPos.z(), stubbend, stub.first->innerClusterPosition(), - assocTPs); + assocTPs, + stub.first); const trklet::L1TStub& lastStub = ev.lastStub(); stubMap[lastStub] = stub.first; @@ -643,6 +679,17 @@ void L1FPGATrackProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSe iEvent.put(std::move(L1TkTracksForOutput), "Level1TTTracks"); + // produce clock and bit output tracks and stubs + // number of track channel + const int numStreamsTrack = N_SECTOR * channelAssignment_->numChannels(); + // number of stub channel + const int numStreamsStub = numStreamsTrack * channelAssignment_->maxNumProjectionLayers(); + Streams streamsTrack(numStreamsTrack); + StreamsStub streamsStub(numStreamsStub); + eventProcessor.produce(streamsTrack, streamsStub); + iEvent.emplace(edPutTokenTracks_, move(streamsTrack)); + iEvent.emplace(edPutTokenStubs_, move(streamsStub)); + } /// End of produce() // /////////////////////////// diff --git a/L1Trigger/TrackFindingTracklet/plugins/ProducerChannelAssignment.cc b/L1Trigger/TrackFindingTracklet/plugins/ProducerChannelAssignment.cc index 131998776b523..4671dfaefb3ef 100644 --- a/L1Trigger/TrackFindingTracklet/plugins/ProducerChannelAssignment.cc +++ b/L1Trigger/TrackFindingTracklet/plugins/ProducerChannelAssignment.cc @@ -42,4 +42,4 @@ namespace trklet { } // namespace trklet -DEFINE_FWK_EVENTSETUP_MODULE(trklet::ProducerChannelAssignment); \ No newline at end of file +DEFINE_FWK_EVENTSETUP_MODULE(trklet::ProducerChannelAssignment); diff --git a/L1Trigger/TrackFindingTracklet/python/Analyzer_cff.py b/L1Trigger/TrackFindingTracklet/python/Analyzer_cff.py index 0750b5de68ba7..bd8435b005fc9 100644 --- a/L1Trigger/TrackFindingTracklet/python/Analyzer_cff.py +++ b/L1Trigger/TrackFindingTracklet/python/Analyzer_cff.py @@ -3,6 +3,7 @@ from L1Trigger.TrackFindingTracklet.Analyzer_cfi import TrackFindingTrackletAnalyzer_params from L1Trigger.TrackFindingTracklet.ProducerKF_cfi import TrackFindingTrackletProducerKF_params +TrackFindingTrackletAnalyzerTBout = cms.EDAnalyzer( 'trklet::AnalyzerTBout', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducerKF_params ) TrackFindingTrackletAnalyzerTracklet = cms.EDAnalyzer( 'trklet::AnalyzerTracklet', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducerKF_params ) TrackFindingTrackletAnalyzerKFin = cms.EDAnalyzer( 'trklet::AnalyzerKFin', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducerKF_params ) TrackFindingTrackletAnalyzerKF = cms.EDAnalyzer( 'trackerTFP::AnalyzerKF', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducerKF_params ) diff --git a/L1Trigger/TrackFindingTracklet/python/ChannelAssignment_cff.py b/L1Trigger/TrackFindingTracklet/python/ChannelAssignment_cff.py index da5dddbaf4853..adb369d78606f 100644 --- a/L1Trigger/TrackFindingTracklet/python/ChannelAssignment_cff.py +++ b/L1Trigger/TrackFindingTracklet/python/ChannelAssignment_cff.py @@ -2,4 +2,4 @@ from L1Trigger.TrackFindingTracklet.ChannelAssignment_cfi import ChannelAssignment_params -ChannelAssignment = cms.ESProducer("trklet::ProducerChannelAssignment", ChannelAssignment_params) \ No newline at end of file +ChannelAssignment = cms.ESProducer("trklet::ProducerChannelAssignment", ChannelAssignment_params) diff --git a/L1Trigger/TrackFindingTracklet/python/Customize_cff.py b/L1Trigger/TrackFindingTracklet/python/Customize_cff.py new file mode 100644 index 0000000000000..1fb50f1a3ad9c --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/python/Customize_cff.py @@ -0,0 +1,26 @@ +import FWCore.ParameterSet.Config as cms + +def newKFConfig(process): + process.TTTracksFromTrackletEmulation.Fakefit = True + +def fwConfig(process): + newKFConfig(process) + process.TrackTriggerSetup.Firmware.FreqBE = 240 + process.TTTracksFromTrackletEmulation.RemovalType = "" + process.TTTracksFromTrackletEmulation.DoMultipleMatches = False + process.TTTracksFromTrackletEmulation.EmulateTB = True + process.ChannelAssignment.UseDuplicateRemoval = False + process.TrackTriggerSetup.KalmanFilter.NumWorker = 8 + +def reducedConfig(process): + fwConfig(process) + process.TrackTriggerSetup.KalmanFilter.NumWorker = 1 + process.ChannelAssignment.SeedTypes = cms.vstring( "L1L2" ) + process.ChannelAssignment.SeedTypesSeedLayers = cms.PSet( L1L2 = cms.vint32( 1, 2 ) ) + process.ChannelAssignment.SeedTypesProjectionLayers = cms.PSet( L1L2 = cms.vint32( 3, 4, 5, 6 ) ) + process.ChannelAssignment.MaxNumProjectionLayers = 4 + process.ChannelAssignment.IRChannelsIn = cms.vint32( 0, 1, 25, 2, 26, 4, 28, 5, 29, 6, 30, 7, 31, 8, 32, 9, 33 ) + process.TTTracksFromTrackletEmulation.Reduced = True + process.TTTracksFromTrackletEmulation.memoryModulesFile = 'L1Trigger/TrackFindingTracklet/data/reduced_memorymodules.dat' + process.TTTracksFromTrackletEmulation.processingModulesFile = 'L1Trigger/TrackFindingTracklet/data/reduced_processingmodules.dat' + process.TTTracksFromTrackletEmulation.wiresFile = 'L1Trigger/TrackFindingTracklet/data/reduced_wires.dat' \ No newline at end of file diff --git a/L1Trigger/TrackFindingTracklet/python/L1HybridEmulationTracks_cff.py b/L1Trigger/TrackFindingTracklet/python/L1HybridEmulationTracks_cff.py index 7ed54556d09fb..38482124edd0d 100644 --- a/L1Trigger/TrackFindingTracklet/python/L1HybridEmulationTracks_cff.py +++ b/L1Trigger/TrackFindingTracklet/python/L1HybridEmulationTracks_cff.py @@ -9,7 +9,6 @@ # prompt hybrid emulation TTTrackAssociatorFromPixelDigis.TTTracks = cms.VInputTag(cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks") ) -L1TrackletTracks = cms.Sequence(offlineBeamSpot*TrackletTracksFromTrackletEmulation) L1HybridTracks = cms.Sequence(offlineBeamSpot*TTTracksFromTrackletEmulation) L1HybridTracksWithAssociators = cms.Sequence(offlineBeamSpot*TTTracksFromTrackletEmulation*TrackTriggerAssociatorTracks) diff --git a/L1Trigger/TrackFindingTracklet/python/ProducerKF_cff.py b/L1Trigger/TrackFindingTracklet/python/ProducerKF_cff.py index 729b3276310d1..bf7ca23d08416 100644 --- a/L1Trigger/TrackFindingTracklet/python/ProducerKF_cff.py +++ b/L1Trigger/TrackFindingTracklet/python/ProducerKF_cff.py @@ -8,6 +8,8 @@ from L1Trigger.TrackFindingTracklet.ChannelAssignment_cff import ChannelAssignment from L1Trigger.TrackFindingTracklet.ProducerKF_cfi import TrackFindingTrackletProducerKF_params +TrackFindingTrackletProducerIRin = cms.EDProducer( 'trklet::ProducerIRin', TrackFindingTrackletProducerKF_params ) +TrackFindingTrackletProducerTBout = cms.EDProducer( 'trklet::ProducerTBout', TrackFindingTrackletProducerKF_params ) TrackFindingTrackletProducerKFin = cms.EDProducer( 'trklet::ProducerKFin', TrackFindingTrackletProducerKF_params ) TrackFindingTrackletProducerKF = cms.EDProducer( 'trackerTFP::ProducerKF', TrackFindingTrackletProducerKF_params ) TrackFindingTrackletProducerTT = cms.EDProducer( 'trklet::ProducerTT', TrackFindingTrackletProducerKF_params ) diff --git a/L1Trigger/TrackFindingTracklet/python/ProducerKF_cfi.py b/L1Trigger/TrackFindingTracklet/python/ProducerKF_cfi.py index 65c397d5c8ef0..0a432c9be2ded 100644 --- a/L1Trigger/TrackFindingTracklet/python/ProducerKF_cfi.py +++ b/L1Trigger/TrackFindingTracklet/python/ProducerKF_cfi.py @@ -2,18 +2,19 @@ TrackFindingTrackletProducerKF_params = cms.PSet ( - InputTag = cms.InputTag( "TrackletTracksFromTrackletEmulation", "Level1TTTracks"), # - InputTagDTC = cms.InputTag( "TrackerDTCProducer", "StubAccepted"), # - LabelKFin = cms.string ( "TrackFindingTrackletProducerKFin" ), # - LabelKF = cms.string ( "TrackFindingTrackletProducerKF" ), # - LabelTT = cms.string ( "TrackFindingTrackletProducerTT" ), # - LabelAS = cms.string ( "TrackFindingTrackletProducerAS" ), # - LabelKFout = cms.string ( "TrackFindingTrackletProducerKFout" ), # - BranchAcceptedStubs = cms.string ( "StubAccepted" ), # - BranchAcceptedTracks = cms.string ( "TrackAccepted" ), # - 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, lost stubs are filled in BranchLost + InputTag = cms.InputTag( "TTTracksFromTrackletEmulation", "Level1TTTracks"), # + InputTagDTC = cms.InputTag( "TrackerDTCProducer", "StubAccepted"), # + LabelTBout = cms.string ( "TrackFindingTrackletProducerTBout" ), # + LabelKFin = cms.string ( "TrackFindingTrackletProducerKFin" ), # + LabelKF = cms.string ( "TrackFindingTrackletProducerKF" ), # + LabelTT = cms.string ( "TrackFindingTrackletProducerTT" ), # + LabelAS = cms.string ( "TrackFindingTrackletProducerAS" ), # + LabelKFout = cms.string ( "TrackFindingTrackletProducerKFout" ), # + BranchAcceptedStubs = cms.string ( "StubAccepted" ), # + BranchAcceptedTracks = cms.string ( "TrackAccepted" ), # + 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, lost stubs are filled in BranchLost ) \ No newline at end of file diff --git a/L1Trigger/TrackFindingTracklet/python/Tracklet_cfi.py b/L1Trigger/TrackFindingTracklet/python/Tracklet_cfi.py index 3b09605f2a625..751924f5c7ddf 100644 --- a/L1Trigger/TrackFindingTracklet/python/Tracklet_cfi.py +++ b/L1Trigger/TrackFindingTracklet/python/Tracklet_cfi.py @@ -1,5 +1,6 @@ import FWCore.ParameterSet.Config as cms from L1Trigger.TrackTrigger.TrackQualityParams_cfi import * +from L1Trigger.TrackFindingTracklet.ChannelAssignment_cff import ChannelAssignment TTTracksFromTrackletEmulation = cms.EDProducer("L1FPGATrackProducer", TTStubSource = cms.InputTag("TTStubsFromPhase2TrackerDigis","StubAccepted"), @@ -21,7 +22,10 @@ # Quality Flag and Quality params TrackQuality = cms.bool(True), TrackQualityPSet = cms.PSet(TrackQualityParams), - Fakefit = cms.bool(False) + Fakefit = cms.bool(False), + EmulateTB = cms.bool(False), + RemovalType = cms.string("merge"), + DoMultipleMatches = cms.bool(True) ) TTTracksFromExtendedTrackletEmulation = TTTracksFromTrackletEmulation.clone( @@ -43,9 +47,4 @@ memoryModulesFile = cms.FileInPath('L1Trigger/TrackFindingTracklet/data/reduced_memorymodules.dat'), processingModulesFile = cms.FileInPath('L1Trigger/TrackFindingTracklet/data/reduced_processingmodules.dat'), wiresFile = cms.FileInPath('L1Trigger/TrackFindingTracklet/data/reduced_wires.dat'), - ) - -# this is to run Tracklet pattern reco with new KF -TrackletTracksFromTrackletEmulation = TTTracksFromTrackletEmulation.clone( - Fakefit = cms.bool(True) ) \ No newline at end of file diff --git a/L1Trigger/TrackFindingTracklet/src/ChannelAssignment.cc b/L1Trigger/TrackFindingTracklet/src/ChannelAssignment.cc index 7b2ebbdebb228..616f33e1b7f61 100644 --- a/L1Trigger/TrackFindingTracklet/src/ChannelAssignment.cc +++ b/L1Trigger/TrackFindingTracklet/src/ChannelAssignment.cc @@ -132,10 +132,9 @@ namespace trklet { return true; } - // sets layerId of given TTStubRef and TTTrackRef, returns false if seeed stub - bool ChannelAssignment::layerId(const TTTrackRef& ttTrackRef, const TTStubRef& ttStubRef, int& layerId) { + // sets layerId of given TTStubRef and seedType, returns false if seeed stub + bool ChannelAssignment::layerId(int seedType, const TTStubRef& ttStubRef, int& layerId) { layerId = -1; - const int seedType = ttTrackRef->trackSeedType(); if (seedType < 0 || seedType >= numSeedTypes_) { cms::Exception exception("logic_error"); exception.addContext("trklet::ChannelAssignment::layerId"); @@ -160,4 +159,11 @@ namespace trklet { return true; } + // return tracklet layerId (barrel: [0-5], endcap: [6-10]) for given TTStubRef + int ChannelAssignment::trackletLayerId(const TTStubRef& ttStubRef) const { + static constexpr int offsetBarrel = 1; + static constexpr int offsetDisks = 5; + return setup_->layerId(ttStubRef) - (setup_->barrel(ttStubRef) ? offsetBarrel : offsetDisks); + } + } // namespace trklet \ No newline at end of file diff --git a/L1Trigger/TrackFindingTracklet/src/ChannelAssignmentRcd.cc b/L1Trigger/TrackFindingTracklet/src/ChannelAssignmentRcd.cc index 12ad133f92d5e..63f58f4d7b206 100644 --- a/L1Trigger/TrackFindingTracklet/src/ChannelAssignmentRcd.cc +++ b/L1Trigger/TrackFindingTracklet/src/ChannelAssignmentRcd.cc @@ -1,4 +1,4 @@ #include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignmentRcd.h" #include "FWCore/Framework/interface/eventsetuprecord_registration_macro.h" -EVENTSETUP_RECORD_REG(trklet::ChannelAssignmentRcd); \ No newline at end of file +EVENTSETUP_RECORD_REG(trklet::ChannelAssignmentRcd); diff --git a/L1Trigger/TrackFindingTracklet/src/ES_ChannelAssignment.cc b/L1Trigger/TrackFindingTracklet/src/ES_ChannelAssignment.cc index 42476d6e4d3fc..c98934bd494ff 100644 --- a/L1Trigger/TrackFindingTracklet/src/ES_ChannelAssignment.cc +++ b/L1Trigger/TrackFindingTracklet/src/ES_ChannelAssignment.cc @@ -1,4 +1,4 @@ #include "FWCore/Utilities/interface/typelookup.h" #include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h" -TYPELOOKUP_DATA_REG(trklet::ChannelAssignment); \ No newline at end of file +TYPELOOKUP_DATA_REG(trklet::ChannelAssignment); diff --git a/L1Trigger/TrackFindingTracklet/src/FitTrack.cc b/L1Trigger/TrackFindingTracklet/src/FitTrack.cc index 46cf0eb980fb2..e020a480918d3 100644 --- a/L1Trigger/TrackFindingTracklet/src/FitTrack.cc +++ b/L1Trigger/TrackFindingTracklet/src/FitTrack.cc @@ -869,7 +869,10 @@ std::vector FitTrack::orderedMatches(vector& fullma return tmp; } -void FitTrack::execute(unsigned int iSector) { +void FitTrack::execute(ChannelAssignment* channelAssignment, + deque& streamTrack, + vector>& streamsStub, + unsigned int iSector) { // merge const std::vector& matches1 = orderedMatches(fullmatch1_); const std::vector& matches2 = orderedMatches(fullmatch2_); @@ -1023,6 +1026,52 @@ void FitTrack::execute(unsigned int iSector) { trackfit_->addTrack(bestTracklet); } } + // store bit and clock accurate TB output + if (settings_.emulateTB() && bestTracklet) { + // add gap if enough layer to form track + if (!bestTracklet->fit()) { + streamTrack.emplace_back(tt::Frame()); + for (auto& stream : streamsStub) + stream.emplace_back(tt::FrameStub()); + continue; + } + // convert Track word + const int seedType = bestTracklet->getISeed(); + static const string valid = "1"; + const string seed = TTBV(seedType, settings_.nbitsseed()).str(); + const string rinv = bestTracklet->fpgarinv().str(); + const string phi0 = bestTracklet->fpgaphi0().str(); + const string z0 = bestTracklet->fpgaz0().str(); + const string t = bestTracklet->fpgat().str(); + streamTrack.emplace_back(valid + seed + rinv + phi0 + z0 + t); + // hitMap used to remember whcih layer had no stub to fill them with gaps + TTBV hitMap(0, channelAssignment->maxNumProjectionLayers()); + // convert and fill stubs on this track into streamsStub + for (const auto& stub : bestTracklet->getL1Stubs()) { + // get TTStubRef of this stub + const TTStubRef& ttStubRef = stub->ttStubRef(); + // get layerId and skip over seeding layer + int layerId(-1); + if (!channelAssignment->layerId(seedType, ttStubRef, layerId)) + continue; + // mark layerId + hitMap.set(layerId); + // tracklet layerId + const int trackletLayerId = channelAssignment->trackletLayerId(ttStubRef); + // get stub Residual + const Residual& resid = bestTracklet->resid(trackletLayerId); + // create bit accurate 64 bit word + const string& r = resid.stubptr()->r().str(); + const string& phi = resid.fpgaphiresid().str(); + const string& rz = resid.fpgarzresid().str(); + // store TTStubRef and bit accurate 64 bit word in clock accurate output + streamsStub[layerId].emplace_back(ttStubRef, valid + r + phi + rz); + } + // fill all layer with no stubs with gaps + for (int layer : hitMap.ids(false)) { + streamsStub[layer].emplace_back(tt::FrameStub()); + } + } } while (bestTracklet != nullptr && countAll < settings_.maxStep("TB")); diff --git a/L1Trigger/TrackFindingTracklet/src/L1TStub.cc b/L1Trigger/TrackFindingTracklet/src/L1TStub.cc index d7cc37d26b863..af02c5095a3eb 100644 --- a/L1Trigger/TrackFindingTracklet/src/L1TStub.cc +++ b/L1Trigger/TrackFindingTracklet/src/L1TStub.cc @@ -16,7 +16,9 @@ L1TStub::L1TStub(std::string DTClink, double z, double bend, double strip, - std::vector tps) { + std::vector tps, + const TTStubRef& ttStubRef) + : ttStubRef_(ttStubRef) { DTClink_ = DTClink; layerdisk_ = layerdisk; region_ = region; diff --git a/L1Trigger/TrackFindingTracklet/src/SLHCEvent.cc b/L1Trigger/TrackFindingTracklet/src/SLHCEvent.cc index 4ea8f49d3f953..d30d60dde5198 100644 --- a/L1Trigger/TrackFindingTracklet/src/SLHCEvent.cc +++ b/L1Trigger/TrackFindingTracklet/src/SLHCEvent.cc @@ -21,8 +21,9 @@ bool SLHCEvent::addStub(string DTClink, double z, double bend, double strip, - vector tps) { - L1TStub stub(DTClink, region, layerdisk, stubword, isPSmodule, isFlipped, x, y, z, bend, strip, tps); + vector tps, + const TTStubRef& ttStubRef) { + L1TStub stub(DTClink, region, layerdisk, stubword, isPSmodule, isFlipped, x, y, z, bend, strip, tps, ttStubRef); stubs_.push_back(stub); return true; @@ -98,7 +99,7 @@ SLHCEvent::SLHCEvent(istream& in) { tps.push_back(tp); } - L1TStub stub(DTClink, region, layerdisk, stubword, isPSmodule, isFlipped, x, y, z, bend, strip, tps); + L1TStub stub(DTClink, region, layerdisk, stubword, isPSmodule, isFlipped, x, y, z, bend, strip, tps, TTStubRef()); in >> tmp; diff --git a/L1Trigger/TrackFindingTracklet/src/Sector.cc b/L1Trigger/TrackFindingTracklet/src/Sector.cc index f4ddd63a21f8a..8d7418c2c3f4e 100644 --- a/L1Trigger/TrackFindingTracklet/src/Sector.cc +++ b/L1Trigger/TrackFindingTracklet/src/Sector.cc @@ -42,6 +42,8 @@ #include "DataFormats/Math/interface/deltaPhi.h" #include "L1Trigger/TrackFindingTracklet/interface/TrackletLUT.h" +#include + using namespace std; using namespace trklet; @@ -410,13 +412,26 @@ void Sector::executeMP() { } } + // Order here reflects Tracklet algo that calls FitTrack before PurgeDuplicates. // If using Hybrid, then PurgeDuplicates runs both duplicate removal & KF steps. // (unless duplicate removal disabled, in which case FitTrack runs KF). -void Sector::executeFT() { + +void Sector::executeFT(ChannelAssignment* channelAssignment, tt::Streams& streamsTrack, tt::StreamsStub& streamsStub) { + int channelTrack(0); + const int offsetTrack = isector_ * channelAssignment->numChannels(); for (auto& i : FT_) { - i->execute(isector_); + deque streamsTrackTmp; + vector> streamsStubTmp(channelAssignment->maxNumProjectionLayers()); + i->execute(channelAssignment, streamsTrackTmp, streamsStubTmp, isector_); + if (!settings_.emulateTB()) + continue; + const int offestStub = (offsetTrack + channelTrack) * channelAssignment->maxNumProjectionLayers(); + streamsTrack[offsetTrack + channelTrack++] = tt::Stream(streamsTrackTmp.begin(), streamsTrackTmp.end()); + int channelStub(0); + for (deque& stream : streamsStubTmp) + streamsStub[offestStub + channelStub++] = tt::StreamStub(stream.begin(), stream.end()); } } diff --git a/L1Trigger/TrackFindingTracklet/src/TrackletEventProcessor.cc b/L1Trigger/TrackFindingTracklet/src/TrackletEventProcessor.cc index 5c002b5e5311d..ae02bb509992e 100644 --- a/L1Trigger/TrackFindingTracklet/src/TrackletEventProcessor.cc +++ b/L1Trigger/TrackFindingTracklet/src/TrackletEventProcessor.cc @@ -24,8 +24,15 @@ TrackletEventProcessor::~TrackletEventProcessor() { } } -void TrackletEventProcessor::init(Settings const& theSettings) { +void TrackletEventProcessor::init(Settings const& theSettings, ChannelAssignment* channelAssignment) { settings_ = &theSettings; + channelAssignment_ = channelAssignment; + // number of track channel + const int numStreamsTrack = N_SECTOR * channelAssignment_->numChannels(); + // number of stub channel + const int numStreamsStub = numStreamsTrack * channelAssignment_->maxNumProjectionLayers(); + streamsTrack_ = tt::Streams(numStreamsTrack); + streamsStub_ = tt::StreamsStub(numStreamsStub); globals_ = make_unique(*settings_); @@ -177,6 +184,8 @@ void TrackletEventProcessor::event(SLHCEvent& ev) { globals_->event() = &ev; tracks_.clear(); + for (tt::StreamStub& streamStub : streamsStub_) + streamStub.clear(); eventnum_++; bool first = (eventnum_ == 1); @@ -364,7 +373,7 @@ void TrackletEventProcessor::event(SLHCEvent& ev) { // fit track FTTimer_.start(); - sector_->executeFT(); + sector_->executeFT(channelAssignment_, streamsTrack_, streamsStub_); if ((settings_->writeMem() || settings_->writeMonitorData("IFit")) && k == settings_->writememsect()) { sector_->writeTF(first); } @@ -442,3 +451,8 @@ void TrackletEventProcessor::printSummary() { << setprecision(3) << PDTimer_.avgtime() * 1000.0 << setw(20) << setprecision(3) << PDTimer_.tottime(); } + +void TrackletEventProcessor::produce(tt::Streams& streamsTrack, tt::StreamsStub& streamsStub) { + swap(streamsTrack, streamsTrack_); + swap(streamsStub, streamsStub_); +} \ No newline at end of file diff --git a/L1Trigger/TrackFindingTracklet/test/AnalyzerTBout.cc b/L1Trigger/TrackFindingTracklet/test/AnalyzerTBout.cc new file mode 100644 index 0000000000000..d26fd5a1664e8 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/test/AnalyzerTBout.cc @@ -0,0 +1,432 @@ +#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_; + // + const Settings settings_; + // helper class to extract structured data from tt::Frames + const DataFormats* dataFormats_; + // helper class to assign tracklet track to channel + const ChannelAssignment* channelAssignment_; + // enables analyze of TPs + bool useMCTruth_; + // + int nEvents_; + // + vector> regionStubs_; + // + int region_; + // + vector nOverflows_; + + // 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) + : settings_(), useMCTruth_(iConfig.getParameter("UseMCTruth")), nEvents_(0) { + 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(); + // initial ES products + setup_ = nullptr; + dataFormats_ = nullptr; + channelAssignment_ = nullptr; + // + nOverflows_ = vector(2, 0); + // 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_->numChannels() * setup_->numLayers() * 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_->numChannels(); + int nStubs(0); + int nTracks(0); + int nLost(0); + for (int channel = 0; channel < channelAssignment_->numChannels(); 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 SF summary + const double totalTPs = prof_->GetBinContent(9); + const double numStubs = prof_->GetBinContent(1); + const double numTracks = prof_->GetBinContent(2); + const double numTracksLost = prof_->GetBinContent(3); + const double totalTracks = prof_->GetBinContent(5); + const double numTracksMatched = prof_->GetBinContent(4); + const double numTPsAll = prof_->GetBinContent(6); + const double numTPsEff = prof_->GetBinContent(7); + const double numTPsLost = prof_->GetBinContent(8); + const double errStubs = prof_->GetBinError(1); + const double errTracks = prof_->GetBinError(2); + const double errTracksLost = prof_->GetBinError(3); + const double fracFake = (totalTracks - numTracksMatched) / totalTracks; + const double fracDup = (numTracksMatched - numTPsAll) / totalTracks; + const double eff = numTPsEff / totalTPs; + const double errEff = sqrt(eff * (1. - eff) / totalTPs / nEvents_); + const double effLoss = numTPsLost / totalTPs; + const double errEffLoss = sqrt(effLoss * (1. - effLoss) / totalTPs / nEvents_); + const vector nums = {numStubs, numTracks, numTracksLost}; + const vector errs = {errStubs, errTracks, errTracksLost}; + const int wNums = ceil(log10(*max_element(nums.begin(), nums.end()))) + 5; + const int wErrs = ceil(log10(*max_element(errs.begin(), errs.end()))) + 5; + log_ << " 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_ << "number of overflowed rz residuals: " << nOverflows_[0] << " and phi: " << nOverflows_[1] << endl; + log_ << "============================================================="; + LogPrint("L1Trigger/TrackerTFP") << log_.str(); + } + + // + void AnalyzerTBout::formTracks(const StreamsTrack& streamsTrack, + const StreamsStub& streamsStubs, + vector>& tracks, + int channel) { + const int offset = channel * channelAssignment_->maxNumProjectionLayers(); + 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; + for (int layer = 0; layer < channelAssignment_->maxNumProjectionLayers(); layer++) { + const FrameStub& stub = streamsStubs[offset + layer][frame]; + if (stub.first.isNonnull()) + this->fill(frameTrack, stub); + } + tracks.push_back(frameTrack.first->getStubRefs()); + } + } + + // + 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 = channelAssignment_->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); + bool overflowPhi = abs(phii - hwPhi.val()) > pow(2, widthPhi) * 7. / 8.; + bool overflowZ = abs(rzi - hwRZ.val()) > pow(2, widthRZ) * 7. / 8.; + const double hwPhid = hwPhi.val(basePhi); + const double hwRZd = hwRZ.val(baseRZ); + const vector resolutions = {phid - hwPhid, rzd - hwRZd}; + const vector overflows = {overflowPhi, overflowZ}; + for (Resolution r : AllResolution) { + if (overflows[r]) { + nOverflows_[r]++; + continue; + } + 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); \ No newline at end of file diff --git a/L1Trigger/TrackFindingTracklet/test/HybridTracksNewKF_cfg.py b/L1Trigger/TrackFindingTracklet/test/HybridTracksNewKF_cfg.py index c7ccbc4f258c8..803789b341075 100644 --- a/L1Trigger/TrackFindingTracklet/test/HybridTracksNewKF_cfg.py +++ b/L1Trigger/TrackFindingTracklet/test/HybridTracksNewKF_cfg.py @@ -26,6 +26,8 @@ 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 @@ -41,12 +43,13 @@ # build schedule process.mc = cms.Sequence( process.StubAssociator ) process.dtc = cms.Sequence( process.TrackerDTCProducer + process.TrackerDTCAnalyzer ) -process.tracklet = cms.Sequence( process.L1TrackletTracks + process.TrackFindingTrackletAnalyzerTracklet ) +process.tracklet = cms.Sequence( process.L1HybridTracks + process.TrackFindingTrackletAnalyzerTracklet ) process.interIn = cms.Sequence( process.TrackFindingTrackletProducerKFin + process.TrackFindingTrackletAnalyzerKFin ) process.kf = cms.Sequence( process.TrackFindingTrackletProducerKF + process.TrackFindingTrackletAnalyzerKF ) process.TTTracks = cms.Sequence( process.TrackFindingTrackletProducerTT + process.TrackFindingTrackletProducerAS + process.TrackTriggerAssociatorTracks ) process.interOut = cms.Sequence( process.TrackFindingTrackletProducerKFout + process.TrackFindingTrackletAnalyzerKFout ) -process.tt = cms.Path( process.mc + process.dtc + process.tracklet + process.interIn + process.kf + process.TTTracks + process.interOut ) +process.TBout = cms.Sequence( process.TrackFindingTrackletProducerTBout + process.TrackFindingTrackletAnalyzerTBout ) +process.tt = cms.Path( process.mc + process.dtc + process.tracklet + process.TBout + process.interIn + process.kf + process.TTTracks + process.interOut ) process.schedule = cms.Schedule( process.tt ) # create options diff --git a/L1Trigger/TrackFindingTracklet/test/L1TrackNtupleMaker_cfg.py b/L1Trigger/TrackFindingTracklet/test/L1TrackNtupleMaker_cfg.py index 01ffc2f5cc157..c4194f988347c 100644 --- a/L1Trigger/TrackFindingTracklet/test/L1TrackNtupleMaker_cfg.py +++ b/L1Trigger/TrackFindingTracklet/test/L1TrackNtupleMaker_cfg.py @@ -150,13 +150,16 @@ # HYBRID_NEWKF: prompt tracking elif (L1TRKALGO == 'HYBRID_NEWKF'): + process.load("L1Trigger.TrackFindingTracklet.L1HybridEmulationTracks_cff") + from L1Trigger.TrackFindingTracklet.Customize_cff import * + newKFConfig( process ) process.load( 'L1Trigger.TrackFindingTracklet.ProducerKF_cff' ) NHELIXPAR = 4 L1TRK_NAME = process.TrackFindingTrackletProducerKF_params.LabelTT.value() L1TRK_LABEL = process.TrackFindingTrackletProducerKF_params.BranchAcceptedTracks.value() L1TRUTH_NAME = "TTTrackAssociatorFromPixelDigis" process.TTTrackAssociatorFromPixelDigis.TTTracks = cms.VInputTag( cms.InputTag(L1TRK_NAME, L1TRK_LABEL) ) - process.HybridNewKF = cms.Sequence(process.L1TrackletTracks + process.TrackFindingTrackletProducerKFin + process.TrackFindingTrackletProducerKF + process.TrackFindingTrackletProducerTT + process.TrackFindingTrackletProducerAS + process.TrackFindingTrackletProducerKFout) + process.HybridNewKF = cms.Sequence(process.L1HybridTracks + process.TrackFindingTrackletProducerKFin + process.TrackFindingTrackletProducerKF + process.TrackFindingTrackletProducerTT + process.TrackFindingTrackletProducerAS + process.TrackFindingTrackletProducerKFout) process.TTTracksEmulation = cms.Path(process.HybridNewKF) #process.TTTracksEmulationWithTruth = cms.Path(process.HybridNewKF + process.TrackTriggerAssociatorTracks) # Optionally include code producing performance plots & end-of-job summary. diff --git a/L1Trigger/TrackFindingTracklet/test/ProducerIRin.cc b/L1Trigger/TrackFindingTracklet/test/ProducerIRin.cc new file mode 100644 index 0000000000000..8da7687a0d767 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/test/ProducerIRin.cc @@ -0,0 +1,109 @@ +#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 +#include +#include +#include +#include +#include + +using namespace std; +using namespace edm; +using namespace tt; + +namespace trklet { + + /*! \class trklet::ProducerIRin + * \brief Transforms TTTDCinto f/w comparable format for summer chain configuratiotn + * \author Thomas Schuh + * \date 2021, Oct + */ + class ProducerIRin : public stream::EDProducer<> { + public: + explicit ProducerIRin(const ParameterSet&); + ~ProducerIRin() override {} + + private: + virtual void beginRun(const Run&, const EventSetup&) override; + virtual void produce(Event&, const EventSetup&) override; + virtual void endJob() {} + // ED input token of DTC Stubs + EDGetTokenT edGetTokenTTDTC_; + // ED output token for stubs + EDPutTokenT edPutTokenStubs_; + // Setup token + ESGetToken esGetTokenSetup_; + // ChannelAssignment token + ESGetToken esGetTokenChannelAssignment_; + // configuration + ParameterSet iConfig_; + // helper class to store configurations + const Setup* setup_; + // helper class to assign stubs to channel + const ChannelAssignment* channelAssignment_; + // reduce l1 tracking to summer chain configuration + bool summerChain_; + // map of used tfp channels in summer chain config + vector channelEncoding_; + }; + + ProducerIRin::ProducerIRin(const ParameterSet& iConfig) : iConfig_(iConfig) { + const InputTag& inputTag = iConfig.getParameter("InputTagDTC"); + const string& branchStubs = iConfig.getParameter("BranchAcceptedStubs"); + // book in- and output ED products + edGetTokenTTDTC_ = consumes(inputTag); + edPutTokenStubs_ = produces(branchStubs); + // book ES products + esGetTokenSetup_ = esConsumes(); + esGetTokenChannelAssignment_ = esConsumes(); + // initial ES products + setup_ = nullptr; + } + + 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 in summer chain config + channelEncoding_ = channelAssignment_->channelEncoding(); + } + + void ProducerIRin::produce(Event& iEvent, const EventSetup& iSetup) { + // 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 = + summerChain_ ? channelEncoding_.size() : handleTTDTC->tfpRegions().size() * handleTTDTC->tfpChannels().size(); + streamStubs.reserve(numChannel); + for (int tfpRegion : handleTTDTC->tfpRegions()) + for (int tfpChannel : summerChain_ ? channelEncoding_ : handleTTDTC->tfpChannels()) + streamStubs.emplace_back(handleTTDTC->stream(tfpRegion, tfpChannel)); + } + // store products + iEvent.emplace(edPutTokenStubs_, move(streamStubs)); + } + +} // namespace trklet + +DEFINE_FWK_MODULE(trklet::ProducerIRin); diff --git a/L1Trigger/TrackFindingTracklet/test/ProducerTBout.cc b/L1Trigger/TrackFindingTracklet/test/ProducerTBout.cc new file mode 100644 index 0000000000000..1435c68dbe88d --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/test/ProducerTBout.cc @@ -0,0 +1,193 @@ +#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/Settings.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 from Tracklet pattern reco. into f/w comparable format + * \author Thomas Schuh + * \date 2021, Oct + */ + class ProducerTBout : public stream::EDProducer<> { + public: + explicit ProducerTBout(const ParameterSet&); + ~ProducerTBout() override {} + + private: + virtual void beginRun(const Run&, const EventSetup&) override; + virtual 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_; + // helper class to extract structured data from TTDTC::Frames + const DataFormats* dataFormats_; + // helper class to assign tracks to channel + ChannelAssignment* channelAssignment_; + // + bool enableTruncation_; + // + trklet::Settings settings_; + }; + + 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(); + // initial ES products + setup_ = nullptr; + dataFormats_ = nullptr; + channelAssignment_ = nullptr; + // + 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 TTDTC::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_->numChannels(); + const int numStreamsStubs = numStreamsTracks * channelAssignment_->maxNumProjectionLayers(); + // 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); + if (channelAssignment_->channelId(ttTrackRef, channelId)) + 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_->numChannels(); + const int channel = channelId % channelAssignment_->numChannels(); + exception << "Region " << region << " output channel " << channel << " has " << nTracks << " tracks found in f/w 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_, move(streamAcceptedStubs)); + iEvent.emplace(edPutTokenAcceptedTracks_, move(streamAcceptedTracks)); + iEvent.emplace(edPutTokenLostStubs_, move(streamLostStubs)); + iEvent.emplace(edPutTokenLostTracks_, move(streamLostTracks)); + } + +} // namespace trklet + +DEFINE_FWK_MODULE(trklet::ProducerTBout); diff --git a/L1Trigger/TrackFindingTracklet/test/demonstrator_cfg.py b/L1Trigger/TrackFindingTracklet/test/demonstrator_cfg.py index fe4ca21c46886..478b13c17e678 100644 --- a/L1Trigger/TrackFindingTracklet/test/demonstrator_cfg.py +++ b/L1Trigger/TrackFindingTracklet/test/demonstrator_cfg.py @@ -3,8 +3,11 @@ process = cms.Process( "Demo" ) process.load( 'FWCore.MessageService.MessageLogger_cfi' ) +process.load( 'Configuration.EventContent.EventContent_cff' ) process.load( 'Configuration.Geometry.GeometryExtended2026D76Reco_cff' ) process.load( 'Configuration.Geometry.GeometryExtended2026D76_cff' ) +#process.load( 'Configuration.Geometry.GeometryExtended2026D49Reco_cff' ) +#process.load( 'Configuration.Geometry.GeometryExtended2026D49_cff' ) process.load( 'Configuration.StandardSequences.MagneticField_cff' ) process.load( 'Configuration.StandardSequences.FrontierConditions_GlobalTag_cff' ) process.load( 'L1Trigger.TrackTrigger.TrackTrigger_cff' ) @@ -22,15 +25,14 @@ process.load( 'L1Trigger.TrackFindingTracklet.ProducerKF_cff' ) #--- Load code that compares s/w with f/w process.load( 'L1Trigger.TrackerTFP.Demonstrator_cff' ) +from L1Trigger.TrackFindingTracklet.Customize_cff import * +reducedConfig( process ) # build schedule process.tt = cms.Sequence ( process.TrackerDTCProducer - + process.L1TrackletTracks - + process.TrackFindingTrackletProducerKFin - + process.TrackFindingTrackletProducerKF - + process.TrackFindingTrackletProducerTT - + process.TrackFindingTrackletProducerAS - + process.TrackFindingTrackletProducerKFout + + process.L1HybridTracks + + process.TrackFindingTrackletProducerIRin + + process.TrackFindingTrackletProducerTBout ) process.demo = cms.Path( process.tt + process.TrackerTFPDemonstrator ) process.schedule = cms.Schedule( process.demo ) @@ -39,7 +41,7 @@ import FWCore.ParameterSet.VarParsing as VarParsing options = VarParsing.VarParsing( 'analysis' ) # specify input MC -Samples = [ +inputMC = [ #'/store/relval/CMSSW_11_3_0_pre6/RelValSingleMuFlatPt2To100/GEN-SIM-DIGI-RAW/113X_mcRun4_realistic_v6_2026D76noPU-v1/10000/05f802b7-b0b3-4cca-8b70-754682c3bb4c.root' #'/store/relval/CMSSW_11_3_0_pre6/RelValDisplacedMuPt2To100Dxy100/GEN-SIM-DIGI-RAW/113X_mcRun4_realistic_v6_2026D76noPU-v1/00000/011da61a-9524-4a96-b91f-03e8690af3bd.root' '/store/relval/CMSSW_11_3_0_pre6/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_113X_mcRun4_realistic_v6_2026D76PU200-v1/00000/00026541-6200-4eed-b6f8-d3a1fd720e9c.root', @@ -52,8 +54,9 @@ '/store/relval/CMSSW_11_3_0_pre6/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_113X_mcRun4_realistic_v6_2026D76PU200-v1/00000/16760a5c-9cd2-41c3-82e5-399bb962d537.root', '/store/relval/CMSSW_11_3_0_pre6/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_113X_mcRun4_realistic_v6_2026D76PU200-v1/00000/1752640f-2001-4d14-9276-063ec07cea92.root', '/store/relval/CMSSW_11_3_0_pre6/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_113X_mcRun4_realistic_v6_2026D76PU200-v1/00000/180712c9-31a5-4f2a-bf92-a7fbee4dabad.root' + #"/store/relval/CMSSW_11_3_0_pre3/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_113X_mcRun4_realistic_v3_2026D49PU200_rsb-v1/00000/00260a30-734a-4a3a-a4b0-f836ce5502c6.root" ] -options.register( 'inputMC', Samples, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.string, "Files to be processed" ) +options.register( 'inputMC', inputMC, 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() @@ -63,7 +66,7 @@ process.source = cms.Source( "PoolSource", fileNames = cms.untracked.vstring( options.inputMC ), - #skipEvents = cms.untracked.uint32( 914 ), + skipEvents = cms.untracked.uint32( 0 ), secondaryFileNames = cms.untracked.vstring(), duplicateCheckMode = cms.untracked.string( 'noDuplicateCheck' ) ) diff --git a/L1Trigger/TrackTrigger/interface/Setup.h b/L1Trigger/TrackTrigger/interface/Setup.h index 3ac24f4fe615a..c8ba10098bd1e 100644 --- a/L1Trigger/TrackTrigger/interface/Setup.h +++ b/L1Trigger/TrackTrigger/interface/Setup.h @@ -79,10 +79,10 @@ namespace tt { const TrackerGeometry* trackerGeometry() const { return trackerGeometry_; } // TrackerTopology const TrackerTopology* trackerTopology() const { return trackerTopology_; } - // returns bit accurate position of a stub from a given tfp identifier region [0-8] channel [0-47] - GlobalPoint stubPos(bool hybrid, const tt::FrameStub& frame, int tfpRegion, int tfpChannel) const; // returns global TTStub position GlobalPoint stubPos(const TTStubRef& ttStubRef) const; + // returns bit accurate position of a stub from a given tfp region [0-8] + GlobalPoint stubPos(bool hybrid, const tt::FrameStub& frame, int region) const; // empty trackerDTC EDProduct TTDTC ttDTC() const { return TTDTC(numRegions_, numOverlappingRegions_, numDTCsPerRegion_); } // checks if stub collection is considered forming a reconstructable track diff --git a/L1Trigger/TrackTrigger/src/Setup.cc b/L1Trigger/TrackTrigger/src/Setup.cc index c33805914770b..bb4ac8ffd57a5 100644 --- a/L1Trigger/TrackTrigger/src/Setup.cc +++ b/L1Trigger/TrackTrigger/src/Setup.cc @@ -707,20 +707,20 @@ namespace tt { kfWidthLayerCount_ = ceil(log2(zhtMaxStubsPerLayer_)); } - // returns bit accurate position of a stub from a given tfp identifier region [0-8] channel [0-47] - GlobalPoint Setup::stubPos(bool hybrid, const FrameStub& frame, int tfpRegion, int tfpChannel) const { + // returns bit accurate position of a stub from a given tfp region [0-8] + GlobalPoint Setup::stubPos(bool hybrid, const FrameStub& frame, int region) const { GlobalPoint p; if (frame.first.isNull()) return p; TTBV bv(frame.second); if (hybrid) { const DetId& detId = frame.first->getDetId(); - const int dtcId = Setup::dtcId(tfpRegion, tfpChannel); - const bool barrel = detId.subdetId() == StripSubdetector::TOB; - const bool psModule = Setup::psModule(dtcId); + const bool barrel = this->barrel(frame.first); const int layerId = (barrel ? trackerTopology_->layer(detId) : trackerTopology_->tidWheel(detId)) - offsetLayerId_; - const bool side = Setup::side(dtcId); + const bool psModule = this->psModule(frame.first); + const GlobalPoint gp = this->stubPos(frame.first); + const bool side = gp.z() > 0.; SensorModule::Type type; if (barrel && psModule) type = SensorModule::BarrelPS; @@ -740,17 +740,17 @@ namespace tt { const double baseR = hybridBasesR_.at(type); // parse bit vector bv >>= 1 + hybridWidthLayerId_ + widthBend + widthAlpha; - double phi = (bv.val(widthPhi) + .5) * basePhi - hybridRangePhi_ / 2.; + double phi = bv.val(basePhi, widthPhi) - hybridRangePhi_ / 2.; bv >>= widthPhi; - double z = (bv.val(widthZ, 0, true) + .5) * baseZ; + double z = bv.val(baseZ, widthZ, 0, true); bv >>= widthZ; - double r = (bv.val(widthR, 0, barrel) + .5) * baseR; + double r = bv.val(baseR, widthR, 0, barrel); if (barrel) { r += hybridLayerRs_.at(layerId); } else { z += hybridDiskZs_.at(layerId) * (side ? 1. : -1.); } - phi = deltaPhi(phi + tfpRegion * baseRegion_); + phi = deltaPhi(phi + region * baseRegion_); if (type == SensorModule::Disk2S) { r = bv.val(widthR); r = disk2SRs_.at(layerId).at((int)r); @@ -765,7 +765,7 @@ namespace tt { double r = (bv.val(tmttWidthR_, 0, true) + .5) * tmttBaseR_; bv >>= tmttWidthR_; r = r + chosenRofPhi_; - phi = deltaPhi(phi + tfpRegion * baseRegion_); + phi = deltaPhi(phi + region * baseRegion_); p = GlobalPoint(GlobalPoint::Cylindrical(r, phi, z)); } return p; diff --git a/L1Trigger/TrackerDTC/test/Analyzer.cc b/L1Trigger/TrackerDTC/test/Analyzer.cc index 494ea1948058b..59251f4819114 100644 --- a/L1Trigger/TrackerDTC/test/Analyzer.cc +++ b/L1Trigger/TrackerDTC/test/Analyzer.cc @@ -371,7 +371,7 @@ namespace trackerDTC { if (frame.first.isNull()) continue; sum++; - const GlobalPoint& pos = setup_->stubPos(hybrid_, frame, region, channel); + const GlobalPoint& pos = setup_->stubPos(hybrid_, frame, region); const GlobalPoint& ttPos = setup_->stubPos(frame.first); const vector resolutions = { ttPos.perp() - pos.perp(), deltaPhi(ttPos.phi() - pos.phi()), ttPos.z() - pos.z()}; diff --git a/L1Trigger/TrackerTFP/interface/Demonstrator.h b/L1Trigger/TrackerTFP/interface/Demonstrator.h index b57bca6e3ca25..73799b10816fd 100644 --- a/L1Trigger/TrackerTFP/interface/Demonstrator.h +++ b/L1Trigger/TrackerTFP/interface/Demonstrator.h @@ -22,7 +22,7 @@ namespace trackerTFP { Demonstrator(const edm::ParameterSet& iConfig, const tt::Setup* setup); ~Demonstrator() {} // plays input through modelsim and compares result with output - void analyze(const std::vector>& input, + bool analyze(const std::vector>& input, const std::vector>& output) const; private: @@ -31,7 +31,7 @@ namespace trackerTFP { // plays stringstream through modelsim void sim(const std::stringstream& ss) const; // compares stringstream with modelsim output - void compare(std::stringstream& ss) const; + bool compare(std::stringstream& ss) const; // creates emp file header std::string header(int numChannel) const; // creates 6 frame gap between packets diff --git a/L1Trigger/TrackerTFP/python/Demonstrator_cfi.py b/L1Trigger/TrackerTFP/python/Demonstrator_cfi.py index 42f0274b982e9..e70d510eeecfb 100644 --- a/L1Trigger/TrackerTFP/python/Demonstrator_cfi.py +++ b/L1Trigger/TrackerTFP/python/Demonstrator_cfi.py @@ -10,9 +10,9 @@ #RunTime = cms.double( 6.0 ) # runtime in us # hybrid - LabelIn = cms.string( "TrackFindingTrackletProducerKF" ), # - LabelOut = cms.string( "TrackFindingTrackletProducerKF" ), # - DirIPBB = cms.string( "/heplnw039/tschuh/work/proj/kfout/" ), # path to ipbb proj area - RunTime = cms.double( 6.0 ) # runtime in us + LabelIn = cms.string( "TrackFindingTrackletProducerIRin" ), # + LabelOut = cms.string( "TrackFindingTrackletProducerTBout" ), # + DirIPBB = cms.string( "/heplnw039/tschuh/work/proj/sim/" ), # path to ipbb proj area + RunTime = cms.double( 8.0 ) # runtime in us ) \ No newline at end of file diff --git a/L1Trigger/TrackerTFP/src/Demonstrator.cc b/L1Trigger/TrackerTFP/src/Demonstrator.cc index 9d27ee9a7f893..d60e6e4e23d25 100644 --- a/L1Trigger/TrackerTFP/src/Demonstrator.cc +++ b/L1Trigger/TrackerTFP/src/Demonstrator.cc @@ -23,7 +23,7 @@ namespace trackerTFP { numRegions_(setup->numRegions()) {} // plays input through modelsim and compares result with output - void Demonstrator::analyze(const vector>& input, const vector>& output) const { + bool Demonstrator::analyze(const vector>& input, const vector>& output) const { stringstream ss; // converts input into stringstream convert(input, ss); @@ -32,7 +32,7 @@ namespace trackerTFP { // converts output into stringstream convert(output, ss); // compares output with modelsim output - compare(ss); + return compare(ss); } // converts streams of bv into stringstream @@ -81,7 +81,7 @@ namespace trackerTFP { } // compares stringstream with modelsim output - void Demonstrator::compare(stringstream& ss) const { + bool Demonstrator::compare(stringstream& ss) const { // write ss to disk fstream fs; fs.open(dirPre_.c_str(), fstream::out); @@ -101,12 +101,13 @@ namespace trackerTFP { string token; while (getline(ss, token)) n++; - if (n != 4) { + /*if (n != 4) { cms::Exception exception("RunTimeError."); exception.addContext("trackerTFP::Demonstrator::compare"); exception << "Bit error detected."; throw exception; - } + }*/ + return n == 4; } // creates emp file header diff --git a/L1Trigger/TrackerTFP/test/AnalyzerDemonstrator.cc b/L1Trigger/TrackerTFP/test/AnalyzerDemonstrator.cc index a2c0f77338eed..054223fa51fa4 100644 --- a/L1Trigger/TrackerTFP/test/AnalyzerDemonstrator.cc +++ b/L1Trigger/TrackerTFP/test/AnalyzerDemonstrator.cc @@ -32,7 +32,7 @@ namespace trackerTFP { 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 {} + void endJob() override; private: // @@ -57,6 +57,10 @@ namespace trackerTFP { const Setup* setup_; // const Demonstrator* demonstrator_; + // + int nEvents_; + // + int nEventsSuccessful_; }; AnalyzerDemonstrator::AnalyzerDemonstrator(const ParameterSet& iConfig) { @@ -73,7 +77,8 @@ namespace trackerTFP { labelIn == "TrackFindingTrackletProducerKFin" || labelIn == "TrackFindingTrackletProducerKF") edGetTokenTracksIn_ = consumes(InputTag(labelIn, branchTracks)); if (labelOut == "TrackerTFPProducerKF" || labelOut == "TrackerTFPProducerDR" || - labelOut == "TrackFindingTrackletProducerKF" || labelOut == "TrackFindingTrackletProducerKFout") + labelOut == "TrackFindingTrackletProducerKF" || labelOut == "TrackFindingTrackletProducerKFout" || + labelOut == "TrackFindingTrackletProducerTBout") edGetTokenTracksOut_ = consumes(InputTag(labelOut, branchTracks)); // book ES products esGetTokenSetup_ = esConsumes(); @@ -81,6 +86,8 @@ namespace trackerTFP { // initial ES product setup_ = nullptr; demonstrator_ = nullptr; + nEvents_ = 0; + nEventsSuccessful_ = 0; } void AnalyzerDemonstrator::beginRun(const Run& iEvent, const EventSetup& iSetup) { @@ -91,11 +98,13 @@ namespace trackerTFP { } void AnalyzerDemonstrator::analyze(const Event& iEvent, const EventSetup& iSetup) { + nEvents_++; vector> input; vector> output; convert(iEvent, edGetTokenTracksIn_, edGetTokenStubsIn_, input); convert(iEvent, edGetTokenTracksOut_, edGetTokenStubsOut_, output); - demonstrator_->analyze(input, output); + if (demonstrator_->analyze(input, output)) + nEventsSuccessful_++; } // @@ -149,6 +158,12 @@ namespace trackerTFP { transform(collection.begin(), collection.end(), back_inserter(bvs), [](const auto& frame) { return frame.second; }); } + void AnalyzerDemonstrator::endJob() { + stringstream log; + log << "Successrate: " << nEventsSuccessful_ << " / " << nEvents_ << " = " << nEventsSuccessful_ / (double)nEvents_; + LogPrint("L1Trigger/TrackerTFP") << log.str(); + } + } // namespace trackerTFP DEFINE_FWK_MODULE(trackerTFP::AnalyzerDemonstrator); \ No newline at end of file