4 from __future__
import print_function
7 from AnalysisAlgorithmsConfig.ConfigBlock
import ConfigBlock
8 from AnalysisAlgorithmsConfig.ConfigSequence
import groupBlocks
9 from AnalysisAlgorithmsConfig.ConfigAccumulator
import DataType
11 from AthenaConfiguration.Enums
import LHCPeriod
12 from AthenaCommon.Logging
import logging
17 """the ConfigBlock for the common preprocessing of jet sequences"""
19 def __init__ (self, containerName='', jetCollection='') :
20 super (PreJetAnalysisConfig, self).__init__ ()
21 self.addOption (
'containerName', containerName, type=str,
23 info=
"the name of the output container after calibration.")
24 self.addOption (
'jetCollection', jetCollection, type=str,
26 info=
"the jet container to run on. It is interpreted to determine "
27 "the correct config blocks to call for small- or large-R jets.")
28 self.addOption(
'outputTruthLabelIDs',
False, type=bool,
29 info=
'Enable or disable HadronConeExclTruthLabelID and PartonTruthLabelID decorations')
31 self.addOption (
'runOriginalObjectLink',
False, type=bool,
33 self.addOption (
'runGhostMuonAssociation',
None, type=bool,
34 info=
"whether to set up the jet-ghost-muon association algorithm "
35 "CP::JetGhostMuonAssociationAlg. The default is False.")
36 self.addOption (
'runTruthJetTagging',
None, type=bool,
37 info=
"whether to set up the jet truth tagging algorithm "
38 "CP::JetTruthTagAlg. The default is True.")
45 config.setSourceName (self.containerName,
"AnalysisJets", originalName = self.
jetCollection)
46 elif config.isPhyslite()
and self.
jetCollection ==
'AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets' :
47 config.setSourceName (self.containerName,
"AnalysisLargeRJets", originalName = self.
jetCollection)
52 if self.runOriginalObjectLink :
53 alg = config.createAlgorithm(
'CP::AsgOriginalObjectLinkAlg',
54 'JetOriginalObjectLinkAlg'+self.containerName,
57 alg.particles = config.readName (self.containerName)
58 if config.wantCopy (self.containerName) :
59 alg.particlesOut = config.copyName (self.containerName)
60 alg.preselection = config.getPreselection (self.containerName,
'')
63 if (self.runGhostMuonAssociation
is None and not config.isPhyslite())
or \
64 (self.runGhostMuonAssociation
is True):
65 alg = config.createAlgorithm(
'CP::JetGhostMuonAssociationAlg',
66 'JetGhostMuonAssociationAlg'+self.containerName )
67 alg.jets = config.readName (self.containerName)
68 if config.isPhyslite():
69 alg.muons =
"AnalysisMuons"
70 if config.wantCopy (self.containerName) :
71 alg.jetsOut = config.copyName (self.containerName)
75 if self.runTruthJetTagging
or (
76 self.runTruthJetTagging
is None
77 and config.dataType()
is not DataType.Data
80 alg = config.createAlgorithm(
'CP::JetDecoratorAlg',
'JetPileupLabelAlg'+self.containerName )
81 config.addPrivateTool(
'decorator',
'JetPileupLabelingTool' )
82 alg.jets = config.readName (self.containerName)
83 alg.jetsOut = config.copyName (self.containerName)
84 alg.decorator.RecoJetContainer = alg.jetsOut.replace (
'%SYS%',
'NOSYS')
85 alg.decorator.SuppressOutputDependence=
True
88 if config.wantCopy (self.containerName) :
89 alg = config.createAlgorithm(
'CP::AsgShallowCopyAlg',
'JetShallowCopyAlg' + self.containerName )
90 alg.input = config.readName (self.containerName)
91 alg.output = config.copyName (self.containerName)
93 config.addOutputVar (self.containerName,
'pt',
'pt')
94 config.addOutputVar (self.containerName,
'eta',
'eta', noSys=
True)
95 config.addOutputVar (self.containerName,
'phi',
'phi', noSys=
True)
96 config.addOutputVar (self.containerName,
'charge',
'charge', noSys=
True, enabled=
False)
98 if self.outputTruthLabelIDs
and config.dataType()
is not DataType.Data:
99 config.addOutputVar (self.containerName,
'HadronConeExclTruthLabelID',
'HadronConeExclTruthLabelID', noSys=
True)
100 config.addOutputVar (self.containerName,
'PartonTruthLabelID',
'PartonTruthLabelID', noSys=
True)
105 """the ConfigBlock for the small-r jet sequence"""
107 def __init__ (self, containerName='', jetCollection='', jetInput='') :
108 super (SmallRJetAnalysisConfig, self).__init__ ()
109 self.addOption (
'containerName', containerName, type=str,
111 info=
"the name of the output container after calibration.")
112 self.addOption (
'jetCollection', jetCollection, type=str,
114 info=
"the jet container to run on. It is interpreted to determine "
115 "the correct config blocks to call for small- or large-R jets.")
117 self.addOption (
'jetInput', jetInput, type=str,
120 self.addOption (
'runJvtUpdate',
False, type=bool,
121 info=
"whether to update the JVT. The default is False.")
122 self.addOption (
'runNNJvtUpdate',
False, type=bool,
123 info=
"whether to update the NN-JVT. The default is False.")
124 self.addOption (
'runFJvtUpdate',
False, type=bool,
125 info=
"whether to update the forward JVT. The default is False.")
126 self.addOption (
'runJvtSelection',
True, type=bool,
127 info=
"whether to run JVT selection. The default is True.")
128 self.addOption (
'runFJvtSelection',
False, type=bool,
129 info=
"whether to run forward JVT selection. The default is False.")
130 self.addOption (
'jvtWP',
"FixedEffPt", type=str,
131 info=
"which Jvt WP to apply. The default is FixedEffPt.")
132 self.addOption (
'fJvtWP',
"Loose", type=str,
133 info=
"which fJvt WP to apply. The default is Loose.")
134 self.addOption (
'runJvtEfficiency',
True, type=bool,
135 info=
"whether to calculate the JVT efficiency. The default is True.")
136 self.addOption (
'runFJvtEfficiency',
False, type=bool,
137 info=
"whether to calculate the forward JVT efficiency. The default is False.")
138 self.addOption (
'systematicsModelJES',
"Category", type=str,
139 info=
"the NP reduction scheme to use for JES: All, Global, Category, "
140 "Scenario. The default is Category.")
141 self.addOption (
'systematicsModelJER',
"Full", type=str,
142 info=
"the NP reduction scheme to use for JER: All, Full, Simple. The "
144 self.addOption (
'runJERsystematicsOnData',
False, type=bool,
145 info=
"whether to run the All/Full JER model variations also on data samples. Expert option!")
146 self.addOption (
'recalibratePhyslite',
True, type=bool,
147 info=
"whether to run the CP::JetCalibrationAlg on PHYSLITE derivations. "
148 "The default is True.")
150 self.addOption (
'calibToolConfigFile',
None, type=str,
151 info=
"name (str) of the config file to use for the jet calibration "
152 "tool. Expert option to override JetETmiss recommendations. The "
154 self.addOption (
'calibToolCalibArea',
None, type=str,
155 info=
"name (str) of the CVMFS area to use for the jet calibration "
156 "tool. Expert option to override JetETmiss recommendations. The "
158 self.addOption (
'calibToolCalibSeq',
None, type=str,
159 info=
"name (str) of the sequence to use for the jet calibration "
160 "tool (e.g. 'JetArea_Residual_EtaJES_GSC'). Expert option to override "
161 "JetETmiss recommendations. The default is None.")
163 self.addOption (
'uncertToolConfigPath',
None, type=str,
164 info=
"name (str) of the config file to use for the jet uncertainty "
165 "tool. Expert option to override JetETmiss recommendations. The "
167 self.addOption (
'uncertToolCalibArea',
None, type=str,
168 info=
"name (str) of the CVMFS area to use for the jet uncertainty "
169 "tool. Expert option to override JetETmiss recommendations. The "
171 self.addOption (
'uncertToolMCType',
None, type=str,
172 info=
"data type (str) to use for the jet uncertainty tool (e.g. "
173 "'AF3' or 'MC16'). Expert option to override JetETmiss "
174 "recommendations. The default is None.")
186 config_file =
"R4_AllNuisanceParameters_AllJERNP.config"
190 "Invalid uncertainty configuration - Scenario* systematicsModelJESs can "
191 "only be used together with the Simple systematicsModelJER")
197 "Invalid combination of systematicsModelJES and systematicsModelJER settings: "
202 if self.uncertToolCalibArea
is not None:
203 calib_area = self.uncertToolCalibArea
206 if self.uncertToolConfigPath
is not None:
207 config_file = self.uncertToolConfigPath
209 if config.geometry()
is LHCPeriod.Run2:
210 if config.dataType()
is DataType.FastSim:
211 config_file =
"rel22/Fall2024_PreRec/" + config_file
214 config_file =
"HIJetUncertainties/Spring2023/HI" + config_file
216 config_file =
"rel22/Summer2023_PreRec/" + config_file
218 if config.dataType()
is DataType.FastSim:
219 config_file =
"rel22/Winter2025_AF3_PreRec/" + config_file
222 config_file =
"HIJetUncertainties/Spring2023/HI" + config_file
224 config_file =
"rel22/Winter2025_PreRec/" + config_file
228 if self.uncertToolMCType
is not None:
229 mc_type = self.uncertToolMCType
231 if config.geometry()
is LHCPeriod.Run2:
232 if config.dataType()
is DataType.FastSim:
237 if config.dataType()
is DataType.FastSim:
245 return config_file, calib_area, mc_type
260 config.addPrivateTool(
'uncertaintiesTool',
'JetUncertaintiesTool' )
261 jetUncertaintiesAlg.uncertaintiesTool.JetDefinition = jetCollectionName[:-4]
262 jetUncertaintiesAlg.uncertaintiesTool.ConfigFile = configFile
263 if calibArea
is not None:
264 jetUncertaintiesAlg.uncertaintiesTool.CalibArea = calibArea
265 jetUncertaintiesAlg.uncertaintiesTool.MCType = mcType
266 jetUncertaintiesAlg.uncertaintiesTool.IsData = (config.dataType()
is DataType.Data)
267 jetUncertaintiesAlg.uncertaintiesTool.PseudoDataJERsmearingMode =
False
269 if config.dataType()
is DataType.Data
and not (doPseudoData
and self.runJERsystematicsOnData):
271 jetUncertaintiesAlg.affectingSystematicsFilter =
'.*'
272 if config.dataType()
is not DataType.Data
and doPseudoData
and not self.runJERsystematicsOnData:
274 config.addPrivateTool(
'uncertaintiesToolPD',
'JetUncertaintiesTool' )
275 jetUncertaintiesAlg.uncertaintiesToolPD.JetDefinition = jetCollectionName[:-4]
276 jetUncertaintiesAlg.uncertaintiesToolPD.ConfigFile = configFile
277 if calibArea
is not None:
278 jetUncertaintiesAlg.uncertaintiesToolPD.CalibArea = calibArea
279 jetUncertaintiesAlg.uncertaintiesToolPD.MCType = mcType
282 jetUncertaintiesAlg.uncertaintiesToolPD.IsData =
True
283 jetUncertaintiesAlg.uncertaintiesToolPD.PseudoDataJERsmearingMode =
True
290 jetCollectionName=
"AntiKt4EMPFlowJets"
292 jetCollectionName=
"AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets"
294 if self.
jetInput not in [
"EMTopo",
"EMPFlow",
"HI"]:
296 "Unsupported input type '{0}' for R=0.4 jets!".
format(self.
jetInput) )
298 if self.jvtWP
not in [
"FixedEffPt"]:
300 "Unsupported NNJvt WP '{0}'".
format(self.jvtWP) )
302 if self.fJvtWP
not in [
"Loose",
"Tight",
"Tighter"]:
304 "Unsupported fJvt WP '{0}'".
format(self.fJvtWP) )
306 if not config.isPhyslite()
or self.recalibratePhyslite:
308 alg = config.createAlgorithm(
'CP::JetCalibrationAlg',
'JetCalibrationAlg'+self.containerName )
309 config.addPrivateTool(
'calibrationTool',
'JetCalibrationTool' )
310 alg.calibrationTool.JetCollection = jetCollectionName[:-4]
313 if config.geometry()
is LHCPeriod.Run2:
314 configFile =
"PreRec_R22_PFlow_ResPU_EtaJES_GSC_February23_230215.config"
315 alg.calibrationTool.CalibArea =
"00-04-82"
316 elif config.geometry() >= LHCPeriod.Run3:
317 configFile =
"AntiKt4EMPFlow_MC23a_PreRecR22_Phase2_CalibConfig_ResPU_EtaJES_GSC_241208_InSitu.config"
318 alg.calibrationTool.CalibArea =
"00-04-83"
320 if config.geometry()
is LHCPeriod.Run2:
321 configFile =
"JES_MC16_HI_Jan2021_5TeV.config"
322 if config.geometry()
is LHCPeriod.Run3:
323 configFile =
"AntiKt4HI_JES_constants_11-05-2024_13p6TeVFinalConfiguration.config"
324 alg.calibrationTool.CalibArea =
"00-04-83"
326 if config.dataType()
is DataType.FastSim:
327 configFile =
"JES_MC16Recommendation_AFII_{0}_Apr2019_Rel21.config"
329 configFile =
"JES_MC16Recommendation_Consolidated_{0}_Apr2019_Rel21.config"
330 configFile = configFile.format(self.
jetInput)
331 if self.calibToolCalibArea
is not None:
332 alg.calibrationTool.CalibArea = self.calibToolCalibArea
333 if self.calibToolConfigFile
is not None:
334 configFile = self.calibToolConfigFile
335 alg.calibrationTool.ConfigFile = configFile
336 if config.dataType()
is DataType.Data:
338 if config.geometry()
is LHCPeriod.Run2:
339 alg.calibrationTool.CalibSequence =
'EtaJES_Insitu'
340 if config.geometry()
is LHCPeriod.Run3:
341 alg.calibrationTool.CalibSequence =
'EtaJES'
343 alg.calibrationTool.CalibSequence =
'JetArea_Residual_EtaJES_GSC_Insitu'
346 alg.calibrationTool.CalibSequence =
'JetArea_Residual_EtaJES_GSC'
348 alg.calibrationTool.CalibSequence =
'EtaJES'
350 alg.calibrationTool.CalibSequence =
'JetArea_Residual_EtaJES_GSC_Smear'
351 if self.calibToolCalibSeq
is not None:
352 alg.calibrationTool.CalibSequence = self.calibToolCalibSeq
353 alg.calibrationTool.IsData = (config.dataType()
is DataType.Data)
354 alg.jets = config.readName (self.containerName)
355 alg.jetsOut = config.copyName (self.containerName)
358 alg = config.createAlgorithm(
'CP::JetUncertaintiesAlg',
'JetUncertaintiesAlg'+self.containerName )
360 alg.jets = config.readName (self.containerName)
361 alg.jetsOut = config.copyName (self.containerName)
362 alg.preselection = config.getPreselection (self.containerName,
'')
365 if self.runJvtUpdate :
366 alg = config.createAlgorithm(
'CP::JvtUpdateAlg',
'JvtUpdateAlg'+self.containerName )
367 config.addPrivateTool(
'jvtTool',
'JetVertexTaggerTool' )
369 alg.jvtTool.SuppressInputDependence=
True
370 alg.jets = config.readName (self.containerName)
371 alg.jetsOut = config.copyName (self.containerName)
372 alg.preselection = config.getPreselection (self.containerName,
'')
374 if self.runNNJvtUpdate:
375 assert self.
jetInput==
"EMPFlow",
"NN JVT only defined for PFlow jets"
376 alg = config.createAlgorithm(
'CP::JetDecoratorAlg',
'NNJvtUpdateAlg'+self.containerName )
377 config.addPrivateTool(
'decorator',
'JetPileupTag::JetVertexNNTagger' )
379 alg.jets = config.readName (self.containerName)
380 alg.jetsOut = config.copyName (self.containerName)
381 alg.decorator.JetContainer = alg.jetsOut.replace (
'%SYS%',
'NOSYS')
382 alg.decorator.SuppressInputDependence=
True
383 alg.decorator.SuppressOutputDependence=
True
385 if self.runFJvtUpdate :
386 alg = config.createAlgorithm(
'CP::JetModifierAlg',
'JetModifierAlg'+self.containerName )
387 config.addPrivateTool(
'modifierTool',
'JetForwardJvtTool')
388 alg.modifierTool.OutputDec =
"passFJVT_internal"
389 alg.modifierTool.FJVTName =
"fJVT"
392 alg.modifierTool.EtaThresh = 2.5
393 alg.modifierTool.ForwardMaxPt = 120*GeV
394 alg.modifierTool.RenounceOutputs =
True
395 alg.jets = config.readName (self.containerName)
396 alg.jetsOut = config.copyName (self.containerName)
400 if self.runJvtSelection :
401 assert self.
jetInput==
"EMPFlow",
"NNJvt WPs and SFs only valid for PFlow jets"
402 alg = config.createAlgorithm(
'CP::AsgSelectionAlg', f
'JvtSelectionAlg{self.containerName}')
403 config.addPrivateTool(
'selectionTool',
'CP::NNJvtSelectionTool')
404 alg.selectionTool.JetContainer = config.readName(self.containerName)
405 alg.selectionTool.WorkingPoint = self.jvtWP
406 alg.selectionTool.MaxPtForJvt = 60*GeV
407 alg.selectionDecoration =
"jvt_selection,as_char"
408 alg.particles = config.readName(self.containerName)
410 if self.runJvtEfficiency
and config.dataType()
is not DataType.Data:
411 alg = config.createAlgorithm(
'CP::JvtEfficiencyAlg',
'JvtEfficiencyAlg'+self.containerName )
412 config.addPrivateTool(
'efficiencyTool',
'CP::NNJvtEfficiencyTool' )
413 alg.efficiencyTool.JetContainer = config.readName(self.containerName)
414 alg.efficiencyTool.MaxPtForJvt = 60*GeV
415 alg.efficiencyTool.WorkingPoint = self.jvtWP
416 if config.geometry()
is LHCPeriod.Run2:
417 alg.efficiencyTool.SFFile =
"JetJvtEfficiency/May2024/NNJvtSFFile_Run2_EMPFlow.root"
419 alg.efficiencyTool.SFFile =
"JetJvtEfficiency/May2024/NNJvtSFFile_Run3_EMPFlow.root"
420 alg.selection =
'jvt_selection,as_char'
421 alg.scaleFactorDecoration =
'jvt_effSF_%SYS%'
422 alg.outOfValidity = 2
423 alg.outOfValidityDeco =
'no_jvt'
424 alg.skipBadEfficiency =
False
425 alg.jets = config.readName (self.containerName)
426 alg.preselection = config.getPreselection (self.containerName,
'')
427 config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
'jvtEfficiency')
428 config.addSelection (self.containerName,
'baselineJvt',
'jvt_selection,as_char', preselection=
False)
430 if self.runFJvtSelection :
431 assert self.
jetInput==
"EMPFlow",
"fJvt WPs and SFs only valid for PFlow jets"
432 alg = config.createAlgorithm(
'CP::AsgSelectionAlg', f
'FJvtSelectionAlg{self.containerName}')
433 config.addPrivateTool(
'selectionTool',
'CP::FJvtSelectionTool')
434 alg.selectionTool.JetContainer = config.readName(self.containerName)
435 alg.selectionTool.WorkingPoint = self.fJvtWP
436 alg.selectionDecoration =
"fjvt_selection,as_char"
437 alg.particles = config.readName(self.containerName)
439 if self.runFJvtEfficiency
and config.dataType()
is not DataType.Data:
440 alg = config.createAlgorithm(
'CP::JvtEfficiencyAlg',
'FJvtEfficiencyAlg'+self.containerName )
441 config.addPrivateTool(
'efficiencyTool',
'CP::FJvtEfficiencyTool' )
442 alg.efficiencyTool.JetContainer = config.readName(self.containerName)
443 alg.efficiencyTool.WorkingPoint = self.fJvtWP
444 if config.geometry()
is LHCPeriod.Run2:
445 alg.efficiencyTool.SFFile =
"JetJvtEfficiency/May2024/fJvtSFFile_Run2_EMPFlow.root"
447 alg.efficiencyTool.SFFile =
"JetJvtEfficiency/May2024/fJvtSFFile_Run3_EMPFlow.root"
448 alg.selection =
'fjvt_selection,as_char'
449 alg.scaleFactorDecoration =
'fjvt_effSF_%SYS%'
450 alg.outOfValidity = 2
451 alg.outOfValidityDeco =
'no_fjvt'
452 alg.skipBadEfficiency =
False
453 alg.jets = config.readName (self.containerName)
454 alg.preselection = config.getPreselection (self.containerName,
'')
455 config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
'fjvtEfficiency')
456 config.addSelection (self.containerName,
'baselineFJvt',
'fjvt_selection,as_char', preselection=
False)
459 alg = config.createAlgorithm(
'CP::AsgEnergyDecoratorAlg',
'EnergyDecorator' + self.containerName )
460 alg.particles = config.readName (self.containerName)
462 config.addOutputVar (self.containerName,
'e_%SYS%',
'e')
466 """the ConfigBlock for the r-scan jet sequence"""
468 def __init__ (self, containerName='', jetCollection='', jetInput='', radius=None) :
469 super (RScanJetAnalysisConfig, self).__init__ ()
470 self.addOption (
'containerName', containerName, type=str,
472 info=
"the name of the output container after calibration.")
473 self.addOption (
'jetCollection', jetCollection, type=str,
475 info=
"the jet container to run on. It is interpreted to determine "
476 "the correct config blocks to call for small- or large-R jets.")
478 self.addOption (
'jetInput', jetInput, type=str,
482 self.addOption (radius, radius, type=int,
485 self.addOption (
'recalibratePhyslite',
True, type=bool,
486 info=
"whether to run the CP::JetCalibrationAlg on PHYSLITE "
487 "derivations. The default is True.")
492 log = logging.getLogger(
'RScanJetAnalysisConfig')
496 jetCollectionName=
"AntiKt4EMPFlowJets"
498 jetCollectionName=
"AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets"
500 if not config.isPhyslite()
or self.recalibratePhyslite:
501 if self.jetInput !=
"LCTopo":
503 "Unsupported input type '{0}' for R-scan jets!".
format(self.jetInput) )
505 alg = config.createAlgorithm(
'CP::JetCalibrationAlg',
'JetCalibrationAlg'+self.containerName )
506 config.addPrivateTool(
'calibrationTool',
'JetCalibrationTool' )
507 alg.calibrationTool.JetCollection = jetCollectionName[:-4]
508 alg.calibrationTool.ConfigFile = \
509 "JES_MC16Recommendation_Rscan{0}LC_Feb2022_R21.config".
format(self.radius)
510 if config.dataType()
is DataType.Data:
511 alg.calibrationTool.CalibSequence =
"JetArea_Residual_EtaJES_GSC_Insitu"
513 alg.calibrationTool.CalibSequence =
"JetArea_Residual_EtaJES_GSC_Smear"
514 alg.calibrationTool.IsData = (config.dataType()
is DataType.Data)
515 alg.jets = config.readName (self.containerName)
517 log.warning(
"Uncertainties for R-Scan jets are not yet released!")
521 is_sim = config.dataType()
in {DataType.FullSim}
522 if self.largeRMass ==
"Comb":
523 if config.dataType()
is DataType.Data:
524 return "JES_MC16recommendation_FatJet_Trimmed_JMS_comb_March2021.config"
526 return "JES_MC16recommendation_FatJet_Trimmed_JMS_comb_17Oct2018.config"
527 elif self.largeRMass ==
"Calo":
528 if config.dataType()
is DataType.Data:
529 return "JES_MC16recommendation_FatJet_Trimmed_JMS_comb_March2021.config"
531 return "JES_MC16recommendation_FatJet_Trimmed_JMS_calo_12Oct2018.config "
532 elif self.largeRMass ==
"TA":
533 if config.dataType()
is DataType.Data:
534 return "JES_MC16recommendation_FatJet_Trimmed_JMS_comb_March2021.config"
536 return "JES_MC16recommendation_FatJet_Trimmed_JMS_TA_12Oct2018.config"
541 """the ConfigBlock for the large-r jet sequence"""
543 def __init__ (self, containerName='', jetCollection='', jetInput='') :
544 super (LargeRJetAnalysisConfig, self).__init__ ()
545 self.addOption (
'containerName', containerName, type=str,
547 info=
"the name of the output container after calibration.")
548 self.addOption (
'jetCollection', jetCollection, type=str,
550 info=
"the jet container to run on. It is interpreted to determine "
551 "the correct config blocks to call for small- or large-R jets.")
553 self.addOption (
'jetInput', jetInput, type=str,
557 self.addOption (
'largeRMass',
"Comb", type=str,
559 self.addOption (
'recalibratePhyslite',
True, type=bool,
560 info=
"whether to run the CP::JetCalibrationAlg on PHYSLITE "
561 "derivations. The default is True.")
562 self.addOption (
'systematicsModelJER',
"Full", type=str)
563 self.addOption (
'systematicsModelJMS',
"Full", type=str)
564 self.addOption (
'systematicsModelJMR',
"Full", type=str,
565 info=
"the NP reduction scheme to use for JMR: Full, Simple. The default is Full.")
566 self.addOption (
'runJERsystematicsOnData',
False, type=bool,
567 info=
"whether to run the All/Full JER model variations also on data samples. Expert option!")
570 self.addOption (
'calibToolConfigFile',
None, type=str,
571 info=
"name (str) of the config file to use for the jet calibration "
572 "tool. Expert option to override JetETmiss recommendations. The "
574 self.addOption (
'calibToolCalibArea',
None, type=str,
575 info=
"name (str) of the CVMFS area to use for the jet calibration "
576 "tool. Expert option to override JetETmiss recommendations. The "
578 self.addOption (
'calibToolCalibSeq',
None, type=str,
579 info=
"name (str) of the sequence to use for the jet calibration "
580 "tool (e.g. 'JetArea_Residual_EtaJES_GSC'). Expert option to override "
581 "JetETmiss recommendations. The default is None.")
583 self.addOption (
'uncertToolConfigPath',
None, type=str,
584 info=
"name (str) of the config file to use for the jet uncertainty "
585 "tool. Expert option to override JetETmiss recommendations. The "
587 self.addOption (
'uncertToolCalibArea',
None, type=str,
588 info=
"name (str) of the CVMFS area to use for the jet uncertainty "
589 "tool. Expert option to override JetETmiss recommendations. The "
591 self.addOption (
'uncertToolMCType',
None, type=str,
592 info=
"data type (str) to use for the jet uncertainty tool (e.g. "
593 "'AF3' or 'MC16'). Expert option to override JetETmiss "
594 "recommendations. The default is None.")
595 self.addOption (
'minPt', 200.*GeV, type=float,
596 info=
"the minimum pt cut to apply to calibrated large-R jets. "
597 "The default is 200 GeV.")
598 self.addOption (
'maxPt', 3000.*GeV, type=float,
599 info=
"the maximum pt cut to apply to calibrated large-R jets. "
600 "The default is 3000 GeV.")
601 self.addOption (
'maxEta', 2., type=float,
602 info=
"the maximum |eta| cut to apply to calibrated large-R jets. "
604 self.addOption (
'minMass', 40.*GeV, type=float,
605 info=
"the minimum mass cut to apply to calibrated large-R jets. "
606 "The default is 40 GeV.")
607 self.addOption (
'maxMass', 600.*GeV, type=float,
608 info=
"the maximum mass cut to apply to calibrated large-R jets. "
609 "The default is 600 GeV.")
616 log = logging.getLogger(
'LargeRJetAnalysisConfig')
620 if self.systematicsModelJER
in [
"Simple",
"Full"]
and self.systematicsModelJMS
in [
"Simple",
"Full"]:
621 config_file =
"R10_CategoryJES_{0}JER_{1}JMS.config".
format(self.systematicsModelJER, self.systematicsModelJMS)
624 "Invalid request for systematicsModelJER/JMS settings: "
625 "systematicsModelJER = '{0}', "
626 "systematicsModelJMS = '{1}'".
format(self.systematicsModelJER, self.systematicsModelJMS) )
627 if self.uncertToolConfigPath
is not None:
629 config_file = self.uncertToolConfigPath
631 if config.geometry()
in [LHCPeriod.Run2, LHCPeriod.Run3]:
632 config_file =
"rel22/Winter2024_PreRec/" + config_file
634 log.warning(
"Uncertainties for UFO jets are not for Run 4!")
638 if self.uncertToolCalibArea
is not None:
639 calib_area = self.uncertToolCalibArea
642 if self.uncertToolMCType
is not None:
643 mc_type = self.uncertToolMCType
645 if config.dataType()
is DataType.FastSim:
647 log.warning(
"AF3 uncertainties for large-R jets are not yet released!")
648 log.warning(
"Using full-sim ones in the meantime!")
649 if config.geometry()
is LHCPeriod.Run2:
654 if config.geometry()
is LHCPeriod.Run2:
659 return config_file, calib_area, mc_type
663 Create instance(s) of JetUncertaintiesTool following JetETmiss recommendations.
665 JER uncertainties under the "Full" scheme must be run on MC samples twice:
667 2. Pseudodata (PD) mode, as if the events are Data.
674 config.addPrivateTool(
'uncertaintiesTool',
'JetUncertaintiesTool' )
675 jetUncertaintiesAlg.uncertaintiesTool.JetDefinition = jetCollectionName[:-4]
676 jetUncertaintiesAlg.uncertaintiesTool.ConfigFile = configFile
677 if calibArea
is not None:
678 jetUncertaintiesAlg.uncertaintiesTool.CalibArea = calibArea
679 jetUncertaintiesAlg.uncertaintiesTool.MCType = mcType
680 jetUncertaintiesAlg.uncertaintiesTool.IsData = (config.dataType()
is DataType.Data)
681 jetUncertaintiesAlg.uncertaintiesTool.PseudoDataJERsmearingMode =
False
684 if config.dataType()
is DataType.Data
and not (config.isPhyslite()
and doPseudoData
and self.runJERsystematicsOnData):
686 jetUncertaintiesAlg.affectingSystematicsFilter =
'.*'
688 if config.dataType()
is not (DataType.Data
and config.isPhyslite())
and doPseudoData
and not self.runJERsystematicsOnData:
690 config.addPrivateTool(
'uncertaintiesToolPD',
'JetUncertaintiesTool' )
691 jetUncertaintiesAlg.uncertaintiesToolPD.JetDefinition = jetCollectionName[:-4]
692 jetUncertaintiesAlg.uncertaintiesToolPD.ConfigFile = configFile
693 if calibArea
is not None:
694 jetUncertaintiesAlg.uncertaintiesToolPD.CalibArea = calibArea
695 jetUncertaintiesAlg.uncertaintiesToolPD.MCType = mcType
696 jetUncertaintiesAlg.uncertaintiesToolPD.IsData =
True
697 jetUncertaintiesAlg.uncertaintiesToolPD.PseudoDataJERsmearingMode =
True
702 log = logging.getLogger(
'LargeRJetAnalysisConfig')
705 if self.systematicsModelJMR
in [
"Simple",
"Full"]:
706 config_file = f
"R10_{self.systematicsModelJMR}JMR.config"
709 f
"Invalid request for systematicsModelJMR settings: {self.systematicsModelJMR}"
713 if self.uncertToolConfigPath
is not None:
714 config_file = self.uncertToolConfigPath
716 if config.geometry()
in [LHCPeriod.Run2, LHCPeriod.Run3]:
717 config_file =
"rel22/Fall2024_PreRec/" + config_file
719 log.warning(
"Uncertainties for UFO jets are not for Run 4!")
722 if config.geometry()
is LHCPeriod.Run2:
723 if config.dataType()
is DataType.FastSim:
727 elif config.geometry()
is LHCPeriod.Run3:
731 config.addPrivateTool(
'FFSmearingTool',
'CP::FFJetSmearingTool')
732 jetFFSmearingAlg.FFSmearingTool.MassDef =
"UFO"
733 jetFFSmearingAlg.FFSmearingTool.MCType = mc_type
734 jetFFSmearingAlg.FFSmearingTool.ConfigFile = config_file
744 jetCollectionName=
"AntiKt4EMPFlowJets"
746 jetCollectionName=
"AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets"
748 if self.largeRMass
not in [
"Comb",
"Calo",
"TA"]:
749 raise ValueError(
"Invalid large-R mass defintion {0}!".
format(self.largeRMass) )
751 if self.
jetInput not in [
"LCTopo",
"TrackCaloCluster",
"UFO"]:
752 raise ValueError(
"Invalid input type '{0}' for large-R jets!".
format(self.
jetInput) )
756 if self.largeRMass !=
"Calo":
757 raise ValueError(
"Invalid large-R TCC jet mass '{0}'!".
format(self.largeRMass) )
758 configFile =
"JES_MC16recommendation_FatJet_TCC_JMS_calo_30Oct2018.config"
762 configFile =
"JES_MC20PreRecommendation_R10_UFO_CSSK_SoftDrop_JMS_R21Insitu_02Aug2024.config"
763 if self.calibToolConfigFile
is not None:
764 configFile = self.calibToolConfigFile
766 if self.
jetInput ==
"TrackCaloCluster" or self.
jetInput ==
"UFO" or config.dataType()
is DataType.FullSim:
767 calibSeq =
"EtaJES_JMS"
768 elif config.dataType()
is DataType.Data:
769 calibSeq =
"EtaJES_JMS_Insitu"
770 if self.calibToolCalibSeq
is not None:
771 calibSeq = self.calibToolCalibSeq
773 if self.calibToolCalibArea
is not None:
774 calibArea = self.calibToolCalibArea
776 if not config.isPhyslite()
or self.recalibratePhyslite:
778 alg = config.createAlgorithm(
'CP::JetCalibrationAlg',
'JetCalibrationAlg'+self.containerName )
779 config.addPrivateTool(
'calibrationTool',
'JetCalibrationTool' )
781 alg.calibrationTool.JetCollection = jetCollectionName[:-4]
783 if configFile
is None:
784 raise ValueError(f
'Unsupported: {self.jetInput=}, {config.dataType()=}')
785 alg.calibrationTool.ConfigFile = configFile
788 raise ValueError(f
'Unsupported: {self.jetInput=}, {config.dataType()=}')
789 alg.calibrationTool.CalibSequence = calibSeq
791 if calibArea
is not None:
792 alg.calibrationTool.CalibArea = calibArea
794 alg.calibrationTool.IsData = (config.dataType()
is DataType.Data)
795 alg.jets = config.readName(self.containerName)
798 if self.
jetInput ==
"UFO" and config.dataType()
in [DataType.FullSim, DataType.FastSim]:
799 alg = config.createAlgorithm(
'CP::JetUncertaintiesAlg',
'JetUncertaintiesAlg'+self.containerName )
800 self.
createUncertaintyTool(alg, config, jetCollectionName, doPseudoData=( self.systematicsModelJER
in [
"Full",
"All"] ))
802 alg.uncertaintiesTool.JetDefinition = jetCollectionName[:-4]
805 alg.outOfValidity = 2
806 alg.outOfValidityDeco =
'outOfValidity'
808 alg.jets = config.readName (self.containerName)
809 alg.jetsOut = config.copyName (self.containerName)
810 alg.preselection = config.getPreselection (self.containerName,
'')
813 alg = config.createAlgorithm(
'CP::JetUncertaintiesAlg',
'JetUncertaintiesAlg'+self.containerName )
816 alg.outOfValidity = 2
817 alg.outOfValidityDeco =
'outOfValidity'
818 config.addPrivateTool(
'uncertaintiesTool',
'JetUncertaintiesTool' )
820 alg.uncertaintiesTool.JetDefinition = jetCollectionName[:-4]
821 alg.uncertaintiesTool.ConfigFile = \
822 "rel21/Moriond2018/R10_{0}Mass_all.config".
format(self.largeRMass)
823 alg.uncertaintiesTool.MCType =
"MC16a"
824 alg.uncertaintiesTool.IsData = (config.dataType()
is DataType.Data)
826 alg.jets = config.readName (self.containerName)
827 alg.jetsOut = config.copyName (self.containerName)
828 alg.preselection = config.getPreselection (self.containerName,
'')
829 config.addSelection (self.containerName,
'',
'outOfValidity')
831 if self.
jetInput ==
"UFO" and config.dataType()
is not DataType.Data:
833 alg = config.createAlgorithm(
'CP::JetFFSmearingAlg',
'JetFFSmearingAlg'+self.containerName )
835 alg.outOfValidity = 2
836 alg.outOfValidityDeco =
'outOfValidityJMR'
837 alg.jets = config.readName (self.containerName)
838 alg.jetsOut = config.copyName (self.containerName)
839 alg.preselection = config.getPreselection (self.containerName,
'')
841 if self.minPt > 0
or self.maxPt > 0
or self.maxEta > 0:
843 alg = config.createAlgorithm(
'CP::AsgSelectionAlg',
'JetPtEtaCutAlg'+self.containerName )
844 alg.selectionDecoration =
'selectPtEta,as_bits'
845 config.addPrivateTool(
'selectionTool',
'CP::AsgPtEtaSelectionTool' )
846 alg.selectionTool.minPt = self.minPt
847 alg.selectionTool.maxPt = self.maxPt
848 alg.selectionTool.maxEta = self.maxEta
849 alg.particles = config.readName (self.containerName)
850 alg.preselection = config.getPreselection (self.containerName,
'')
851 config.addSelection (self.containerName,
'', alg.selectionDecoration,
854 if self.minMass > 0
or self.maxMass > 0:
856 alg = config.createAlgorithm(
'CP::AsgSelectionAlg',
'JetMassCutAlg'+self.containerName )
857 alg.selectionDecoration =
'selectMass,as_bits'
858 config.addPrivateTool(
'selectionTool',
'CP::AsgMassSelectionTool' )
859 alg.selectionTool.minM = self.minMass
860 alg.selectionTool.maxM = self.maxMass
861 alg.particles = config.readName (self.containerName)
862 alg.preselection = config.getPreselection (self.containerName,
'')
863 config.addSelection (self.containerName,
'', alg.selectionDecoration,
866 config.addOutputVar (self.containerName,
'm',
'm')
881 runGhostMuonAssociation = None):
882 """Create a jet analysis algorithm sequence
883 The jet collection is interpreted and selects the correct function to call,
884 makeSmallRJetAnalysisConfig, makeRScanJetAnalysisConfig or
885 makeLargeRJetAnalysisConfig
888 jetCollection -- The jet container to run on.
892 btIndex = jetCollection.find(
'_BTagging')
894 jetCollection = jetCollection[:btIndex]
896 jetCollectionName=jetCollection
898 if(jetCollection==
"AnalysisJets") :
899 jetCollectionName=
"AntiKt4EMPFlowJets"
900 if(jetCollection==
"AnalysisLargeRJets") :
901 jetCollectionName=
"AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets"
904 collection_pattern = re.compile(
905 r"AntiKt(\d+)(EMTopo|EMPFlow|LCTopo|TrackCaloCluster|UFO|Track|HI)(TrimmedPtFrac5SmallR20|CSSKSoftDropBeta100Zcut10)?Jets")
906 match = collection_pattern.match(jetCollectionName)
909 "Jet collection {0} does not match expected pattern!".
format(jetCollectionName) )
910 radius =
int(match.group(1) )
911 if radius
not in [2, 4, 6, 10]:
912 raise ValueError(
"Jet collection has an unsupported radius '{0}'!".
format(radius) )
913 jetInput = match.group(2)
915 if jetCollectionName ==
'AntiKtVR30Rmax4Rmin02PV0TrackJets' :
917 config = PreJetAnalysisConfig (containerName, jetCollection)
918 config.setOptionValue (
'runOriginalObjectLink',
False)
919 config.setOptionValue (
'runGhostMuonAssociation',
False)
923 config = PreJetAnalysisConfig (containerName, jetCollection)
924 config.runOriginalObjectLink = (btIndex != -1)
925 config.setOptionValue (
'runGhostMuonAssociation', runGhostMuonAssociation)
930 jetCollection, jetInput=jetInput)
931 elif radius
in [2, 6]:
933 jetCollection, jetInput=jetInput, radius=radius)
935 trim = match.group(3)
937 raise ValueError(
"Untrimmed large-R jets are not supported!")
939 jetCollection, jetInput=jetInput)
944 runJvtUpdate = None, runNNJvtUpdate = None, runFJvtUpdate = None,
945 runJvtSelection = None, runFJvtSelection = None,
946 jvtWP = None, fJvtWP = None,
947 runJvtEfficiency = None, runFJvtEfficiency = None,
948 systematicsModelJES = None, systematicsModelJER = None):
949 """Add algorithms for the R=0.4 jets.
952 seq -- The sequence to add the algorithms to
953 jetCollection -- The jet container to run on.
954 jetInput -- The type of input used, read from the collection name.
955 runJvtUpdate -- Determines whether or not to update JVT on the jets
956 runNNJvtUpdate -- Determines whether or not to update NN JVT on the jets
957 runFJvtUpdate -- Determines whether or not to update forward JVT on the jets
958 runJvtSelection -- Determines whether or not to run JVT selection on the jets
959 runFJvtSelection -- Determines whether or not to run forward JVT selection on the jets
960 jvtWP -- Defines the NNJvt WP to apply on the jets
961 fJvtWP -- Defines the fJvt WP to apply on the jets
962 runJvtEfficiency -- Determines whether or not to calculate the JVT efficiency
963 runFJvtEfficiency -- Determines whether or not to calculate the forward JVT efficiency
964 systematicsModelJES -- Which NP systematicsModelJES scheme should be used (All, Global, Category, Scenario)
965 systematicsModelJER -- Which variant of the systematicsModelJES should be used (All, Full, Simple). Note that not all combinations of systematicsModelJES and systematicsModelJER are valid!
968 if jetInput
not in [
"EMTopo",
"EMPFlow",
"HI"]:
970 "Unsupported input type '{0}' for R=0.4 jets!".
format(jetInput) )
972 config = SmallRJetAnalysisConfig (containerName, jetCollection, jetInput)
973 config.setOptionValue (
'runJvtUpdate', runJvtUpdate)
974 config.setOptionValue (
'runNNJvtUpdate', runNNJvtUpdate)
975 config.setOptionValue (
'runFJvtUpdate', runFJvtUpdate)
976 config.setOptionValue (
'runJvtSelection', runJvtSelection)
977 config.setOptionValue (
'runFJvtSelection', runFJvtSelection)
978 config.setOptionValue (
'jvtWP', jvtWP)
979 config.setOptionValue (
'fJvtWP', fJvtWP)
980 config.setOptionValue (
'runJvtEfficiency', runJvtEfficiency)
981 config.setOptionValue (
'runFJvtEfficiency', runFJvtEfficiency)
982 config.setOptionValue (
'systematicsModelJES', systematicsModelJES)
983 config.setOptionValue (
'systematicsModelJER', systematicsModelJER)
989 """Add algorithms for the R-scan jets.
992 seq -- The sequence to add the algorithms to
993 jetCollection -- The jet container to run on.
994 jetInput -- The type of input used, read from the collection name.
995 radius -- The radius of the r-scan jets.
998 config = SmallRJetAnalysisConfig (containerName, jetCollection, jetInput, radius)
1005 jetInput, largeRMass = None):
1006 """Add algorithms for the R=1.0 jets.
1009 seq -- The sequence to add the algorithms to
1010 jetCollection -- The jet container to run on.
1011 jetInput -- The type of input used, read from the collection name.
1012 largeRMass -- Which large-R mass definition to use. Ignored if not running on large-R jets ("Comb", "Calo", "TA")
1014 config = LargeRJetAnalysisConfig (containerName, jetCollection, jetInput)
1015 config.setOptionValue (
'largeRMass', largeRMass)