diff --git a/L1Trigger/Phase2L1GT/README.md b/L1Trigger/Phase2L1GT/README.md index 8474c6e682a9b..f32fa240a0ac6 100644 --- a/L1Trigger/Phase2L1GT/README.md +++ b/L1Trigger/Phase2L1GT/README.md @@ -199,3 +199,93 @@ process.pDoubleTkEle25_12 = cms.Path(process.DoubleTkEle2512) algorithms.append(cms.PSet(expression = cms.string("pSingleTkMuon22 or pDoubleTkEle25_12"))) ``` + +## Firmware pattern writers + +There are 3 types of Global Trigger pattern writers currently implemented. + +* `L1GTAlgoBoardWriter`: Used to write out the algorithm bits into 2 channels. With config + +| Name | Datatype | Description | +|:-----|:----------:|:--------------| +| `filename` | `cms.string` | The filename prefix to use for pattern files (required) | +| `fileExtension` | `cms.string` | `txt`, `txt.gz` or `txt.xz` (default: `txt`) | +| `algoBlocksTag` | `cms.InputTag` | AlgoBlock producer input tag to use (required) | +| `maxFrames` | `cms.unit32` | Maximum number of frames (default: 1024) | +| `maxEvents` | `cms.unit32` | Maximum number of events (default: events that fit into `maxFrames`) | +| `channels` | `cms.vuint32` | Vector of 2 channel numbers for output (required) | +| `algoBitMask` | `cms.vuint64` | Vector of 9 64 bit masks (default: all set to 1) | +| `patternFormat` | `cms.string` | `APx`, `EMPv1`, `EMPv2` or `X2O` (default: `EMPv2`) | + +* `L1GTFinOrBoardWriter`: Used to write out Final OR bits (beforeBxMaskAndPrescale, beforePrescale and final) each on a different channel for the low bits (0 - 575), mid bits (576 - 1151) and high bits (1152 - 1727). 9 channels in total + one channel for the passing Final OR trigger types. Config: + +| Name | Datatype | Description | +|:-----|:----------:|:--------------| +| `filename` | `cms.string` | The filename prefix to use for pattern files (required) | +| `fileExtension` | `cms.string` | `txt`, `txt.gz` or `txt.xz` (default: `txt`) | +| `algoBlocksTag` | `cms.InputTag` | AlgoBlock producer input tag to use (required) | +| `maxFrames` | `cms.unit32` | Maximum number of frames (default: 1024) | +| `maxEvents` | `cms.unit32` | Maximum number of events (default: events that fit into `maxFrames`) | +| `channelsLow` | `cms.vuint32` | Vector of 3 channel numbers for low bits (0 - 575) (required) | +| `channelsMid` | `cms.vuint32` | Vector of 3 channel numbers for mid bits (576 - 1151) (required) | +| `channelsHigh` | `cms.vuint32` | Vector of 3 channel numbers for high bits (1152 - 1727) (required) | +| `channelFinOr` | `cms.uint32` | Channel for FinalOr trigger types (required) | +| `patternFormat` | `cms.string` | `APx`, `EMPv1`, `EMPv2` or `X2O` (default: `EMPv2`) | + +* `L1GTObjectBoardWriter`: Used to write input and output object patterns using the upstream provided pack functions. + +| Name | Datatype | Description | +|:-----|:----------:|:--------------| +| `filename` | `cms.string` | The filename prefix to use for pattern files (required) | +| `fileExtension` | `cms.string` | `txt`, `txt.gz` or `txt.xz` (default: `txt`) | +| `maxFrames` | `cms.unit32` | Maximum number of frames (default: 1024) | +| `maxEvents` | `cms.unit32` | Maximum number of events (default: events that fit into `maxFrames`) | +| `patternFormat` | `cms.string` | `APx`, `EMPv1`, `EMPv2` or `X2O` (default: `EMPv2`) | +| `bufferFileType`| `cms.string` | Either `input` or `output` (required) | +| `InputChannels.GCT_1` | `cms.vuint32` | Channels for GCT link 1 (required if `bufferFileType` = `input`) | +| `InputChannels.GMT_1` | `cms.vuint32` | Channels for GMT link 1 (required if `bufferFileType` = `input`) | +| `InputChannels.GTT_1` | `cms.vuint32` | Channels for GTT link 1 (required if `bufferFileType` = `input`) | +| `InputChannels.GTT_2` | `cms.vuint32` | Channels for GTT link 2 (required if `bufferFileType` = `input`) | +| `InputChannels.GTT_3` | `cms.vuint32` | Channels for GTT link 3 (required if `bufferFileType` = `input`) | +| `InputChannels.GTT_4` | `cms.vuint32` | Channels for GTT link 4 (required if `bufferFileType` = `input`) | +| `InputChannels.CL2_1` | `cms.vuint32` | Channels for CL2 link 1 (required if `bufferFileType` = `input`) | +| `InputChannels.CL2_2` | `cms.vuint32` | Channels for CL2 link 2 (required if `bufferFileType` = `input`) | +| `InputChannels.CL2_3` | `cms.vuint32` | Channels for CL2 link 3 (required if `bufferFileType` = `input`) | +| `OutputChannels.GTTPromptJets` | `cms.vuint32` | Channels for collection GTTPromptJets (required if `bufferFileType` = `output`) | +| `OutputChannels.GTTDisplacedJets` | `cms.vuint32` | Channels for collection GTTDisplacedJets (required if `bufferFileType` = `output`) | +| `OutputChannels.GTTPromptHtSum` | `cms.vuint32` | Channels for collection GTTPromptHtSum (required if `bufferFileType` = `output`) | +| `OutputChannels.GTTDisplacedHtSum` | `cms.vuint32` | Channels for collection GTTDisplacedHtSum (required if `bufferFileType` = `output`) | +| `OutputChannels.GTTEtSum` | `cms.vuint32` | Channels for collection GTTEtSum (required if `bufferFileType` = `output`) | +| `OutputChannels.GTTPrimaryVert` | `cms.vuint32` | Channels for collection GTTPrimaryVert (required if `bufferFileType` = `output`) | +| `OutputChannels.GMTSaPromptMuons` | `cms.vuint32` | Channels for collection GMTSaPromptMuons (required if `bufferFileType` = `output`) | +| `OutputChannels.GMTSaDisplacedMuons` | `cms.vuint32` | Channels for collection GMTSaDisplacedMuons (required if `bufferFileType` = `output`) | +| `OutputChannels.GMTTkMuons` | `cms.vuint32` | Channels for collection GMTTkMuons (required if `bufferFileType` = `output`) | +| `OutputChannels.CL2JetsSC4` | `cms.vuint32` | Channels for collection CL2JetsSC4 (required if `bufferFileType` = `output`) | +| `OutputChannels.CL2JetsSC8` | `cms.vuint32` | Channels for collection CL2JetsSC8 (required if `bufferFileType` = `output`) | +| `OutputChannels.CL2Photons` | `cms.vuint32` | Channels for collection CL2Photons (required if `bufferFileType` = `output`) | +| `OutputChannels.CL2Electrons` | `cms.vuint32` | Channels for collection CL2Electrons (required if `bufferFileType` = `output`) | +| `OutputChannels.CL2Taus` | `cms.vuint32` | Channels for collection CL2Taus (required if `bufferFileType` = `output`) | +| `OutputChannels.CL2EtSum` | `cms.vuint32` | Channels for collection CL2EtSum (required if `bufferFileType` = `output`) | +| `OutputChannels.CL2HtSum` | `cms.vuint32` | Channels for collection CL2HtSum (required if `bufferFileType` = `output`) | + +Note: In order to get consistency across multiple pattern files written by multiple writers it is recommended to produce patterns in single threaded mode only (i.e. `process.options.numberOfThreads = 1`). + +Default configurations for `L1GTAlgoBoardWriter` and `L1GTObjectBoardWriter` in input and output direction can be pulled into the configuration for each of the two prototype implementations VU9P and VU13P via: + +```python +# Serenity VU9P prototype board +process.load('L1Trigger.Phase2L1GT.l1tGTBoardWriterVU9P_cff') + +process.pBoardDataInputVU9P = cms.EndPath(process.BoardDataInputVU9P) +process.pBoardDataOutputObjectsVU9P = cms.EndPath(process.BoardDataOutputObjectsVU9P) +process.pAlgoBitBoardDataVU9P = cms.EndPath(process.AlgoBitBoardDataVU9P) +``` + +```python +# Serenity VU13P prototype board +process.load('L1Trigger.Phase2L1GT.l1tGTBoardWriterVU13P_cff') + +process.pBoardDataInputVU13P = cms.EndPath(process.BoardDataInputVU13P) +process.pBoardDataOutputObjectsVU13P = cms.EndPath(process.BoardDataOutputObjectsVU13P) +process.pAlgoBitBoardDataVU13P = cms.EndPath(process.AlgoBitBoardDataVU13P) +``` diff --git a/L1Trigger/Phase2L1GT/plugins/L1GTAlgoBoardWriter.cc b/L1Trigger/Phase2L1GT/plugins/L1GTAlgoBoardWriter.cc index f07ba977bc093..565d460398fd9 100644 --- a/L1Trigger/Phase2L1GT/plugins/L1GTAlgoBoardWriter.cc +++ b/L1Trigger/Phase2L1GT/plugins/L1GTAlgoBoardWriter.cc @@ -73,8 +73,8 @@ L1GTAlgoBoardWriter::L1GTAlgoBoardWriter(const edm::ParameterSet& config) algoBlocksToken_(consumes(config.getUntrackedParameter("algoBlocksTag"))), boardDataWriter_( l1t::demo::parseFileFormat(config.getUntrackedParameter("patternFormat")), - config.getUntrackedParameter("outputFilename"), - config.getUntrackedParameter("outputFileExtension"), + config.getUntrackedParameter("filename"), + config.getUntrackedParameter("fileExtension"), 9, 2, config.getUntrackedParameter("maxFrames"), @@ -133,8 +133,8 @@ void L1GTAlgoBoardWriter::endJob() { void L1GTAlgoBoardWriter::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { edm::ParameterSetDescription desc; - desc.addUntracked("outputFilename"); - desc.addUntracked("outputFileExtension", "txt"); + desc.addUntracked("filename"); + desc.addUntracked("fileExtension", "txt"); desc.addUntracked("algoBlocksTag"); desc.addUntracked("maxEvents", 0); desc.addUntracked>("channels"); diff --git a/L1Trigger/Phase2L1GT/plugins/L1GTFinOrBoardWriter.cc b/L1Trigger/Phase2L1GT/plugins/L1GTFinOrBoardWriter.cc index 2763fcc4c072f..14f76a2cb0ac9 100644 --- a/L1Trigger/Phase2L1GT/plugins/L1GTFinOrBoardWriter.cc +++ b/L1Trigger/Phase2L1GT/plugins/L1GTFinOrBoardWriter.cc @@ -39,6 +39,8 @@ class L1GTFinOrBoardWriter : public edm::one::EDAnalyzer<> { void analyze(const edm::Event&, const edm::EventSetup&) override; void endJob() override; + unsigned int eventCounter_; + const unsigned int maxEvents_; const std::array channelsLow_; const std::array channelsMid_; const std::array channelsHigh_; @@ -63,7 +65,9 @@ static std::array convert(std::vector vec, const char* name) { } L1GTFinOrBoardWriter::L1GTFinOrBoardWriter(const edm::ParameterSet& config) - : channelsLow_(convert(config.getUntrackedParameter>("channelsLow"), + : eventCounter_(0), + maxEvents_(config.getUntrackedParameter("maxEvents")), + channelsLow_(convert(config.getUntrackedParameter>("channelsLow"), "channelsLow")), channelsMid_(convert(config.getUntrackedParameter>("channelsMid"), "channelsMid")), @@ -72,8 +76,8 @@ L1GTFinOrBoardWriter::L1GTFinOrBoardWriter(const edm::ParameterSet& config) channelFinOr_(config.getUntrackedParameter("channelFinOr")), algoBlocksToken_(consumes(config.getUntrackedParameter("algoBlocksTag"))), boardDataWriter_(l1t::demo::parseFileFormat(config.getUntrackedParameter("patternFormat")), - config.getUntrackedParameter("outputFilename"), - config.getUntrackedParameter("outputFileExtension"), + config.getUntrackedParameter("filename"), + config.getUntrackedParameter("fileExtension"), 9, 2, config.getUntrackedParameter("maxFrames"), @@ -186,6 +190,13 @@ void L1GTFinOrBoardWriter::analyze(const edm::Event& event, const edm::EventSetu } tmuxCounter_ = (tmuxCounter_ + 1) % 2; + + eventCounter_++; + + if (maxEvents_ != 0 && eventCounter_ == maxEvents_) { + boardDataWriter_.flush(); + eventCounter_ = 0; + } } void L1GTFinOrBoardWriter::endJob() { @@ -198,14 +209,15 @@ void L1GTFinOrBoardWriter::endJob() { void L1GTFinOrBoardWriter::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { edm::ParameterSetDescription desc; - desc.addUntracked("outputFilename"); - desc.addUntracked("outputFileExtension", "txt"); + desc.addUntracked("filename"); + desc.addUntracked("fileExtension", "txt"); desc.addUntracked("algoBlocksTag"); desc.addUntracked>("channelsLow"); desc.addUntracked>("channelsMid"); desc.addUntracked>("channelsHigh"); desc.addUntracked("channelFinOr"); desc.addUntracked("maxFrames", 1024); + desc.addUntracked("maxEvents", 0); desc.addUntracked("patternFormat", "EMPv2"); descriptions.addDefault(desc); diff --git a/L1Trigger/Phase2L1GT/plugins/L1GTObjectBoardWriter.cc b/L1Trigger/Phase2L1GT/plugins/L1GTObjectBoardWriter.cc index d283816bb02a9..6059c3b474f62 100644 --- a/L1Trigger/Phase2L1GT/plugins/L1GTObjectBoardWriter.cc +++ b/L1Trigger/Phase2L1GT/plugins/L1GTObjectBoardWriter.cc @@ -61,7 +61,7 @@ class L1GTObjectBoardWriter : public edm::one::EDAnalyzer<> { const BufferType bufferFileType_; unsigned int eventCounter_; unsigned int maxEvents_; - std::unordered_map numChannels; + std::unordered_map numChannels_; demo::BoardDataWriter boardDataWriter_; // From upstream @@ -122,7 +122,7 @@ L1GTObjectBoardWriter::L1GTObjectBoardWriter(const edm::ParameterSet& config) : bufferFileType_(config.getUntrackedParameter("bufferFileType") == "input" ? INPUT : OUTPUT), eventCounter_(0), maxEvents_(config.getUntrackedParameter("maxEvents")), - numChannels(), + numChannels_(), boardDataWriter_( demo::parseFileFormat(config.getUntrackedParameter("patternFormat")), config.getUntrackedParameter("filename"), @@ -181,7 +181,7 @@ L1GTObjectBoardWriter::L1GTObjectBoardWriter(const edm::ParameterSet& config) for (std::size_t i = 0; i < channels.size(); i++) { channelMap.insert({{name, i}, {{1, 0}, {channels.at(i)}}}); } - numChannels.insert({name, channels.size()}); + numChannels_.insert({name, channels.size()}); } return channelMap; } @@ -284,7 +284,12 @@ static std::vector> packCollection(const std::vector& collection) } else if constexpr (std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v) { while (packed.size() < 18) { - packed.emplace_back(0); + if (next_packed) { + packed.emplace_back(next_packed.value()); + next_packed.reset(); + } else { + packed.emplace_back(0); + } } } else if constexpr (std::is_same_v || std::is_same_v) { while (packed.size() < 12) { @@ -385,8 +390,8 @@ void L1GTObjectBoardWriter::analyze(const edm::Event& event, const edm::EventSet data = packCollection(cl2HtSum); } - for (std::size_t i = 0; i < numChannels.at(name); i++) { - for (std::size_t j = 0; j < data.size(); j += numChannels.at(name)) { + for (std::size_t i = 0; i < numChannels_.at(name); i++) { + for (std::size_t j = i; j < data.size(); j += numChannels_.at(name)) { eventData[{name, i}].push_back(data[j]); } diff --git a/L1Trigger/Phase2L1GT/python/l1tGTBoardWriterVU13P_cff.py b/L1Trigger/Phase2L1GT/python/l1tGTBoardWriterVU13P_cff.py index 3e6686620c2a9..c1edfc6684536 100644 --- a/L1Trigger/Phase2L1GT/python/l1tGTBoardWriterVU13P_cff.py +++ b/L1Trigger/Phase2L1GT/python/l1tGTBoardWriterVU13P_cff.py @@ -1,8 +1,9 @@ import FWCore.ParameterSet.Config as cms -from L1Trigger.Phase2L1GT.l1tGTBoardWriter_cff import BoardDataInput, BoardDataOutputObjects, AlgoBitBoardData +from L1Trigger.Phase2L1GT.l1tGTBoardWriter_cff import BoardDataInput as BoardDataInputVU13P +from L1Trigger.Phase2L1GT.l1tGTBoardWriter_cff import BoardDataOutputObjects as BoardDataOutputObjectsVU13P +from L1Trigger.Phase2L1GT.l1tGTBoardWriter_cff import AlgoBitBoardData as AlgoBitBoardDataVU13P - -BoardDataInput.InputChannels = cms.untracked.PSet( +BoardDataInputVU13P.InputChannels = cms.untracked.PSet( # SLR 0 GTT_1 = cms.untracked.vuint32(range(0, 6)), GTT_2 = cms.untracked.vuint32(range(6, 12)), @@ -21,7 +22,7 @@ GMT_1 = cms.untracked.vuint32(48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 68, 69, 70, 71, 72, 73) ) -BoardDataOutputObjects.OutputChannels = cms.untracked.PSet( +BoardDataOutputObjectsVU13P.OutputChannels = cms.untracked.PSet( GTTPromptJets = cms.untracked.vuint32(range(2, 6)), GTTDisplacedJets = cms.untracked.vuint32(range(6, 10)), GTTPromptHtSum = cms.untracked.vuint32(range(10, 11)), @@ -51,4 +52,4 @@ GTTPrimaryVert = cms.untracked.vuint32(range(121, 123)) ) -AlgoBitBoardData.channels = cms.untracked.vuint32(46, 47) +AlgoBitBoardDataVU13P.channels = cms.untracked.vuint32(46, 47) diff --git a/L1Trigger/Phase2L1GT/python/l1tGTBoardWriterVU9P_cff.py b/L1Trigger/Phase2L1GT/python/l1tGTBoardWriterVU9P_cff.py index dccf1fea96995..d1c75e5725838 100644 --- a/L1Trigger/Phase2L1GT/python/l1tGTBoardWriterVU9P_cff.py +++ b/L1Trigger/Phase2L1GT/python/l1tGTBoardWriterVU9P_cff.py @@ -1,8 +1,10 @@ import FWCore.ParameterSet.Config as cms -from L1Trigger.Phase2L1GT.l1tGTBoardWriter_cff import BoardDataInput, BoardDataOutputObjects, AlgoBitBoardData +from L1Trigger.Phase2L1GT.l1tGTBoardWriter_cff import BoardDataInput as BoardDataInputVU9P +from L1Trigger.Phase2L1GT.l1tGTBoardWriter_cff import BoardDataOutputObjects as BoardDataOutputObjectsVU9P +from L1Trigger.Phase2L1GT.l1tGTBoardWriter_cff import AlgoBitBoardData as AlgoBitBoardDataVU9P -BoardDataInput.InputChannels = cms.untracked.PSet( +BoardDataInputVU9P.InputChannels = cms.untracked.PSet( # SLR 0 GTT_1 = cms.untracked.vuint32(range(0, 6)), GTT_2 = cms.untracked.vuint32(range(6, 12)), @@ -19,7 +21,7 @@ GMT_1 = cms.untracked.vuint32(range(60, 78)) ) -BoardDataOutputObjects.OutputChannels = cms.untracked.PSet( +BoardDataOutputObjectsVU9P.OutputChannels = cms.untracked.PSet( GTTPromptJets = cms.untracked.vuint32(range(2, 6)), GTTDisplacedJets = cms.untracked.vuint32(range(6, 10)), GTTPromptHtSum = cms.untracked.vuint32(range(10, 11)), @@ -49,4 +51,4 @@ GTTPrimaryVert = cms.untracked.vuint32(range(113, 115)) ) -AlgoBitBoardData.channels = cms.untracked.vuint32(32, 33) +AlgoBitBoardDataVU9P.channels = cms.untracked.vuint32(32, 33) diff --git a/L1Trigger/Phase2L1GT/python/l1tGTBoardWriter_cff.py b/L1Trigger/Phase2L1GT/python/l1tGTBoardWriter_cff.py index e2fe2b6b43eee..993ae5b879a11 100644 --- a/L1Trigger/Phase2L1GT/python/l1tGTBoardWriter_cff.py +++ b/L1Trigger/Phase2L1GT/python/l1tGTBoardWriter_cff.py @@ -44,6 +44,6 @@ ) AlgoBitBoardData = cms.EDAnalyzer("L1GTAlgoBoardWriter", - outputFilename = cms.untracked.string("algoBitPattern"), + filename = cms.untracked.string("algoBitPattern"), algoBlocksTag = cms.untracked.InputTag("l1tGTAlgoBlockProducer"), ) diff --git a/L1Trigger/Phase2L1GT/test/gt_firmware_evaluation.py b/L1Trigger/Phase2L1GT/test/gt_firmware_evaluation.py index c154e5949bcfe..f37d67bcdefe9 100644 --- a/L1Trigger/Phase2L1GT/test/gt_firmware_evaluation.py +++ b/L1Trigger/Phase2L1GT/test/gt_firmware_evaluation.py @@ -812,14 +812,14 @@ process.BoardData = cms.EDAnalyzer("L1GTAlgoBoardWriter", - outputFilename = cms.untracked.string("outputPattern"), + filename = cms.untracked.string("outputPattern"), algoBlocksTag = cms.untracked.InputTag("l1tGTAlgoBlockProducer"), maxFrames = cms.untracked.uint32(1024), channels = channels ) process.FinOrBoardData = cms.EDAnalyzer("L1GTFinOrBoardWriter", - outputFilename = cms.untracked.string("outputFinOrPattern"), + filename = cms.untracked.string("outputFinOrPattern"), algoBlocksTag = cms.untracked.InputTag("l1tGTAlgoBlockProducer"), maxFrames = cms.untracked.uint32(1024), channelsLow = cms.untracked.vuint32(4, 5, 6), diff --git a/L1Trigger/Phase2L1GT/test/test_GT.py b/L1Trigger/Phase2L1GT/test/test_GT.py index 1866add7a7e7a..85b402c536a1b 100644 --- a/L1Trigger/Phase2L1GT/test/test_GT.py +++ b/L1Trigger/Phase2L1GT/test/test_GT.py @@ -120,13 +120,13 @@ process.load('L1Trigger.Phase2L1GT.l1tGTBoardWriterVU13P_cff') -process.pBoardDataInput = cms.EndPath(process.BoardDataInput) -process.pBoardDataOutputObjects = cms.EndPath(process.BoardDataOutputObjects) +process.pBoardDataInputVU13P = cms.EndPath(process.BoardDataInputVU13P) +process.pBoardDataOutputObjectsVU13P = cms.EndPath(process.BoardDataOutputObjectsVU13P) # Schedule definition process.schedule = cms.Schedule(process.raw2digi_step,process.L1simulation_step,process.GTemulation_step, *collectAlgorithmPaths(process), process.pGToutput, - process.pBoardDataInput, process.pBoardDataOutputObjects, process.endjob_step) + process.pBoardDataInputVU13P, process.pBoardDataOutputObjectsVU13P, process.endjob_step) from PhysicsTools.PatAlgos.tools.helpers import associatePatAlgosToolsTask associatePatAlgosToolsTask(process)