From 3716d1868b00d0a55a78e78967c3a0e6bedba22b Mon Sep 17 00:00:00 2001 From: Marino Missiroli Date: Sat, 7 Mar 2026 17:49:04 +0100 Subject: [PATCH 1/3] L1S(Nano): fix in SimpleOrbitFlatTableProducer for skipNonExistingSrc=True This changes the initialisation of the vector "selbxOffsets", which is used in case the parameter "skipNonExistingSrc" is set to True. Without this change, that vector is empty, and this leads to a segmentation fault at https://github.com/cms-sw/cmssw/blob/edd2f62bfb3fe43fdc5609ce38b82169e80251fb/DataFormats/NanoAOD/interface/OrbitFlatTable.h#L27 --- .../Utilities/plugins/SimpleOrbitFlatTableProducer.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/L1TriggerScouting/Utilities/plugins/SimpleOrbitFlatTableProducer.cc b/L1TriggerScouting/Utilities/plugins/SimpleOrbitFlatTableProducer.cc index d7096bdb6e6cd..cf69b1c53cdd3 100644 --- a/L1TriggerScouting/Utilities/plugins/SimpleOrbitFlatTableProducer.cc +++ b/L1TriggerScouting/Utilities/plugins/SimpleOrbitFlatTableProducer.cc @@ -188,7 +188,7 @@ class SimpleOrbitFlatTableProducer : public edm::stream::EDProducer<> { std::vector selobjs; std::vector> selptrs; // for external variables - std::vector selbxOffsets; + std::vector selbxOffsets(l1ScoutingRun3::OrbitFlatTable::NBX + 2, 0); if (src.isValid() || !skipNonExistingSrc_) { if (singleton_) { From 10178d8f9516c3b2af1571980599660b3dc3ab8a Mon Sep 17 00:00:00 2001 From: Marino Missiroli Date: Sat, 7 Mar 2026 17:54:31 +0100 Subject: [PATCH 2/3] L1S(Nano): updates for CaloTowers in Run3_2026 era Updates to add CaloTowers' information to the output of "L1ScoutingNano" for 2026 workflows. This is done by adding a modifier named "run3_l1scouting_2026", and including it in the Era "Run3_2026". Various updates are made to custom_l1scoutingrun3_cff, mainly - using a dedicated Sequence (rather than overriding the regular NANO sequence), and - making the customisation of the relevant output module(s) more robust (covering both the NANOEDMAOD and NANOAOD data tiers, and not relying solely on the label of the output module). Co-Authored-By: Rocco Ardino --- .../Eras/python/Era_Run3_2026_cff.py | 4 +- .../Modifier_run3_l1scouting_2026_cff.py | 3 + ...outingCaloTowerPhysicalValueMapProducer.cc | 89 +++++++++ .../plugins/SimpleOrbitFlatTableProducer.cc | 4 + PhysicsTools/NanoAOD/python/autoNANO.py | 6 +- .../python/custom_l1scoutingrun3_cff.py | 189 +++++++++++------- .../NanoAOD/python/l1scoutingrun3_cff.py | 33 ++- 7 files changed, 254 insertions(+), 74 deletions(-) create mode 100644 Configuration/Eras/python/Modifier_run3_l1scouting_2026_cff.py create mode 100644 L1TriggerScouting/Utilities/plugins/L1ScoutingCaloTowerPhysicalValueMapProducer.cc diff --git a/Configuration/Eras/python/Era_Run3_2026_cff.py b/Configuration/Eras/python/Era_Run3_2026_cff.py index 571f93382441d..58bfe2b0460b9 100644 --- a/Configuration/Eras/python/Era_Run3_2026_cff.py +++ b/Configuration/Eras/python/Era_Run3_2026_cff.py @@ -2,4 +2,6 @@ from Configuration.Eras.Era_Run3_2025_cff import Run3_2025 -Run3_2026 = cms.ModifierChain(Run3_2025) +from Configuration.Eras.Modifier_run3_l1scouting_2026_cff import run3_l1scouting_2026 + +Run3_2026 = cms.ModifierChain(Run3_2025, run3_l1scouting_2026) diff --git a/Configuration/Eras/python/Modifier_run3_l1scouting_2026_cff.py b/Configuration/Eras/python/Modifier_run3_l1scouting_2026_cff.py new file mode 100644 index 0000000000000..c32e54c03d61c --- /dev/null +++ b/Configuration/Eras/python/Modifier_run3_l1scouting_2026_cff.py @@ -0,0 +1,3 @@ +import FWCore.ParameterSet.Config as cms + +run3_l1scouting_2026 = cms.Modifier() diff --git a/L1TriggerScouting/Utilities/plugins/L1ScoutingCaloTowerPhysicalValueMapProducer.cc b/L1TriggerScouting/Utilities/plugins/L1ScoutingCaloTowerPhysicalValueMapProducer.cc new file mode 100644 index 0000000000000..0efd084eb0cf0 --- /dev/null +++ b/L1TriggerScouting/Utilities/plugins/L1ScoutingCaloTowerPhysicalValueMapProducer.cc @@ -0,0 +1,89 @@ +#include +#include +#include +#include + +#include "DataFormats/Common/interface/ValueMap.h" +#include "DataFormats/L1Scouting/interface/OrbitCollection.h" +#include "DataFormats/L1Scouting/interface/L1ScoutingCaloTower.h" +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "L1TriggerScouting/Utilities/interface/conversion.h" + +class L1ScoutingCaloTowerPhysicalValueMapProducer : public edm::global::EDProducer<> { +public: + L1ScoutingCaloTowerPhysicalValueMapProducer(edm::ParameterSet const&); + ~L1ScoutingCaloTowerPhysicalValueMapProducer() override = default; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + void produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const override; + + void putValueMap(edm::Event&, + edm::Handle const&, + std::vector const&, + std::string const&) const; + + edm::EDGetTokenT const src_; +}; + +L1ScoutingCaloTowerPhysicalValueMapProducer::L1ScoutingCaloTowerPhysicalValueMapProducer(edm::ParameterSet const& params) + : src_(consumes(params.getParameter("src"))) { + produces>("fEt"); + produces>("fEta"); + produces>("fPhi"); +} + +void L1ScoutingCaloTowerPhysicalValueMapProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("src"); + descriptions.addWithDefaultLabel(desc); +} + +void L1ScoutingCaloTowerPhysicalValueMapProducer::produce(edm::StreamID, + edm::Event& iEvent, + edm::EventSetup const&) const { + auto const src_h = iEvent.getHandle(src_); + + std::vector outv_fEt{}; + std::vector outv_fEta{}; + std::vector outv_fPhi{}; + + if (src_h.isValid()) { + auto const& src = *src_h; + auto const nobjs = src.size(); + + outv_fEt.reserve(nobjs); + outv_fEta.reserve(nobjs); + outv_fPhi.reserve(nobjs); + + for (auto iobj = 0; iobj < nobjs; ++iobj) { + auto const& obj = src[iobj]; + outv_fEt.emplace_back(l1ScoutingRun3::calol1::fEt(obj.hwEt())); + outv_fEta.emplace_back(l1ScoutingRun3::calol1::fEta(obj.hwEta())); + outv_fPhi.emplace_back(l1ScoutingRun3::calol1::fPhi(obj.hwPhi())); + } + + putValueMap(iEvent, src_h, outv_fEt, "fEt"); + putValueMap(iEvent, src_h, outv_fEta, "fEta"); + putValueMap(iEvent, src_h, outv_fPhi, "fPhi"); + } +} + +void L1ScoutingCaloTowerPhysicalValueMapProducer::putValueMap( + edm::Event& iEvent, + edm::Handle const& handle, + std::vector const& values, + std::string const& label) const { + auto valuemap = std::make_unique>(); + edm::ValueMap::Filler filler(*valuemap); + filler.insert(handle, values.begin(), values.end()); + filler.fill(); + iEvent.put(std::move(valuemap), label); +} + +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(L1ScoutingCaloTowerPhysicalValueMapProducer); diff --git a/L1TriggerScouting/Utilities/plugins/SimpleOrbitFlatTableProducer.cc b/L1TriggerScouting/Utilities/plugins/SimpleOrbitFlatTableProducer.cc index cf69b1c53cdd3..eada7d15527f6 100644 --- a/L1TriggerScouting/Utilities/plugins/SimpleOrbitFlatTableProducer.cc +++ b/L1TriggerScouting/Utilities/plugins/SimpleOrbitFlatTableProducer.cc @@ -297,9 +297,13 @@ typedef SimpleOrbitFlatTableProducer SimpleL1ScoutingJetOrb #include "DataFormats/L1Scouting/interface/L1ScoutingBMTFStub.h" typedef SimpleOrbitFlatTableProducer SimpleL1ScoutingBMTFStubOrbitFlatTableProducer; +#include "DataFormats/L1Scouting/interface/L1ScoutingCaloTower.h" +typedef SimpleOrbitFlatTableProducer SimpleL1ScoutingCaloTowerOrbitFlatTableProducer; + #include "FWCore/Framework/interface/MakerMacros.h" DEFINE_FWK_MODULE(SimpleL1ScoutingMuonOrbitFlatTableProducer); DEFINE_FWK_MODULE(SimpleL1ScoutingEGammaOrbitFlatTableProducer); DEFINE_FWK_MODULE(SimpleL1ScoutingTauOrbitFlatTableProducer); DEFINE_FWK_MODULE(SimpleL1ScoutingJetOrbitFlatTableProducer); DEFINE_FWK_MODULE(SimpleL1ScoutingBMTFStubOrbitFlatTableProducer); +DEFINE_FWK_MODULE(SimpleL1ScoutingCaloTowerOrbitFlatTableProducer); diff --git a/PhysicsTools/NanoAOD/python/autoNANO.py b/PhysicsTools/NanoAOD/python/autoNANO.py index 04d3ec7ad2c69..59525ca0791c2 100644 --- a/PhysicsTools/NanoAOD/python/autoNANO.py +++ b/PhysicsTools/NanoAOD/python/autoNANO.py @@ -39,10 +39,10 @@ def expandNanoMapping(seqList, mapping, key): 'ScoutFromMini' : {'sequence': '@Scout', 'customize': '@Scout+PhysicsTools/NanoAOD/custom_run3scouting_cff.customiseScoutingNanoFromMini'}, # L1Scouting nano - 'L1Scout': {'sequence': 'PhysicsTools/NanoAOD/custom_l1scoutingrun3_cff', + 'L1Scout': {'sequence': 'PhysicsTools/NanoAOD/custom_l1scoutingrun3_cff.l1scoutingNanoSequence', 'customize': 'PhysicsTools/NanoAOD/custom_l1scoutingrun3_cff.customiseL1ScoutingNanoAOD'}, - 'L1ScoutSelect': {'sequence': '@L1Scout', - 'customize': '@L1Scout+PhysicsTools/NanoAOD/custom_l1scoutingrun3_cff.customiseL1ScoutingNanoAODSelection'}, + 'L1ScoutSelect': {'sequence': 'PhysicsTools/NanoAOD/custom_l1scoutingrun3_cff.l1scoutingNanoSequence', + 'customize': 'PhysicsTools/NanoAOD/custom_l1scoutingrun3_cff.customiseL1ScoutingNanoAODSelection'}, # BPH nano 'BPH' : {'sequence': '@PHYS', 'customize': '@PHYS+PhysicsTools/NanoAOD/custom_bph_cff.nanoAOD_customizeBPH'}, diff --git a/PhysicsTools/NanoAOD/python/custom_l1scoutingrun3_cff.py b/PhysicsTools/NanoAOD/python/custom_l1scoutingrun3_cff.py index 3a2f938124b7c..5dea8b253634f 100644 --- a/PhysicsTools/NanoAOD/python/custom_l1scoutingrun3_cff.py +++ b/PhysicsTools/NanoAOD/python/custom_l1scoutingrun3_cff.py @@ -1,13 +1,10 @@ import FWCore.ParameterSet.Config as cms + from PhysicsTools.NanoAOD.l1scoutingrun3_cff import * -######################### -# Default Configuration # -######################### +from Configuration.Eras.Modifier_run3_l1scouting_2026_cff import run3_l1scouting_2026 -# since L1ScoutingNano should be run standalone only, -# this replace task and sequences in standard NanoAOD -nanoTableTaskCommon = cms.Task( +l1scoutingNanoTask = cms.Task( l1scoutingMuonPhysicalValueMap, l1scoutingEGammaPhysicalValueMap, l1scoutingTauPhysicalValueMap, @@ -20,91 +17,133 @@ l1scoutingBMTFStubTable, ) -nanoSequenceCommon = cms.Sequence(l1scoutingJetPhysicalValueMap + cms.Sequence(nanoTableTaskCommon)) - -nanoSequence = cms.Sequence(nanoSequenceCommon) - -nanoSequenceMC = cms.Sequence(nanoSequenceCommon) +_l1scoutingNanoTask = l1scoutingNanoTask.copy() +_l1scoutingNanoTask.add(l1scoutingCaloTowerPhysicalValueMap) +_l1scoutingNanoTask.add(l1scoutingCaloTowerTable) +run3_l1scouting_2026.toReplaceWith(l1scoutingNanoTask, _l1scoutingNanoTask) + +l1scoutingNanoSequence = cms.Sequence(l1scoutingNanoTask) + +def _getNanoPoolOutputModuleLabels(process): + """This method is meant to catch the instances of PoolOutputModule used for NanoAOD EDM products. + - At present, these instances are identified by requiring the "dataset.dataTier" parameter (string) + of the output module to contain the word "NANO" (this requirement is not case-sensitive). + """ + ret = [] + for outModLabel, outMod in process.outputModules_().items(): + if outMod.type_() != "PoolOutputModule": + continue + try: + if "nano" in outMod.dataset.dataTier.value().lower(): + ret += [outModLabel] + except: + pass + return ret + +def _getNanoAODOutputModuleLabels(process): + return [outModLabel for outModLabel in process.outputModules_() \ + if process.outputModules_()[outModLabel].type_() == "NanoAODOutputModule"] + +def _getOrbitNanoAODOutputModuleLabels(process): + return [outModLabel for outModLabel in process.outputModules_() \ + if process.outputModules_()[outModLabel].type_() == "OrbitNanoAODOutputModule"] def customiseL1ScoutingNanoAOD(process): - # change OutputModule to OrbitNanoAODOutputModule - if hasattr(process, "NANOAODoutput"): - print("custom_l1scoutingrun3_cff: Change NANOAODoutput to OrbitNanoAODOutputModule") - setattr(process, "NANOAODoutput", - cms.OutputModule("OrbitNanoAODOutputModule", - # copy from standard NanoAOD - compressionAlgorithm = process.NANOAODoutput.compressionAlgorithm, - compressionLevel = process.NANOAODoutput.compressionLevel, - dataset = process.NANOAODoutput.dataset, - fileName = process.NANOAODoutput.fileName, - # change eventcontent - outputCommands = cms.untracked.vstring( - "drop *", - "keep l1ScoutingRun3OrbitFlatTable_*_*_*"), - # additional parameters for l1scouting - SelectEvents = cms.untracked.PSet( - SelectEvents = cms.vstring('nanoAOD_step') # l1scouting runs standalone only - ), - skipEmptyBXs = cms.bool(True), # drop empty bxs - ) - ) + """Customisation to run on the "L1Scouting" primary dataset + """ + # NANO: convert instances of NanoAODOutputModule to instances of OrbitNanoAODOutputModule + nanoAODOutputModuleLabels = _getNanoAODOutputModuleLabels(process) + for outModLabel in nanoAODOutputModuleLabels: + outMod = getattr(process, outModLabel) + setattr(process, outModLabel, cms.OutputModule("OrbitNanoAODOutputModule", + **outMod.parameters_(), + skipEmptyBXs = cms.bool(True), # drop empty BXs + selectedBx = cms.InputTag("") # not used if the InputTag's label is empty + )) + + # NANO and NANOEDM: customise the event content + nanoPoolOutputModuleLabels = _getNanoPoolOutputModuleLabels(process) + for outModLabel in (nanoAODOutputModuleLabels + nanoPoolOutputModuleLabels): + outMod = getattr(process, outModLabel) + outMod.outputCommands = [ + "drop *", + "keep l1ScoutingRun3OrbitFlatTable_*_*_*", + ] return process -################# -# Customisation # -################# -# these function are designed to be used with --customise flag in cmsDriver.py -# e.g. --customise PhysicsTools/NanoAOD/python/custom_l1scoutingrun3_cff.dropStub - -# configure to run with L1ScoutingSelection dataset -# should be used with default customiseL1ScoutingNanoAOD def customiseL1ScoutingNanoAODSelection(process): - # change sources - process.l1scoutingMuonPhysicalValueMap.src = cms.InputTag("FinalBxSelectorMuon", "Muon") - process.l1scoutingEGammaPhysicalValueMap.src = cms.InputTag("FinalBxSelectorEGamma", "EGamma") - process.l1scoutingJetPhysicalValueMap.src = cms.InputTag("FinalBxSelectorJet", "Jet") - - process.l1scoutingMuonTable.src = cms.InputTag("FinalBxSelectorMuon", "Muon") - process.l1scoutingEGammaTable.src = cms.InputTag("FinalBxSelectorEGamma", "EGamma") - process.l1scoutingJetTable.src = cms.InputTag("FinalBxSelectorJet", "Jet") - process.l1scoutingEtSumTable.src = cms.InputTag("FinalBxSelectorBxSums", "EtSum") - process.l1scoutingBMTFStubTable.src = cms.InputTag("FinalBxSelectorBMTFStub", "BMTFStub") + """Customisation to run on the "L1ScoutingSelection" primary dataset + """ + process = customiseL1ScoutingNanoAOD(process) + + # change input collections from the L1SCOUT data tier + process.l1scoutingMuonPhysicalValueMap.src = "FinalBxSelectorMuon:Muon" + process.l1scoutingEGammaPhysicalValueMap.src = "FinalBxSelectorEGamma:EGamma" + process.l1scoutingJetPhysicalValueMap.src = "FinalBxSelectorJet:Jet" + process.l1scoutingCaloTowerPhysicalValueMap.src = "FinalBxSelectorCaloTower:CaloTower" + + process.l1scoutingMuonTable.src = "FinalBxSelectorMuon:Muon" + process.l1scoutingEGammaTable.src = "FinalBxSelectorEGamma:EGamma" + process.l1scoutingJetTable.src = "FinalBxSelectorJet:Jet" + process.l1scoutingEtSumTable.src = "FinalBxSelectorBxSums:EtSum" + process.l1scoutingBMTFStubTable.src = "FinalBxSelectorBMTFStub:BMTFStub" + process.l1scoutingCaloTowerTable.src = "FinalBxSelectorCaloTower:CaloTower" # drop L1Tau - process.nanoTableTaskCommon.remove(process.l1scoutingTauTable) + process.l1scoutingNanoTask.remove(process.l1scoutingTauTable) + + # NANO: customise instances of OrbitNanoAODOutputModule + for outModLabel in _getOrbitNanoAODOutputModuleLabels(process): + outMod = getattr(process, outModLabel) + outMod.outputCommands += ["keep uints_*_SelBx_*"] # keep SelBx + outMod.selectedBx = "FinalBxSelector:SelBx" # use to select products - # change parameters in OrbitNanoAODOutputModule - process.NANOAODoutput.outputCommands += ["keep uints_*_SelBx_*"] # keep SelBx - process.NANOAODoutput.selectedBx = cms.InputTag("FinalBxSelector", "SelBx") # use to select products + # NANOEDM: modify outputCommands of PoolOutputModule instances + for outModLabel in _getNanoPoolOutputModuleLabels(process): + outMod = getattr(process, outModLabel) + outMod.outputCommands += ["keep uints_*_SelBx_*"] # keep SelBx return process +### +### Additional customisations +### +### - These functions are designed to be used with the --customise flag of cmsDriver.py, +### e.g. "--customise PhysicsTools/NanoAOD/custom_l1scoutingrun3_cff.addHardwareValues". +### def addHardwareValues(process): - # add hardware values to variables + """Customisation to add the hardware values of L1-Scouting objects to the NanoAOD output tables + """ process.l1scoutingMuonTable.variables = cms.PSet( - process.l1scoutingMuonTable.variables, - l1scoutingMuonUnconvertedVariables + process.l1scoutingMuonTable.variables, + l1scoutingMuonUnconvertedVariables ) process.l1scoutingEGammaTable.variables = cms.PSet( - process.l1scoutingEGammaTable.variables, - l1scoutingCaloObjectUnconvertedVariables + process.l1scoutingEGammaTable.variables, + l1scoutingCaloObjectUnconvertedVariables ) process.l1scoutingTauTable.variables = cms.PSet( - process.l1scoutingTauTable.variables, - l1scoutingCaloObjectUnconvertedVariables + process.l1scoutingTauTable.variables, + l1scoutingCaloObjectUnconvertedVariables ) process.l1scoutingJetTable.variables = cms.PSet( - process.l1scoutingJetTable.variables, - l1scoutingCaloObjectUnconvertedVariables + process.l1scoutingJetTable.variables, + l1scoutingCaloObjectUnconvertedVariables + ) + process.l1scoutingCaloTowerTable.variables = cms.PSet( + process.l1scoutingCaloTowerTable.variables, + l1scoutingCaloTowerUnconvertedVariables ) # EtSum uses dedicated EDProducer and can add hardware values by setting a boolean - process.l1scoutingEtSumTable.writeHardwareValues = cms.bool(True) + process.l1scoutingEtSumTable.writeHardwareValues = True return process def keepHardwareValuesOnly(process): + """Customisation to keep ONLY the hardware values of L1-Scouting objects in the NanoAOD output tables + """ # first, add hardware values process = addHardwareValues(process) @@ -114,24 +153,36 @@ def keepHardwareValuesOnly(process): process.l1scoutingEGammaTable.externalVariables = cms.PSet() process.l1scoutingTauTable.externalVariables = cms.PSet() process.l1scoutingJetTable.externalVariables = cms.PSet() + process.l1scoutingCaloTowerTable.externalVariables = cms.PSet() # EtSum uses dedicated EDProducer and can remove physical values by setting a boolean - process.l1scoutingEtSumTable.writePhysicalValues = cms.bool(False) + process.l1scoutingEtSumTable.writePhysicalValues = False return process def outputMultipleEtSums(process): - process.l1scoutingEtSumTable.singleton = cms.bool(False) + """Customisation to output multiple L1-Scouting EtSums in the relevant NanoAOD table + (l1scoutingEtSumTable.singleton = False) + """ + process.l1scoutingEtSumTable.singleton = False return process def dropEmptyBXs(process): - process.NANOAODoutput.skipEmptyBXs = cms.bool(True) + """Customisation to set "skipEmptyBXs = True" in all the instances of OrbitNanoAODOutputModule + """ + for outModLabel in _getOrbitNanoAODOutputModuleLabels(process): + getattr(process, outModLabel).skipEmptyBXs = True return process def keepEmptyBXs(process): - process.NANOAODoutput.skipEmptyBXs = cms.bool(False) + """Customisation to set "skipEmptyBXs = False" in all the instances of OrbitNanoAODOutputModule + """ + for outModLabel in _getOrbitNanoAODOutputModuleLabels(process): + getattr(process, outModLabel).skipEmptyBXs = False return process def dropBMTFStub(process): - process.nanoTableTaskCommon.remove(process.l1scoutingBMTFStubTable) + """Customisation to remove the NanoAOD output table for the L1-Scouting BMTF stubs + """ + process.l1scoutingNanoTask.remove(process.l1scoutingBMTFStubTable) return process diff --git a/PhysicsTools/NanoAOD/python/l1scoutingrun3_cff.py b/PhysicsTools/NanoAOD/python/l1scoutingrun3_cff.py index 22d87c6a6ad87..5c51f54382bc0 100644 --- a/PhysicsTools/NanoAOD/python/l1scoutingrun3_cff.py +++ b/PhysicsTools/NanoAOD/python/l1scoutingrun3_cff.py @@ -1,4 +1,5 @@ import FWCore.ParameterSet.Config as cms + from PhysicsTools.NanoAOD.common_cff import * ############################## @@ -13,7 +14,7 @@ hwPt = Var("hwPt()", "int", doc="hardware pt"), hwEta = Var("hwEta()", "int", doc="hardware eta"), hwPhi = Var("hwPhi()", "int", doc="hardware phi"), - hwPtUnconstrained = Var("hwPtUnconstrained", "int", doc="harware unconstrained pt"), + hwPtUnconstrained = Var("hwPtUnconstrained", "int", doc="hardware unconstrained pt"), hwEtaAtVtx = Var("hwEtaAtVtx()", "int", doc="hardware eta extrapolated at beam line"), hwPhiAtVtx = Var("hwPhiAtVtx()", "int", doc="hardware phi extrapolated at beam line"), ) @@ -25,6 +26,13 @@ hwPhi = Var("hwPhi()", "int", doc="hardware phi"), ) +# CaloTowers +l1scoutingCaloTowerUnconvertedVariables = cms.PSet( + hwEt = Var("hwEt()", "int16", doc="hardware Et"), + hwEta = Var("hwEta()", "int16", doc="hardware eta"), + hwPhi = Var("hwPhi()", "int16", doc="hardware phi"), +) + ################################################# # Physical Value Conversion from Hardware Value # ################################################# @@ -66,6 +74,11 @@ conversions = l1scoutingCaloObjectConversions ) +# Physical values (Et, Eta, Phi) for CaloTowers (Calo Layer-1) +l1scoutingCaloTowerPhysicalValueMap = cms.EDProducer("L1ScoutingCaloTowerPhysicalValueMapProducer", + src = cms.InputTag("l1ScCaloTowerUnpacker", "CaloTower") +) + #################### # Table Definition # #################### @@ -182,3 +195,21 @@ tag = Var("tag()", "int16", doc="tag (raw L1T units)"), ), ) + +# CaloTowers +l1scoutingCaloTowerTable = cms.EDProducer("SimpleL1ScoutingCaloTowerOrbitFlatTableProducer", + src = cms.InputTag("l1ScCaloTowerUnpacker", "CaloTower"), + name = cms.string("L1CaloTower"), + doc = cms.string("CaloTowers from Calo Layer-1"), + singleton = cms.bool(False), + skipNonExistingSrc = cms.bool(False), + variables = cms.PSet( + erBits = Var("erBits()", "int16", doc="hardware energy-ratio bits"), + miscBits = Var("miscBits()", "int16", doc="hardware misc-bits"), + ), + externalVariables = cms.PSet( + pt = ExtVar(cms.InputTag("l1scoutingCaloTowerPhysicalValueMap", "fEt"), "float", doc="pt", precision=10), + eta = ExtVar(cms.InputTag("l1scoutingCaloTowerPhysicalValueMap", "fEta"), "float", doc="eta", precision=10), + phi = ExtVar(cms.InputTag("l1scoutingCaloTowerPhysicalValueMap", "fPhi"), "float", doc="phi", precision=10), + ) +) From 4ed73cadf5d89419facdc2f96d03fce19493464c Mon Sep 17 00:00:00 2001 From: Marino Missiroli Date: Sat, 7 Mar 2026 17:57:49 +0100 Subject: [PATCH 3/3] L1S(Nano): add L1ScoutingNano wfs for 2025 and 2026 This change adds wfs to test on real data the NANOAOD flavours "L1Scout" and "L1ScoutSelect" for the Eras "Run3_2025" and "Run3_2026". --- .../PyReleaseValidation/python/relval_nano.py | 54 ++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/Configuration/PyReleaseValidation/python/relval_nano.py b/Configuration/PyReleaseValidation/python/relval_nano.py index 4a77aa9f11379..3d8f1696cece2 100644 --- a/Configuration/PyReleaseValidation/python/relval_nano.py +++ b/Configuration/PyReleaseValidation/python/relval_nano.py @@ -255,7 +255,7 @@ def next(self, index: int = None) -> None: ################################################################ -# current release cycle workflows : 14.0 +# 14.0 workflows steps['TTbarMINIAOD14.0'] = {'INPUT': InputInfo( location='STD', dataSet='/RelValTTbar_14TeV/CMSSW_14_0_0-PU_140X_mcRun3_2024_realistic_v3_STD_2024_PU-v2/MINIAODSIM')} @@ -431,6 +431,12 @@ def next(self, index: int = None) -> None: steps['ScoutingPFMonitor_Run2025C_MINIAOD_150X'] = {'INPUT': InputInfo( location='STD', ls=lumis_Run2025C, dataSet='/ScoutingPFMonitor/Run2025C-PromptReco-v1/MINIAOD')} +steps['L1Scouting2025RAW15.0'] = {'INPUT': InputInfo(location='STD', ls={398860: [[498, 498]]}, + dataSet='/L1Scouting/Run2025G-v1/L1SCOUT')} + +steps['L1ScoutingSelection2025RAW15.0'] = {'INPUT': InputInfo(location='STD', ls={398860: [[498, 498]]}, + dataSet='/L1ScoutingSelection/Run2025G-v1/L1SCOUT')} + steps['NANO_data15.0'] = merge([{'--era': 'Run3_2025', '--conditions': 'auto:run3_data_prompt'}, _NANO_data]) steps['NANO_data15.0_prompt'] = merge([{'-s': 'NANO:@Prompt,DQM:@nanoAODDQM', '-n': '1000'}, @@ -466,6 +472,29 @@ def next(self, index: int = None) -> None: steps['scoutingNANO_monitorWithPrompt_data15.0'] = merge([{'-s': 'NANO:@Prompt+@ScoutMonitor'}, steps['NANO_data15.0']]) +steps['l1ScoutingNANO_data15.0'] = merge([{'-s': 'NANO:@L1Scout', '-n': '1000'}, + steps['NANO_data15.0']]) + +steps['l1ScoutingSelectionNANO_data15.0'] = merge([{'-s': 'NANO:@L1ScoutSelect', '-n': '1000'}, + steps['NANO_data15.0']]) + +################################################################ +# Run-3, 16_0_X (2026 data-taking) + +steps['L1Scouting2026RAW16.0'] = {'INPUT': InputInfo(location='STD', ls={401733: [[250, 250]]}, + dataSet='/L1Scouting/Run2026A-v1/L1SCOUT')} + +steps['L1ScoutingSelection2026RAW16.0'] = {'INPUT': InputInfo(location='STD', ls={401733: [[250, 250]]}, + dataSet='/L1ScoutingSelection/Run2026A-v1/L1SCOUT')} + +steps['NANO_data16.0'] = merge([{'--era': 'Run3_2026', '--conditions': 'auto:run3_data_prompt'}, _NANO_data]) + +steps['l1ScoutingNANO_data16.0'] = merge([{'-s': 'NANO:@L1Scout', '-n': '1000'}, + steps['NANO_data16.0']]) + +steps['l1ScoutingSelectionNANO_data16.0'] = merge([{'-s': 'NANO:@L1ScoutSelect', '-n': '1000'}, + steps['NANO_data16.0']]) + ################################################################ # NANOGEN steps['NANOGENFromGen'] = merge([{'-s': 'NANO:@GEN,DQM:@nanogenDQM', @@ -633,6 +662,8 @@ def next(self, index: int = None) -> None: workflows[_wfn()] = ['ScoutingNANOmonitordata150Xrun3', ['ScoutingPFMonitor_Run2025C_MINIAOD_150X', 'scoutingNANO_monitor_data15.0']] # noqa workflows[_wfn()] = ['ScoutingNANOmonitorWithPromptdata150Xrun3', ['ScoutingPFMonitor_Run2025C_MINIAOD_150X', 'scoutingNANO_monitorWithPrompt_data15.0']] # noqa workflows[_wfn()] = ['BPHNANOdata150Xrun3', ['JetMET1_Run2025C_MINIAOD_150X', 'BPHNANO_data15.0']] +workflows[_wfn()] = ['L1ScoutingNANOdata150Xrun3', ['L1Scouting2025RAW15.0', 'l1ScoutingNANO_data15.0']] +workflows[_wfn()] = ['L1ScoutingSelectionNANOdata150Xrun3', ['L1ScoutingSelection2025RAW15.0', 'l1ScoutingSelectionNANO_data15.0']] # DPG custom NANOs, data _wfn.subnext() @@ -640,6 +671,27 @@ def next(self, index: int = None) -> None: # DPG custom NANOs, MC _wfn.subnext() +_wfn.next(4) +######## 2500.4xxx ######## +# Run3, 16_0_X input (2026 data-taking) +# Standard NANO, MC + +# Standard NANO, data +_wfn.subnext() + +# POG/PAG custom NANOs, MC +_wfn.subnext() + +# POG/PAG custom NANOs, data +_wfn.subnext() +workflows[_wfn()] = ['L1ScoutingNANOdata160Xrun3', ['L1Scouting2026RAW16.0', 'l1ScoutingNANO_data16.0']] +workflows[_wfn()] = ['L1ScoutingSelectionNANOdata160Xrun3', ['L1ScoutingSelection2026RAW16.0', 'l1ScoutingSelectionNANO_data16.0']] + +# DPG custom NANOs, data +_wfn.subnext() + +# DPG custom NANOs, MC +_wfn.subnext() _wfn.next(9) ######## 2500.9xxx ########