Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve ScoutingNano integration with autoNano #46516

Merged
merged 4 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Configuration/PyReleaseValidation/python/relval_nano.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,9 @@ def subnext(self):
steps['scoutingNANO_mc14.0'] = merge([{'-s': 'NANO:@Scout'},
steps['NANO_mc14.0']])

steps['scoutingNANO_withPrompt_mc14.0'] = merge([{'-s': 'NANO:@Prompt+@Scout'},
steps['NANO_mc14.0']])

# 14.0 workflows -- data
lumis_Run2024D = {380306: [[28, 273]]}
steps['MuonEG2024MINIAOD14.0'] = {'INPUT': InputInfo(location='STD', ls=lumis_Run2024D,
Expand All @@ -208,6 +211,9 @@ def subnext(self):
steps['ScoutingPFRun32024RAW14.0'] = {'INPUT': InputInfo(location='STD', ls=lumis_Run2024D,
dataSet='/ScoutingPFRun3/Run2024D-v1/HLTSCOUT')}

steps['ScoutingPFMonitor2024MINIAOD14.0'] = {'INPUT': InputInfo(location='STD', ls=lumis_Run2024D,
dataSet='/ScoutingPFMonitor/Run2024D-PromptReco-v1/MINIAOD')}

steps['ZMuSkim2024RAWRECO14.0'] = {'INPUT': InputInfo(location='STD', ls=lumis_Run2024D,
dataSet='/Muon0/Run2024D-ZMu-PromptReco-v1/RAW-RECO')}

Expand Down Expand Up @@ -244,6 +250,12 @@ def subnext(self):
steps['scoutingNANO_data14.0'] = merge([{'-s': 'NANO:@Scout'},
steps['NANO_data14.0']])

# Process.options.TryToContinue = cms.untracked.vstring(\'ProductNotFound\') is needed here because some events in ScoutingPFMonitor in 2024 do not contain scouting objects.
# This should be fixed in 2025 (https://its.cern.ch/jira/browse/CMSHLT-3331) so customise_commands won't be needed for 2025 workflow.
steps['scoutingNANO_withPrompt_data14.0'] = merge([{'-s': 'NANO:@Prompt+@Scout',
'--customise_commands': '"process.options.TryToContinue = cms.untracked.vstring(\'ProductNotFound\')"'},
steps['NANO_data14.0']])

# DPG custom NANO
steps['muDPGNANO_data14.0'] = merge([{'-s': 'RAW2DIGI,NANO:@MUDPG', '-n': '100'},
steps['NANO_data14.0']])
Expand Down Expand Up @@ -336,6 +348,7 @@ def subnext(self):
workflows[_wfn()] = ['jmeNANOrePuppimc140X', ['TTbarMINIAOD14.0', 'jmeNANO_rePuppi_mc14.0']]
workflows[_wfn()] = ['lepTrackInfoNANOmc140X', ['TTbarMINIAOD14.0', 'lepTrackInfoNANO_mc14.0']]
workflows[_wfn()] = ['ScoutingNANOmc140X', ['TTbarMINIAOD14.0', 'scoutingNANO_mc14.0']]
workflows[_wfn()] = ['ScoutingNANOwithPromptmc140X', ['TTbarMINIAOD14.0', 'scoutingNANO_withPrompt_mc14.0']]

# POG/PAG custom NANOs, data
_wfn.subnext()
Expand All @@ -346,6 +359,7 @@ def subnext(self):
workflows[_wfn()] = ['jmeNANOrePuppidata140Xrun3', ['MuonEG2024MINIAOD14.0', 'jmeNANO_rePuppi_data14.0']]
workflows[_wfn()] = ['lepTrackInfoNANOdata140Xrun3', ['MuonEG2024MINIAOD14.0', 'lepTrackInfoNANO_data14.0']]
workflows[_wfn()] = ['ScoutingNANOdata140Xrun3', ['ScoutingPFRun32024RAW14.0', 'scoutingNANO_data14.0']]
workflows[_wfn()] = ['ScoutingNANOwithPromptdata140Xrun3', ['ScoutingPFMonitor2024MINIAOD14.0', 'scoutingNANO_withPrompt_data14.0']]

# DPG custom NANOs, data
_wfn.subnext()
Expand Down
7 changes: 5 additions & 2 deletions PhysicsTools/NanoAOD/python/autoNANO.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@ def expandNanoMapping(seqList, mapping, key):
# L1 flavours: add tables through customize, supposed to be combined with PHYS
'L1': {'customize': 'PhysicsTools/NanoAOD/l1trig_cff.nanoL1TrigObjCustomize'},
'L1FULL': {'customize': 'PhysicsTools/NanoAOD/l1trig_cff.nanoL1TrigObjCustomizeFull'},
# scouting nano
'Scout': {'sequence': 'PhysicsTools/NanoAOD/custom_run3scouting_cff'},
# Scouting nano
'Scout' : {'sequence': 'PhysicsTools/NanoAOD/custom_run3scouting_cff.scoutingNanoSequence',
'customize': 'PhysicsTools/NanoAOD/custom_run3scouting_cff.customiseScoutingNano'},
'ScoutFromMini' : {'sequence': '@Scout',
'customize': '@Scout+PhysicsTools/NanoAOD/custom_run3scouting_cff.customiseScoutingNanoFromMini'},
# JME nano
'JME': {'sequence': '@PHYS',
'customize': '@PHYS+PhysicsTools/NanoAOD/custom_jme_cff.PrepJMECustomNanoAOD'},
Expand Down
193 changes: 157 additions & 36 deletions PhysicsTools/NanoAOD/python/custom_run3scouting_cff.py
Original file line number Diff line number Diff line change
@@ -1,62 +1,183 @@
import FWCore.ParameterSet.Config as cms
from PhysicsTools.NanoAOD.run3scouting_cff import *
from PhysicsTools.NanoAOD.globals_cff import puTable
from PhysicsTools.NanoAOD.triggerObjects_cff import unpackedPatTrigger, triggerObjectTable, l1bits
from L1Trigger.Configuration.L1TRawToDigi_cff import *
from EventFilter.L1TRawToDigi.gtStage2Digis_cfi import gtStage2Digis
from PhysicsTools.PatAlgos.triggerLayer1.triggerProducer_cfi import patTrigger
from PhysicsTools.PatAlgos.slimming.selectedPatTrigger_cfi import selectedPatTrigger
from PhysicsTools.PatAlgos.slimming.slimmedPatTrigger_cfi import slimmedPatTrigger
from PhysicsTools.NanoAOD.triggerObjects_cff import l1bits
from PhysicsTools.NanoAOD.globals_cff import puTable

############################
### Sub Task Definitions ###
############################

# common tasks
particleTask = cms.Task(scoutingPFCands)
ak4JetTableTask = cms.Task(ak4ScoutingJets,ak4ScoutingJetParticleNetJetTagInfos,ak4ScoutingJetParticleNetJetTags,ak4ScoutingJetTable)
ak8JetTableTask = cms.Task(ak8ScoutingJets,ak8ScoutingJetsSoftDrop,ak8ScoutingJetsSoftDropMass,ak8ScoutingJetEcfNbeta1,ak8ScoutingJetNjettiness,ak8ScoutingJetParticleNetJetTagInfos,ak8ScoutingJetParticleNetJetTags,ak8ScoutingJetParticleNetMassRegressionJetTags,ak8ScoutingJetTable)
# Task contains all dependent tasks
# ExtensionTask must be run on top of another Task

muonScoutingTableTask = cms.Task(muonScoutingTable)
displacedvertexScoutingTableTask = cms.Task(displacedvertexScoutingTable)
#############################
# Scouting Original Objects #
#############################

# from 2024, there are two scouting muon collections
# Scouting Muon
scoutingMuonTableTask = cms.Task(scoutingMuonTable)
scoutingMuonDisplacedVertexTableTask = cms.Task(scoutingMuonDisplacedVertexTable)

# from 2024, there are two muon collections
from Configuration.Eras.Modifier_run3_scouting_nanoAOD_post2023_cff import run3_scouting_nanoAOD_post2023
run3_scouting_nanoAOD_post2023.toReplaceWith(muonScoutingTableTask, cms.Task(muonVtxScoutingTable, muonNoVtxScoutingTable))\
.toReplaceWith(displacedvertexScoutingTableTask, cms.Task(displacedvertexVtxScoutingTable, displacedvertexNoVtxScoutingTable))
run3_scouting_nanoAOD_post2023.toReplaceWith(scoutingMuonTableTask, cms.Task(scoutingMuonVtxTable, scoutingMuonNoVtxTable))\
.toReplaceWith(scoutingMuonDisplacedVertexTableTask, cms.Task(scoutingMuonVtxDisplacedVertexTable, scoutingMuonNoVtxDisplacedVertexTable))

# other collections are directly from original Run3Scouting objects, so unnessary to define tasks

############################
# Scouting Derived Objects #
############################

scoutingPFCandidateTask = cms.Task(scoutingPFCandidate, scoutingPFCandidateTable)
scoutingPFJetReclusterTask = cms.Task(
scoutingPFCandidate, # translate to reco::PFCandidate, used as input
scoutingPFJetRecluster, # jet clustering
scoutingPFJetReclusterParticleNetJetTagInfos, scoutingPFJetReclusterParticleNetJetTags, # jet tagging
scoutingPFJetReclusterTable
)
scoutingPFJetReclusterMatchGenExtensionTask = cms.Task(
scoutingPFJetReclusterMatchGen, # gen jet matching
scoutingPFJetReclusterMatchGenExtensionTable
)

scoutingFatPFJetReclusterTask = cms.Task(
scoutingPFCandidate, # translate to reco::PFCandidate, used as input
scoutingFatPFJetRecluster, # jet clustering
scoutingFatPFJetReclusterParticleNetJetTagInfos, scoutingFatPFJetReclusterParticleNetJetTags, # jet tagging
scoutingFatPFJetReclusterSoftDrop, scoutingFatPFJetReclusterSoftDropMass, # softdrop mass
scoutingFatPFJetReclusterParticleNetJetTagInfos, scoutingFatPFJetReclusterParticleNetMassRegressionJetTags, # regressed mass
scoutingFatPFJetReclusterEcfNbeta1, scoutingFatPFJetReclusterNjettiness, # substructure variables
scoutingFatPFJetReclusterTable
)
scoutingFatPFJetReclusterMatchGenExtensionTask = cms.Task(
scoutingFatPFJetReclusterMatchGen, # gen jet matching
scoutingFatPFJetReclusterMatchGenExtensionTable
)

############################
# Trigger Bits and Objects #
############################

## L1 decisions
gtStage2DigisScouting = gtStage2Digis.clone(InputLabel="hltFEDSelectorL1")
l1bitsScouting = l1bits.clone(src="gtStage2DigisScouting")
l1bitsScouting = l1bits.clone(src="gtStage2DigisScouting")

## L1 objects
from PhysicsTools.NanoAOD.l1trig_cff import *
l1MuScoutingTable = l1MuTable.clone(src=cms.InputTag("gtStage2DigisScouting","Muon"))
l1JetScoutingTable = l1JetTable.clone(src=cms.InputTag("gtStage2DigisScouting","Jet"))
l1EGScoutingTable = l1EGTable.clone(src=cms.InputTag("gtStage2DigisScouting","EGamma"))
l1TauScoutingTable = l1TauTable.clone(src=cms.InputTag("gtStage2DigisScouting","Tau"))
l1EtSumScoutingTable = l1EtSumTable.clone(src=cms.InputTag("gtStage2DigisScouting","EtSum"))
l1MuScoutingTable = l1MuTable.clone(src=cms.InputTag("gtStage2DigisScouting", "Muon"))
l1EGScoutingTable = l1EGTable.clone(src=cms.InputTag("gtStage2DigisScouting", "EGamma"))
l1TauScoutingTable = l1TauTable.clone(src=cms.InputTag("gtStage2DigisScouting", "Tau"))
l1JetScoutingTable = l1JetTable.clone(src=cms.InputTag("gtStage2DigisScouting", "Jet"))
l1EtSumScoutingTable = l1EtSumTable.clone(src=cms.InputTag("gtStage2DigisScouting", "EtSum"))

#reduce the variables to the core variables as only these are available in gtStage2Digis
l1EGScoutingTable.variables = cms.PSet(l1EGReducedVars)
# reduce the variables to the core variables as only these are available in gtStage2Digis
l1MuScoutingTable.variables = cms.PSet(l1MuonReducedVars)
l1JetScoutingTable.variables = cms.PSet(l1JetReducedVars)
l1EGScoutingTable.variables = cms.PSet(l1EGReducedVars)
l1TauScoutingTable.variables = cms.PSet(l1TauReducedVars)
l1JetScoutingTable.variables = cms.PSet(l1JetReducedVars)
l1EtSumScoutingTable.variables = cms.PSet(l1EtSumReducedVars)

triggerTask = cms.Task(
gtStage2DigisScouting, l1bitsScouting,
l1MuScoutingTable, l1EGScoutingTable, l1TauScoutingTable, l1JetScoutingTable, l1EtSumScoutingTable,
)
triggerSequence = cms.Sequence(L1TRawToDigi+cms.Sequence(triggerTask))
##############################
### Main Tasks Definitions ###
##############################

# default configuration for ScoutingNano common for both data and MC
def prepareScoutingNanoTaskCommon():
# Scouting original objects
# all scouting objects are saved except PF Candidate and Track
scoutingNanoTaskCommon = cms.Task()
scoutingNanoTaskCommon.add(scoutingMuonTableTask, scoutingMuonDisplacedVertexTableTask)
scoutingNanoTaskCommon.add(scoutingElectronTable)
scoutingNanoTaskCommon.add(scoutingPhotonTable)
scoutingNanoTaskCommon.add(scoutingPrimaryVertexTable)
scoutingNanoTaskCommon.add(scoutingPFJetTable)
scoutingNanoTaskCommon.add(scoutingMETTable, scoutingRhoTable)

# Scouting derived objects
scoutingNanoTaskCommon.add(scoutingPFJetReclusterTask)
scoutingNanoTaskCommon.add(scoutingFatPFJetReclusterTask)

return scoutingNanoTaskCommon

# tasks related to trigger bits and objects
def prepareScoutingTriggerTask():
scoutingTriggerTask = cms.Task(gtStage2DigisScouting, l1bitsScouting)
scoutingTriggerTask.add(cms.Task(l1MuScoutingTable, l1EGScoutingTable, l1TauScoutingTable, l1JetScoutingTable, l1EtSumScoutingTable))
return scoutingTriggerTask

# additional tasks for running on MC
def prepareScoutingNanoTaskMC():
scoutingNanoTaskMC = cms.Task()
scoutingNanoTaskMC.add(scoutingPFJetReclusterMatchGenExtensionTask)
scoutingNanoTaskMC.add(scoutingFatPFJetReclusterMatchGenExtensionTask)

# MC tasks
genJetTask = cms.Task(ak4ScoutingJetMatchGen,ak4ScoutingJetExtTable,ak8ScoutingJetMatchGen,ak8ScoutingJetExtTable)
puTask = cms.Task(puTable)
scoutingNanoTaskMC.add(puTable)
return scoutingNanoTaskMC

nanoTableTaskCommon = cms.Task(photonScoutingTable,muonScoutingTableTask,electronScoutingTable,primaryvertexScoutingTable,displacedvertexScoutingTableTask,jetScoutingTable,rhoScoutingTable,metScoutingTable,particleTask,ak4JetTableTask,ak8JetTableTask)
# Common tasks added to main scoutingNanoSequence
scoutingNanoTaskCommon = prepareScoutingNanoTaskCommon()
scoutingNanoSequence = cms.Sequence(scoutingNanoTaskCommon)

# Specific tasks which will be added to sequence during customization
scoutingTriggerTask = prepareScoutingTriggerTask()
scoutingTriggerSequence = cms.Sequence(L1TRawToDigi+cms.Sequence(scoutingTriggerTask))
scoutingNanoTaskMC = prepareScoutingNanoTaskMC()

def customiseScoutingNano(process):
# if running with standard NanoAOD, triggerSequence is already added
# if running standalone, triggerSequence need to be added
if not ((hasattr(process, "nanoSequence") and process.schedule.contains(process.nanoSequence))
or hasattr(process, "nanoSequenceMC") and process.schedule.contains(process.nanoSequenceMC)):
process.trigger_step = cms.Path(process.scoutingTriggerSequence)
process.schedule.extend([process.trigger_step])

# specific tasks when running on MC
runOnMC = hasattr(process,"NANOEDMAODSIMoutput") or hasattr(process,"NANOAODSIMoutput")
if runOnMC:
process.scoutingNanoSequence.associate(scoutingNanoTaskMC)

return process

nanoSequenceCommon = cms.Sequence(triggerSequence,nanoTableTaskCommon)
#####################
### Customisation ###
#####################
# these function are designed to be used with --customise flag in cmsDriver.py
# e.g. --customise PhysicsTools/NanoAOD/python/custom_run3scouting_cff.addScoutingPFCandidate

nanoSequence = cms.Sequence(nanoSequenceCommon)
# reconfigure for running with ScoutingPFMonitor/MiniAOD inputs alone
# should be used with default customiseScoutingNano
def customiseScoutingNanoFromMini(process):
# remove L1TRawToDigi
process.scoutingTriggerSequence.remove(process.L1TRawToDigi)

nanoSequenceMC = cms.Sequence(nanoSequenceCommon + cms.Sequence(cms.Task(genJetTask,puTask)))
# remove gtStage2Digis since they are already run for Mini
process.scoutingTriggerTask.remove(process.gtStage2DigisScouting)

# change src for l1 bits
process.l1bitsScouting.src = cms.InputTag("gtStage2Digis")

# change src for l1 objects
process.l1MuScoutingTable.src = cms.InputTag("gmtStage2Digis", "Muon")
process.l1EGScoutingTable.src = cms.InputTag("caloStage2Digis", "EGamma")
process.l1TauScoutingTable.src = cms.InputTag("caloStage2Digis", "Tau")
process.l1JetScoutingTable.src = cms.InputTag("caloStage2Digis", "Jet")
process.l1EtSumScoutingTable.src = cms.InputTag("caloStage2Digis", "EtSum")

return process

def addScoutingTrack(process):
process.scoutingNanoSequence.associate(cms.Task(scoutingTrackTable))
return process

def addScoutingParticle(process):
# original PF candidate without post-processing
process.scoutingNanoSequence.associate(cms.Task(scoutingParticleTable))
return process

def nanoAOD_customizeCommon(process):
def addScoutingPFCandidate(process):
# PF candidate after translation to reco::PFCandidate
process.scoutingNanoSequence.associate(scoutingPFCandidateTask)
return process
Loading