ATLAS Offline Software
JetAnalysisConfig.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2 
3 
4 
5 # AnaAlgorithm import(s):
6 from AnalysisAlgorithmsConfig.ConfigBlock import ConfigBlock
7 from AnalysisAlgorithmsConfig.ConfigSequence import groupBlocks
8 from AnalysisAlgorithmsConfig.ConfigAccumulator import DataType
9 from AthenaCommon.SystemOfUnits import GeV
10 from AthenaConfiguration.Enums import LHCPeriod
11 from AthenaCommon.Logging import logging
12 import re
13 
14 
15 class PreJetAnalysisConfig (ConfigBlock) :
16  """the ConfigBlock for the common preprocessing of jet sequences"""
17 
18  def __init__ (self) :
19  super (PreJetAnalysisConfig, self).__init__ ()
20  self.addOption ('containerName', '', type=str,
21  noneAction='error',
22  info="the name of the output container after calibration.")
23  self.addOption ('jetCollection', '', type=str,
24  noneAction='error',
25  info="the jet container to run on. It is interpreted to determine "
26  "the correct config blocks to call for small- or large-R jets.")
27  self.addOption('outputTruthLabelIDs', False, type=bool,
28  info='Enable or disable HadronConeExclTruthLabelID and PartonTruthLabelID decorations')
29  # TODO: add info string
30  self.addOption ('runOriginalObjectLink', False, type=bool,
31  info="")
32  self.addOption ('runGhostMuonAssociation', None, type=bool,
33  info="whether to set up the jet-ghost-muon association algorithm "
34  "CP::JetGhostMuonAssociationAlg. The default is True for non-PHYSLITE and False for PHYSLITE.")
35  self.addOption ('runTruthJetTagging', None, type=bool,
36  info="whether to set up the jet truth tagging algorithm "
37  "CP::JetTruthTagAlg. The default is True.")
38 
39  def instanceName (self) :
40  """Return the instance name for this block"""
41  return self.containerName
42 
43  def makeAlgs (self, config) :
44 
45 
46  if config.isPhyslite() and self.jetCollection == 'AntiKt4EMPFlowJets' :
47  config.setSourceName (self.containerName, "AnalysisJets", originalName = self.jetCollection)
48  elif config.isPhyslite() and self.jetCollection == 'AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets' :
49  config.setSourceName (self.containerName, "AnalysisLargeRJets", originalName = self.jetCollection)
50  else :
51  config.setSourceName (self.containerName, self.jetCollection, originalName = self.jetCollection)
52 
53  # Relink original jets in case of b-tagging calibration
54  if self.runOriginalObjectLink :
55  alg = config.createAlgorithm( 'CP::AsgOriginalObjectLinkAlg',
56  'JetOriginalObjectLinkAlg',
57  reentrant=True )
58  alg.baseContainerName = self.jetCollection
59  alg.particles = config.readName (self.containerName)
60  if config.wantCopy (self.containerName) :
61  alg.particlesOut = config.copyName (self.containerName)
62  alg.preselection = config.getPreselection (self.containerName, '')
63 
64  # Set up the jet ghost muon association algorithm:
65  if (self.runGhostMuonAssociation is None and not config.isPhyslite()) or \
66  (self.runGhostMuonAssociation is True):
67  alg = config.createAlgorithm( 'CP::JetGhostMuonAssociationAlg',
68  'JetGhostMuonAssociationAlg' )
69  alg.jets = config.readName (self.containerName)
70  if config.isPhyslite():
71  alg.muons = "AnalysisMuons"
72  if config.wantCopy (self.containerName) :
73  alg.jetsOut = config.copyName (self.containerName)
74 
75  # NB: I'm assuming that the truth tagging is done in PHYSLITE, if not this will
76  # need to change
77  if self.runTruthJetTagging or (
78  self.runTruthJetTagging is None
79  and config.dataType() is not DataType.Data
80  ):
81  # Decorate jets with isHS labels (required to retrieve Jvt SFs)
82  alg = config.createAlgorithm( 'CP::JetDecoratorAlg', 'JetPileupLabelAlg' )
83  config.addPrivateTool( 'decorator', 'JetPileupLabelingTool' )
84  alg.jets = config.readName (self.containerName)
85  alg.jetsOut = config.copyName (self.containerName)
86  alg.decorator.RecoJetContainer = alg.jetsOut.replace ('%SYS%', 'NOSYS')
87  alg.decorator.SuppressOutputDependence=True
88 
89  # Set up shallow copy if needed and not yet done
90  if config.wantCopy (self.containerName) :
91  alg = config.createAlgorithm( 'CP::AsgShallowCopyAlg', 'JetShallowCopyAlg' )
92  alg.input = config.readName (self.containerName)
93  alg.output = config.copyName (self.containerName)
94 
95  config.addOutputVar (self.containerName, 'pt', 'pt')
96  config.addOutputVar (self.containerName, 'eta', 'eta', noSys=True)
97  config.addOutputVar (self.containerName, 'phi', 'phi', noSys=True)
98  config.addOutputVar (self.containerName, 'charge', 'charge', noSys=True, enabled=False)
99 
100  if self.outputTruthLabelIDs and config.dataType() is not DataType.Data:
101  config.addOutputVar (self.containerName, 'HadronConeExclTruthLabelID', 'HadronConeExclTruthLabelID', noSys=True)
102  config.addOutputVar (self.containerName, 'PartonTruthLabelID', 'PartonTruthLabelID', noSys=True)
103 
104 
105 
106 class SmallRJetAnalysisConfig (ConfigBlock) :
107  """the ConfigBlock for the small-r jet sequence"""
108 
109  def __init__ (self) :
110  super (SmallRJetAnalysisConfig, self).__init__ ()
111  self.addOption ('containerName', '', type=str,
112  noneAction='error',
113  info="the name of the output container after calibration.")
114  self.addOption ('jetCollection', '', type=str,
115  noneAction='error',
116  info="the jet container to run on. It is interpreted to determine "
117  "the correct config blocks to call for small- or large-R jets.")
118  # TODO: add info string
119  self.addOption ('jetInput', '', type=str,
120  noneAction='error',
121  info="")
122  self.addOption ('runJvtUpdate', False, type=bool,
123  info="whether to update the JVT. The default is False.")
124  self.addOption ('runNNJvtUpdate', False, type=bool,
125  info="whether to update the NN-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 "
143  "default is Full.")
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.")
149  # Calibration tool options
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 "
153  "default is None.")
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 "
157  "default is None.")
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.")
162  # Uncertainties tool options
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 "
166  "default is None.")
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 "
170  "default is None.")
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.")
175 
176  def instanceName (self) :
177  """Return the instance name for this block"""
178  return self.containerName
179 
180  def getUncertaintyToolSettings(self, config):
181 
182  # Retrieve appropriate JES/JER recommendations for the JetUncertaintiesTool.
183  # We do this separately from the tool declaration, as we may need to set uo
184  # two such tools, but they have to be private.
185 
186  # Config file:
187  config_file = None
188  if self.systematicsModelJES == "All" and self.systematicsModelJER == "All":
189  config_file = "R4_AllNuisanceParameters_AllJERNP.config"
190  elif "Scenario" in self.systematicsModelJES:
191  if self.systematicsModelJER != "Simple":
192  raise ValueError(
193  "Invalid uncertainty configuration - Scenario* systematicsModelJESs can "
194  "only be used together with the Simple systematicsModelJER")
195  config_file = "R4_{0}_SimpleJER.config".format(self.systematicsModelJES)
196  elif self.systematicsModelJES in ["Global", "Category"] and self.systematicsModelJER in ["Simple", "Full"]:
197  config_file = "R4_{0}Reduction_{1}JER.config".format(self.systematicsModelJES, self.systematicsModelJER)
198  else:
199  raise ValueError(
200  "Invalid combination of systematicsModelJES and systematicsModelJER settings: "
201  "systematicsModelJES: {0}, systematicsModelJER: {1}".format(self.systematicsModelJES, self.systematicsModelJER) )
202 
203  # Calibration area:
204  calib_area = None
205  if self.uncertToolCalibArea is not None:
206  calib_area = self.uncertToolCalibArea
207 
208  # Expert override for config path:
209  if self.uncertToolConfigPath is not None:
210  config_file = self.uncertToolConfigPath
211  else:
212  if config.geometry() is LHCPeriod.Run2:
213  if config.dataType() is DataType.FastSim:
214  config_file = "rel22/Fall2024_PreRec/" + config_file
215  else:
216  if self.jetInput == "HI":
217  config_file = "HIJetUncertainties/Spring2023/HI" + config_file
218  else:
219  config_file = "rel22/Summer2023_PreRec/" + config_file
220  else:
221  if config.dataType() is DataType.FastSim:
222  config_file = "rel22/Winter2025_AF3_PreRec/" + config_file
223  else:
224  if self.jetInput == "HI":
225  config_file = "HIJetUncertainties/Spring2023/HI" + config_file
226  else:
227  config_file = "rel22/Winter2025_PreRec/" + config_file
228 
229  # MC type:
230  mc_type = None
231  if self.uncertToolMCType is not None:
232  mc_type = self.uncertToolMCType
233  else:
234  if config.geometry() is LHCPeriod.Run2:
235  if config.dataType() is DataType.FastSim:
236  mc_type = "AF3"
237  else:
238  mc_type = "MC20"
239  else:
240  if config.dataType() is DataType.FastSim:
241  mc_type = "MC23AF3"
242  else:
243  if self.jetInput == "HI":
244  mc_type = "MC16"
245  else:
246  mc_type = "MC23"
247 
248  return config_file, calib_area, mc_type
249 
250 
251  def createUncertaintyTool(self, jetUncertaintiesAlg, config, jetCollectionName, doPseudoData=False):
252 
253  # Create an instance of JetUncertaintiesTool, following JetETmiss recommendations.
254  # To run Jet Energy Resolution (JER) uncertainties in the "Full" or "All" schemes,
255  # we need two sets of tools: one configured as normal (MC), the other with the
256  # exact same settings but pretending to run on data (pseudo-data).
257  # This is achieved by passing "isPseudoData=True" to the arguments.
258 
259  # Retrieve the common configuration settings
260  configFile, calibArea, mcType = self.getUncertaintyToolSettings(config)
261 
262  # The main tool for all JES+JER combinations
263  config.addPrivateTool( 'uncertaintiesTool', 'JetUncertaintiesTool' )
264  jetUncertaintiesAlg.uncertaintiesTool.JetDefinition = jetCollectionName[:-4]
265  jetUncertaintiesAlg.uncertaintiesTool.ConfigFile = configFile
266  if calibArea is not None:
267  jetUncertaintiesAlg.uncertaintiesTool.CalibArea = calibArea
268  jetUncertaintiesAlg.uncertaintiesTool.MCType = mcType
269  jetUncertaintiesAlg.uncertaintiesTool.IsData = (config.dataType() is DataType.Data)
270  jetUncertaintiesAlg.uncertaintiesTool.PseudoDataJERsmearingMode = False
271 
272  if config.dataType() is DataType.Data and not (doPseudoData and self.runJERsystematicsOnData):
273  # we don't want any systematics on data if we're not using the right JER model!
274  jetUncertaintiesAlg.affectingSystematicsFilter = '.*'
275  if config.dataType() is not DataType.Data and doPseudoData and not self.runJERsystematicsOnData:
276  # The secondary tool for pseudo-data JER smearing
277  config.addPrivateTool( 'uncertaintiesToolPD', 'JetUncertaintiesTool' )
278  jetUncertaintiesAlg.uncertaintiesToolPD.JetDefinition = jetCollectionName[:-4]
279  jetUncertaintiesAlg.uncertaintiesToolPD.ConfigFile = configFile
280  if calibArea is not None:
281  jetUncertaintiesAlg.uncertaintiesToolPD.CalibArea = calibArea
282  jetUncertaintiesAlg.uncertaintiesToolPD.MCType = mcType
283 
284  # This is the part that is different!
285  jetUncertaintiesAlg.uncertaintiesToolPD.IsData = True
286  jetUncertaintiesAlg.uncertaintiesToolPD.PseudoDataJERsmearingMode = True
287 
288 
289  def makeAlgs (self, config) :
290 
291  jetCollectionName=self.jetCollection
292  if(self.jetCollection=="AnalysisJets") :
293  jetCollectionName="AntiKt4EMPFlowJets"
294  if(self.jetCollection=="AnalysisLargeRJets") :
295  jetCollectionName="AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets"
296 
297  if self.jetInput not in ["EMTopo", "EMPFlow", "HI"]:
298  raise ValueError(
299  "Unsupported input type '{0}' for R=0.4 jets!".format(self.jetInput) )
300 
301  if self.jvtWP not in ["FixedEffPt"]:
302  raise ValueError(
303  "Unsupported NNJvt WP '{0}'".format(self.jvtWP) )
304 
305  if self.fJvtWP not in ["Loose", "Tight", "Tighter"]:
306  raise ValueError(
307  "Unsupported fJvt WP '{0}'".format(self.fJvtWP) )
308 
309  if not config.isPhyslite() or self.recalibratePhyslite:
310  # Prepare the jet calibration algorithm
311  alg = config.createAlgorithm( 'CP::JetCalibrationAlg', 'JetCalibrationAlg' )
312  config.addPrivateTool( 'calibrationTool', 'JetCalibrationTool' )
313  alg.calibrationTool.JetCollection = jetCollectionName[:-4]
314  # Get the correct string to use in the config file name
315  if self.jetInput == "EMPFlow":
316  if config.geometry() is LHCPeriod.Run2:
317  configFile = "PreRec_R22_PFlow_ResPU_EtaJES_GSC_February23_230215.config"
318  alg.calibrationTool.CalibArea = "00-04-82"
319  elif config.geometry() >= LHCPeriod.Run3:
320  configFile = "AntiKt4EMPFlow_MC23a_PreRecR22_Phase2_CalibConfig_ResPU_EtaJES_GSC_241208_InSitu.config"
321  alg.calibrationTool.CalibArea = "00-04-83"
322  elif self.jetInput == "HI":
323  if config.geometry() is LHCPeriod.Run2:
324  configFile = "JES_MC16_HI_Jan2021_5TeV.config"
325  if config.geometry() is LHCPeriod.Run3:
326  configFile = "AntiKt4HI_JES_constants_11-05-2024_13p6TeVFinalConfiguration.config"
327  alg.calibrationTool.CalibArea = "00-04-83"
328  else:
329  if config.dataType() is DataType.FastSim:
330  configFile = "JES_MC16Recommendation_AFII_{0}_Apr2019_Rel21.config"
331  else:
332  configFile = "JES_MC16Recommendation_Consolidated_{0}_Apr2019_Rel21.config"
333  configFile = configFile.format(self.jetInput)
334  if self.calibToolCalibArea is not None:
335  alg.calibrationTool.CalibArea = self.calibToolCalibArea
336  if self.calibToolConfigFile is not None:
337  configFile = self.calibToolConfigFile
338  alg.calibrationTool.ConfigFile = configFile
339  if config.dataType() is DataType.Data:
340  if self.jetInput == "HI":
341  if config.geometry() is LHCPeriod.Run2:
342  alg.calibrationTool.CalibSequence = 'EtaJES_Insitu'
343  if config.geometry() is LHCPeriod.Run3:
344  alg.calibrationTool.CalibSequence = 'EtaJES'
345  else:
346  alg.calibrationTool.CalibSequence = 'JetArea_Residual_EtaJES_GSC_Insitu'
347  else:
348  if self.jetInput == "EMPFlow":
349  alg.calibrationTool.CalibSequence = 'JetArea_Residual_EtaJES_GSC'
350  elif self.jetInput == "HI":
351  alg.calibrationTool.CalibSequence = 'EtaJES'
352  else:
353  alg.calibrationTool.CalibSequence = 'JetArea_Residual_EtaJES_GSC_Smear'
354  if self.calibToolCalibSeq is not None:
355  alg.calibrationTool.CalibSequence = self.calibToolCalibSeq
356  alg.calibrationTool.IsData = (config.dataType() is DataType.Data)
357  alg.jets = config.readName (self.containerName)
358  alg.jetsOut = config.copyName (self.containerName)
359 
360  # Jet uncertainties
361  alg = config.createAlgorithm( 'CP::JetUncertaintiesAlg', 'JetUncertaintiesAlg' )
362  self.createUncertaintyTool(alg, config, jetCollectionName, doPseudoData=( self.systematicsModelJER in ["Full","All"] ))
363  alg.jets = config.readName (self.containerName)
364  alg.jetsOut = config.copyName (self.containerName)
365  alg.preselection = config.getPreselection (self.containerName, '')
366 
367  # Set up the JVT update algorithm:
368  if self.runJvtUpdate :
369  alg = config.createAlgorithm( 'CP::JvtUpdateAlg', 'JvtUpdateAlg' )
370  config.addPrivateTool( 'jvtTool', 'JetVertexTaggerTool' )
371  alg.jvtTool.JetContainer = self.jetCollection
372  alg.jvtTool.SuppressInputDependence=True
373  alg.jets = config.readName (self.containerName)
374  alg.jetsOut = config.copyName (self.containerName)
375  alg.preselection = config.getPreselection (self.containerName, '')
376 
377  if self.runNNJvtUpdate:
378  assert self.jetInput=="EMPFlow", "NN JVT only defined for PFlow jets"
379  alg = config.createAlgorithm( 'CP::JetDecoratorAlg', 'NNJvtUpdateAlg' )
380  config.addPrivateTool( 'decorator', 'JetPileupTag::JetVertexNNTagger' )
381  # Set this actually to the *output* collection
382  alg.jets = config.readName (self.containerName)
383  alg.jetsOut = config.copyName (self.containerName)
384  alg.decorator.JetContainer = alg.jetsOut.replace ('%SYS%', 'NOSYS')
385  alg.decorator.SuppressInputDependence=True
386  alg.decorator.SuppressOutputDependence=True
387 
388  # Set up the jet efficiency scale factor calculation algorithm
389  # Change the truthJetCollection property to AntiKt4TruthWZJets if preferred
390  if self.runJvtSelection :
391  assert self.jetInput=="EMPFlow", "NNJvt WPs and SFs only valid for PFlow jets"
392  alg = config.createAlgorithm('CP::AsgSelectionAlg', 'JvtSelectionAlg')
393  config.addPrivateTool('selectionTool', 'CP::NNJvtSelectionTool')
394  alg.selectionTool.JetContainer = config.readName(self.containerName)
395  alg.selectionTool.WorkingPoint = self.jvtWP
396  alg.selectionTool.MaxPtForJvt = 60*GeV
397  alg.selectionDecoration = "jvt_selection,as_char"
398  alg.particles = config.readName(self.containerName)
399 
400  if self.runJvtEfficiency and config.dataType() is not DataType.Data:
401  alg = config.createAlgorithm( 'CP::JvtEfficiencyAlg', 'JvtEfficiencyAlg' )
402  config.addPrivateTool( 'efficiencyTool', 'CP::NNJvtEfficiencyTool' )
403  alg.efficiencyTool.JetContainer = config.readName(self.containerName)
404  alg.efficiencyTool.MaxPtForJvt = 60*GeV
405  alg.efficiencyTool.WorkingPoint = self.jvtWP
406  if config.geometry() is LHCPeriod.Run2:
407  alg.efficiencyTool.SFFile = "JetJvtEfficiency/May2024/NNJvtSFFile_Run2_EMPFlow.root"
408  else:
409  alg.efficiencyTool.SFFile = "JetJvtEfficiency/May2024/NNJvtSFFile_Run3_EMPFlow.root"
410  alg.selection = 'jvt_selection,as_char'
411  alg.scaleFactorDecoration = 'jvt_effSF_%SYS%'
412  alg.outOfValidity = 2
413  alg.outOfValidityDeco = 'no_jvt'
414  alg.skipBadEfficiency = False
415  alg.jets = config.readName (self.containerName)
416  alg.preselection = config.getPreselection (self.containerName, '')
417  config.addOutputVar (self.containerName, alg.scaleFactorDecoration, 'jvtEfficiency')
418  config.addSelection (self.containerName, 'baselineJvt', 'jvt_selection,as_char', preselection=False)
419 
420  if self.runFJvtSelection :
421  assert self.jetInput=="EMPFlow", "fJvt WPs and SFs only valid for PFlow jets"
422  alg = config.createAlgorithm('CP::AsgSelectionAlg', 'FJvtSelectionAlg')
423  config.addPrivateTool('selectionTool', 'CP::FJvtSelectionTool')
424  alg.selectionTool.JetContainer = config.readName(self.containerName)
425  alg.selectionTool.WorkingPoint = self.fJvtWP
426  alg.selectionDecoration = "fjvt_selection,as_char"
427  alg.particles = config.readName(self.containerName)
428 
429  if self.runFJvtEfficiency and config.dataType() is not DataType.Data:
430  alg = config.createAlgorithm( 'CP::JvtEfficiencyAlg', 'FJvtEfficiencyAlg' )
431  config.addPrivateTool( 'efficiencyTool', 'CP::FJvtEfficiencyTool' )
432  alg.efficiencyTool.JetContainer = config.readName(self.containerName)
433  alg.efficiencyTool.WorkingPoint = self.fJvtWP
434  if config.geometry() is LHCPeriod.Run2:
435  alg.efficiencyTool.SFFile = "JetJvtEfficiency/May2024/fJvtSFFile_Run2_EMPFlow.root"
436  else:
437  alg.efficiencyTool.SFFile = "JetJvtEfficiency/May2024/fJvtSFFile_Run3_EMPFlow.root"
438  alg.selection = 'fjvt_selection,as_char'
439  alg.scaleFactorDecoration = 'fjvt_effSF_%SYS%'
440  alg.outOfValidity = 2
441  alg.outOfValidityDeco = 'no_fjvt'
442  alg.skipBadEfficiency = False
443  alg.jets = config.readName (self.containerName)
444  alg.preselection = config.getPreselection (self.containerName, '')
445  config.addOutputVar (self.containerName, alg.scaleFactorDecoration, 'fjvtEfficiency')
446  config.addSelection (self.containerName, 'baselineFJvt', 'fjvt_selection,as_char', preselection=False)
447 
448  # Additional decorations
449  alg = config.createAlgorithm( 'CP::AsgEnergyDecoratorAlg', 'AsgEnergyDecoratorAlg' )
450  alg.particles = config.readName (self.containerName)
451 
452  config.addOutputVar (self.containerName, 'e_%SYS%', 'e')
453 
454 
455 class RScanJetAnalysisConfig (ConfigBlock) :
456  """the ConfigBlock for the r-scan jet sequence"""
457 
458  def __init__ (self) :
459  super (RScanJetAnalysisConfig, self).__init__ ()
460  self.addOption ('containerName', '', type=str,
461  noneAction='error',
462  info="the name of the output container after calibration.")
463  self.addOption ('jetCollection', '', type=str,
464  noneAction='error',
465  info="the jet container to run on. It is interpreted to determine "
466  "the correct config blocks to call for small- or large-R jets.")
467  # TODO: add info string
468  self.addOption ('jetInput', '', type=str,
469  noneAction='error',
470  info="")
471  # TODO: add info string
472  self.addOption ('radius', None, type=int,
473  noneAction='error',
474  info="")
475  self.addOption ('recalibratePhyslite', True, type=bool,
476  info="whether to run the CP::JetCalibrationAlg on PHYSLITE "
477  "derivations. The default is True.")
478 
479  def instanceName (self) :
480  """Return the instance name for this block"""
481  return self.containerName
482 
483  def makeAlgs (self, config) :
484 
485  log = logging.getLogger('RScanJetAnalysisConfig')
486 
487  jetCollectionName=self.jetCollection
488  if(self.jetCollection=="AnalysisJets") :
489  jetCollectionName="AntiKt4EMPFlowJets"
490  if(self.jetCollection=="AnalysisLargeRJets") :
491  jetCollectionName="AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets"
492 
493  if not config.isPhyslite() or self.recalibratePhyslite:
494  if self.jetInput != "LCTopo":
495  raise ValueError(
496  "Unsupported input type '{0}' for R-scan jets!".format(self.jetInput) )
497  # Prepare the jet calibration algorithm
498  alg = config.createAlgorithm( 'CP::JetCalibrationAlg', 'JetCalibrationAlg' )
499  config.addPrivateTool( 'calibrationTool', 'JetCalibrationTool' )
500  alg.calibrationTool.JetCollection = jetCollectionName[:-4]
501  alg.calibrationTool.ConfigFile = \
502  "JES_MC16Recommendation_Rscan{0}LC_Feb2022_R21.config".format(self.radius)
503  if config.dataType() is DataType.Data:
504  alg.calibrationTool.CalibSequence = "JetArea_Residual_EtaJES_GSC_Insitu"
505  else:
506  alg.calibrationTool.CalibSequence = "JetArea_Residual_EtaJES_GSC_Smear"
507  alg.calibrationTool.IsData = (config.dataType() is DataType.Data)
508  alg.jets = config.readName (self.containerName)
509  # Logging would be good
510  log.warning("Uncertainties for R-Scan jets are not yet released!")
511 
512 
513 def _largeLCTopoConfigFile(config, self):
514  is_sim = config.dataType() in {DataType.FullSim}
515  if self.largeRMass == "Comb":
516  if config.dataType() is DataType.Data:
517  return "JES_MC16recommendation_FatJet_Trimmed_JMS_comb_March2021.config"
518  if is_sim:
519  return "JES_MC16recommendation_FatJet_Trimmed_JMS_comb_17Oct2018.config"
520  elif self.largeRMass == "Calo":
521  if config.dataType() is DataType.Data:
522  return "JES_MC16recommendation_FatJet_Trimmed_JMS_comb_March2021.config"
523  if is_sim:
524  return "JES_MC16recommendation_FatJet_Trimmed_JMS_calo_12Oct2018.config "
525  elif self.largeRMass == "TA":
526  if config.dataType() is DataType.Data:
527  return "JES_MC16recommendation_FatJet_Trimmed_JMS_comb_March2021.config"
528  if is_sim:
529  return "JES_MC16recommendation_FatJet_Trimmed_JMS_TA_12Oct2018.config"
530  return None
531 
532 
533 class LargeRJetAnalysisConfig (ConfigBlock) :
534  """the ConfigBlock for the large-r jet sequence"""
535 
536  def __init__ (self) :
537  super (LargeRJetAnalysisConfig, self).__init__ ()
538  self.addOption ('containerName', '', type=str,
539  noneAction='error',
540  info="the name of the output container after calibration.")
541  self.addOption ('jetCollection', '', type=str,
542  noneAction='error',
543  info="the jet container to run on. It is interpreted to determine "
544  "the correct config blocks to call for small- or large-R jets.")
545  # TODO: add info string
546  self.addOption ('jetInput', '', type=str,
547  noneAction='error',
548  info="")
549  # TODO: add info string
550  self.addOption ('largeRMass', "Comb", type=str,
551  info="")
552  self.addOption ('recalibratePhyslite', True, type=bool,
553  info="whether to run the CP::JetCalibrationAlg on PHYSLITE "
554  "derivations. The default is True.")
555  self.addOption ('systematicsModelJER', "Full", type=str)
556  self.addOption ('systematicsModelJMS', "Full", type=str)
557  self.addOption ('systematicsModelJMR', "Full", type=str,
558  info="the NP reduction scheme to use for JMR: Full, Simple. The default is Full.")
559  self.addOption ('runJERsystematicsOnData', False, type=bool,
560  info="whether to run the All/Full JER model variations also on data samples. Expert option!")
561  # Adding these options to override the jet uncertainty config file when we have new recommendations
562  # Calibration tool options
563  self.addOption ('calibToolConfigFile', None, type=str,
564  info="name (str) of the config file to use for the jet calibration "
565  "tool. Expert option to override JetETmiss recommendations. The "
566  "default is None.")
567  self.addOption ('calibToolCalibArea', None, type=str,
568  info="name (str) of the CVMFS area to use for the jet calibration "
569  "tool. Expert option to override JetETmiss recommendations. The "
570  "default is None.")
571  self.addOption ('calibToolCalibSeq', None, type=str,
572  info="name (str) of the sequence to use for the jet calibration "
573  "tool (e.g. 'JetArea_Residual_EtaJES_GSC'). Expert option to override "
574  "JetETmiss recommendations. The default is None.")
575  # Uncertainties tool options
576  self.addOption ('uncertToolConfigPath', None, type=str,
577  info="name (str) of the config file to use for the JES, JER, and JMS uncertainty "
578  "tool. Expert option to override JetETmiss recommendations. The "
579  "default is None.")
580  self.addOption ('uncertToolConfigPathJMR', None, type=str,
581  info="name (str) of the config file to use for the JMR uncertainty "
582  "tool. Expert option to override JetETmiss recommendations. The "
583  "default is None.")
584  self.addOption ('uncertToolCalibArea', None, type=str,
585  info="name (str) of the CVMFS area to use for the jet uncertainty "
586  "tool. Expert option to override JetETmiss recommendations. The "
587  "default is None.")
588  self.addOption ('uncertToolMCType', None, type=str,
589  info="data type (str) to use for the jet uncertainty tool (e.g. "
590  "'AF3' or 'MC16'). Expert option to override JetETmiss "
591  "recommendations. The default is None.")
592  self.addOption ('minPt', 200.*GeV, type=float,
593  info="the minimum pt cut to apply to calibrated large-R jets. "
594  "The default is 200 GeV.")
595  self.addOption ('maxPt', 3000.*GeV, type=float,
596  info="the maximum pt cut to apply to calibrated large-R jets. "
597  "The default is 3000 GeV.")
598  self.addOption ('maxEta', 0., type=float,
599  info="the maximum |eta| cut to apply to calibrated large-R jets. "
600  "The default is 0.")
601  self.addOption ('maxRapidity', 2., type=float,
602  info="the maximum rapidity cut to apply to calibrated large-R jets. "
603  "The default is 2.")
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.")
610 
611  def instanceName (self) :
612  """Return the instance name for this block"""
613  return self.containerName
614 
615  def getUncertaintyToolSettings(self, config):
616  # Retrieve appropriate JES/JER recommendations for the JetUncertaintiesTool.
617  # We do this separately from the tool declaration, as we may need to set uo
618  # two such tools, but they have to be private.
619 
620  log = logging.getLogger('LargeRJetAnalysisConfig')
621 
622  # Config file:
623  config_file = None
624  if self.systematicsModelJER in ["Simple", "Full"] and self.systematicsModelJMS in ["Simple", "Full"]:
625  config_file = "R10_CategoryJES_{0}JER_{1}JMS.config".format(self.systematicsModelJER, self.systematicsModelJMS)
626  else:
627  raise ValueError(
628  "Invalid request for systematicsModelJER/JMS settings: "
629  "systematicsModelJER = '{0}', "
630  "systematicsModelJMS = '{1}'".format(self.systematicsModelJER, self.systematicsModelJMS) )
631  if self.uncertToolConfigPath is not None:
632  # Expert override
633  config_file = self.uncertToolConfigPath
634  else:
635  if config.geometry() in [LHCPeriod.Run2, LHCPeriod.Run3]:
636  config_file = "rel22/Summer2025_PreRec/" + config_file
637  else:
638  log.warning("Uncertainties for UFO jets are not for Run 4!")
639 
640  # Calibration area:
641  calib_area = None
642  if self.uncertToolCalibArea is not None:
643  calib_area = self.uncertToolCalibArea
644 
645  # MC type:
646  if self.uncertToolMCType is not None:
647  mc_type = self.uncertToolMCType
648  else:
649  if config.dataType() is DataType.FastSim:
650  if config.geometry() is LHCPeriod.Run2:
651  mc_type = "MC20AF3"
652  else:
653  mc_type = "MC23AF3"
654  else:
655  if config.geometry() is LHCPeriod.Run2:
656  mc_type = "MC20"
657  else:
658  mc_type = "MC23"
659 
660  return config_file, calib_area, mc_type
661 
662  def createUncertaintyTool(self, jetUncertaintiesAlg, config, jetCollectionName, doPseudoData=False):
663  '''
664  Create instance(s) of JetUncertaintiesTool following JetETmiss recommendations.
665 
666  JER uncertainties under the "Full" scheme must be run on MC samples twice:
667  1. Normal (MC) mode,
668  2. Pseudodata (PD) mode, as if the events are Data.
669  '''
670 
671  # Retrieve the common configuration settings
672  configFile, calibArea, mcType = self.getUncertaintyToolSettings(config)
673 
674  # The main tool for all JER combinations
675  config.addPrivateTool( 'uncertaintiesTool', 'JetUncertaintiesTool' )
676  jetUncertaintiesAlg.uncertaintiesTool.JetDefinition = jetCollectionName[:-4]
677  jetUncertaintiesAlg.uncertaintiesTool.ConfigFile = configFile
678  if calibArea is not None:
679  jetUncertaintiesAlg.uncertaintiesTool.CalibArea = calibArea
680  jetUncertaintiesAlg.uncertaintiesTool.MCType = mcType
681  jetUncertaintiesAlg.uncertaintiesTool.IsData = (config.dataType() is DataType.Data)
682  jetUncertaintiesAlg.uncertaintiesTool.PseudoDataJERsmearingMode = False
683 
684  # JER smearing on data
685  if config.dataType() is DataType.Data and not (config.isPhyslite() and doPseudoData and self.runJERsystematicsOnData):
686  # we don't want any systematics on data if we're not using the right JER model!
687  jetUncertaintiesAlg.affectingSystematicsFilter = '.*'
688 
689  if config.dataType() is not (DataType.Data and config.isPhyslite()) and doPseudoData and not self.runJERsystematicsOnData:
690  # The secondary tool for pseudo-data JER smearing
691  config.addPrivateTool( 'uncertaintiesToolPD', 'JetUncertaintiesTool' )
692  jetUncertaintiesAlg.uncertaintiesToolPD.JetDefinition = jetCollectionName[:-4]
693  jetUncertaintiesAlg.uncertaintiesToolPD.ConfigFile = configFile
694  if calibArea is not None:
695  jetUncertaintiesAlg.uncertaintiesToolPD.CalibArea = calibArea
696  jetUncertaintiesAlg.uncertaintiesToolPD.MCType = mcType
697  jetUncertaintiesAlg.uncertaintiesToolPD.IsData = True
698  jetUncertaintiesAlg.uncertaintiesToolPD.PseudoDataJERsmearingMode = True
699 
700  def createFFSmearingTool(self, jetFFSmearingAlg, config):
701  # Retrieve appropriate large-R jet mass resolution recommendations for the FFJetSmearingTool.
702 
703  log = logging.getLogger('LargeRJetAnalysisConfig')
704 
705  # Config file:
706  if self.systematicsModelJMR in ["Simple", "Full"]:
707  config_file = f"R10_{self.systematicsModelJMR}JMR.config"
708  else:
709  raise ValueError(
710  f"Invalid request for systematicsModelJMR settings: {self.systematicsModelJMR}"
711  )
712 
713  # Expert override for config path:
714  if self.uncertToolConfigPathJMR is not None:
715  config_file = self.uncertToolConfigPathJMR
716  else:
717  if config.geometry() in [LHCPeriod.Run2, LHCPeriod.Run3]:
718  config_file = "rel22/Summer2025_PreRec/" + config_file
719  else:
720  log.warning("Uncertainties for UFO jets are not for Run 4!")
721 
722  # MC type:
723  if config.geometry() is LHCPeriod.Run2:
724  if config.dataType() is DataType.FastSim:
725  mc_type = "MC20AF3"
726  else:
727  mc_type = "MC20"
728  elif config.geometry() is LHCPeriod.Run3:
729  if config.dataType() is DataType.FastSim:
730  mc_type = "MC23AF3"
731  else:
732  mc_type = "MC23"
733 
734  # Set up the FF smearing tool
735  config.addPrivateTool( 'FFSmearingTool', 'CP::FFJetSmearingTool')
736  jetFFSmearingAlg.FFSmearingTool.MassDef = "UFO"
737  jetFFSmearingAlg.FFSmearingTool.MCType = mc_type
738  jetFFSmearingAlg.FFSmearingTool.ConfigFile = config_file
739 
740  def makeAlgs (self, config) :
741 
742  configFile = None
743  calibSeq = None
744  calibArea = None
745 
746  jetCollectionName=self.jetCollection
747  if(self.jetCollection=="AnalysisJets") :
748  jetCollectionName="AntiKt4EMPFlowJets"
749  if(self.jetCollection=="AnalysisLargeRJets") :
750  jetCollectionName="AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets"
751 
752  if self.largeRMass not in ["Comb", "Calo", "TA"]:
753  raise ValueError("Invalid large-R mass defintion {0}!".format(self.largeRMass) )
754 
755  if self.jetInput not in ["LCTopo", "TrackCaloCluster", "UFO"]:
756  raise ValueError("Invalid input type '{0}' for large-R jets!".format(self.jetInput) )
757 
758  if self.jetInput == "TrackCaloCluster":
759  # Only one mass defintion supported
760  if self.largeRMass != "Calo":
761  raise ValueError("Invalid large-R TCC jet mass '{0}'!".format(self.largeRMass) )
762  configFile = "JES_MC16recommendation_FatJet_TCC_JMS_calo_30Oct2018.config"
763  if self.jetInput == "LCTopo":
764  configFile = _largeLCTopoConfigFile(config, self)
765  if self.jetInput == "UFO":
766  configFile = "JES_MC20PreRecommendation_R10_UFO_CSSK_SoftDrop_JMS_R21Insitu_26Nov2024.config"
767  calibArea = "00-04-83"
768  if self.calibToolConfigFile is not None:
769  configFile = self.calibToolConfigFile
770 
771  if self.jetInput == "TrackCaloCluster" or self.jetInput == "UFO" or config.dataType() is DataType.FullSim:
772  calibSeq = "EtaJES_JMS"
773  elif config.dataType() is DataType.Data:
774  calibSeq = "EtaJES_JMS_Insitu"
775  if self.calibToolCalibSeq is not None:
776  calibSeq = self.calibToolCalibSeq
777 
778  if self.calibToolCalibArea is not None:
779  calibArea = self.calibToolCalibArea
780 
781  if not config.isPhyslite() or self.recalibratePhyslite:
782  # Prepare the jet calibration algorithm
783  alg = config.createAlgorithm( 'CP::JetCalibrationAlg', 'JetCalibrationAlg' )
784  config.addPrivateTool( 'calibrationTool', 'JetCalibrationTool' )
785 
786  alg.calibrationTool.JetCollection = jetCollectionName[:-4]
787 
788  if configFile is None:
789  raise ValueError(f'Unsupported: {self.jetInput=}, {config.dataType()=}')
790  alg.calibrationTool.ConfigFile = configFile
791 
792  if calibSeq is None:
793  raise ValueError(f'Unsupported: {self.jetInput=}, {config.dataType()=}')
794  alg.calibrationTool.CalibSequence = calibSeq
795 
796  if calibArea is not None:
797  alg.calibrationTool.CalibArea = calibArea
798 
799  alg.calibrationTool.IsData = (config.dataType() is DataType.Data)
800  alg.jets = config.readName(self.containerName)
801 
802  # Jet uncertainties
803  if self.jetInput == "UFO" and config.dataType() in [DataType.FullSim, DataType.FastSim]:
804  alg = config.createAlgorithm( 'CP::JetUncertaintiesAlg', 'JetUncertaintiesAlg' )
805  self.createUncertaintyTool(alg, config, jetCollectionName, doPseudoData=( self.systematicsModelJER in ["Full","All"] ))
806 
807  alg.uncertaintiesTool.JetDefinition = jetCollectionName[:-4]
808 
809  # R=1.0 jets have a validity range
810  alg.outOfValidity = 2 # SILENT
811  alg.outOfValidityDeco = 'outOfValidity'
812 
813  alg.jets = config.readName (self.containerName)
814  alg.jetsOut = config.copyName (self.containerName)
815  alg.preselection = config.getPreselection (self.containerName, '')
816 
817  if self.jetInput != "UFO":
818  alg = config.createAlgorithm( 'CP::JetUncertaintiesAlg', 'JetUncertaintiesAlg' )
819 
820  # R=1.0 jets have a validity range
821  alg.outOfValidity = 2 # SILENT
822  alg.outOfValidityDeco = 'outOfValidity'
823  config.addPrivateTool( 'uncertaintiesTool', 'JetUncertaintiesTool' )
824 
825  alg.uncertaintiesTool.JetDefinition = jetCollectionName[:-4]
826  alg.uncertaintiesTool.ConfigFile = \
827  "rel21/Moriond2018/R10_{0}Mass_all.config".format(self.largeRMass)
828  alg.uncertaintiesTool.MCType = "MC16a"
829  alg.uncertaintiesTool.IsData = (config.dataType() is DataType.Data)
830 
831  alg.jets = config.readName (self.containerName)
832  alg.jetsOut = config.copyName (self.containerName)
833  alg.preselection = config.getPreselection (self.containerName, '')
834  config.addSelection (self.containerName, '', 'outOfValidity')
835 
836  if self.jetInput == "UFO" and config.dataType() is not DataType.Data:
837  # set up the FF smearing algorithm
838  alg = config.createAlgorithm( 'CP::JetFFSmearingAlg', 'JetFFSmearingAlg' )
839  self.createFFSmearingTool(alg, config)
840  alg.outOfValidity = 2 # SILENT
841  alg.outOfValidityDeco = 'outOfValidityJMR'
842  alg.jets = config.readName (self.containerName)
843  alg.jetsOut = config.copyName (self.containerName)
844  alg.preselection = config.getPreselection (self.containerName, '')
845 
846  if self.minPt > 0 or self.maxPt > 0 or self.maxEta > 0 or self.maxRapidity > 0:
847  # Set up the the pt-eta selection
848  alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'JetPtEtaCutAlg' )
849  alg.selectionDecoration = 'selectPtEta,as_bits'
850  config.addPrivateTool( 'selectionTool', 'CP::AsgPtEtaSelectionTool' )
851  alg.selectionTool.minPt = self.minPt
852  alg.selectionTool.maxPt = self.maxPt
853  alg.selectionTool.maxEta = self.maxEta
854  alg.selectionTool.maxRapidity = self.maxRapidity
855  alg.particles = config.readName (self.containerName)
856  alg.preselection = config.getPreselection (self.containerName, '')
857  config.addSelection (self.containerName, '', alg.selectionDecoration,
858  preselection=True)
859 
860  if self.minMass > 0 or self.maxMass > 0:
861  # Set up the the mass selection
862  alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'JetMassCutAlg' )
863  alg.selectionDecoration = 'selectMass,as_bits'
864  config.addPrivateTool( 'selectionTool', 'CP::AsgMassSelectionTool' )
865  alg.selectionTool.minM = self.minMass
866  alg.selectionTool.maxM = self.maxMass
867  alg.particles = config.readName (self.containerName)
868  alg.preselection = config.getPreselection (self.containerName, '')
869  config.addSelection (self.containerName, '', alg.selectionDecoration,
870  preselection=True)
871 
872  config.addOutputVar (self.containerName, 'm', 'm')
873 
874 # These algorithms set up the jet recommendations as-of 04/02/2019.
875 # Jet calibration recommendations
876 # https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/ApplyJetCalibrationR21
877 # Jet uncertainties recommendations
878 # Small-R
879 # https://twiki.cern.ch/twiki/bin/view/AtlasProtected/JetUncertaintiesRel21Summer2018SmallR
880 # Large-R
881 # https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/JetUncertaintiesRel21Moriond2018LargeR
882 # JVT recommendations
883 # https://twiki.cern.ch/twiki/bin/view/AtlasProtected/JVTCalibrationRel21
884 
885 @groupBlocks
886 def makeJetAnalysisConfig( seq, containerName, jetCollection,
887  runGhostMuonAssociation = None):
888  """Create a jet analysis algorithm sequence
889  The jet collection is interpreted and selects the correct function to call,
890  makeSmallRJetAnalysisConfig, makeRScanJetAnalysisConfig or
891  makeLargeRJetAnalysisConfig
892 
893  Keyword arguments
894  jetCollection -- The jet container to run on.
895  """
896 
897  # Remove b-tagging calibration from the container name
898  btIndex = jetCollection.find('_BTagging')
899  if btIndex != -1:
900  jetCollection = jetCollection[:btIndex]
901 
902  jetCollectionName=jetCollection
903  # needed for PHYSLITE
904  if(jetCollection=="AnalysisJets") :
905  jetCollectionName="AntiKt4EMPFlowJets"
906  if(jetCollection=="AnalysisLargeRJets") :
907  jetCollectionName="AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets"
908 
909  # interpret the jet collection
910  collection_pattern = re.compile(
911  r"AntiKt(\d+)(EMTopo|EMPFlow|LCTopo|TrackCaloCluster|UFO|Track|HI)(TrimmedPtFrac5SmallR20|CSSKSoftDropBeta100Zcut10)?Jets")
912  match = collection_pattern.match(jetCollectionName)
913  if not match:
914  raise ValueError(
915  "Jet collection {0} does not match expected pattern!".format(jetCollectionName) )
916  radius = int(match.group(1) )
917  if radius not in [2, 4, 6, 10]:
918  raise ValueError("Jet collection has an unsupported radius '{0}'!".format(radius) )
919  jetInput = match.group(2)
920 
921  if jetCollectionName == 'AntiKtVR30Rmax4Rmin02PV0TrackJets' :
922  # don't to anything on track jets
923  config = PreJetAnalysisConfig()
924  config.setOptionValue ('containerName', containerName)
925  config.setOptionValue ('jetCollection', jetCollection)
926  config.setOptionValue ('runOriginalObjectLink', False)
927  config.setOptionValue ('runGhostMuonAssociation', False)
928  seq.append (config)
929  return
930 
931  config = PreJetAnalysisConfig()
932  config.setOptionValue ('containerName', containerName)
933  config.setOptionValue ('jetCollection', jetCollection)
934  config.runOriginalObjectLink = (btIndex != -1)
935  config.setOptionValue ('runGhostMuonAssociation', runGhostMuonAssociation)
936  seq.append (config)
937 
938  if radius == 4:
939  makeSmallRJetAnalysisConfig(seq, containerName,
940  jetCollection, jetInput=jetInput)
941  elif radius in [2, 6]:
942  makeRScanJetAnalysisConfig(seq, containerName,
943  jetCollection, jetInput=jetInput, radius=radius)
944  else:
945  trim = match.group(3)
946  if trim == "":
947  raise ValueError("Untrimmed large-R jets are not supported!")
948  makeLargeRJetAnalysisConfig(seq, containerName,
949  jetCollection, jetInput=jetInput)
950 
951 
952 
953 def makeSmallRJetAnalysisConfig( seq, containerName, jetCollection, jetInput,
954  runJvtUpdate = None, runNNJvtUpdate = None,
955  runJvtSelection = None, runFJvtSelection = None,
956  jvtWP = None, fJvtWP = None,
957  runJvtEfficiency = None, runFJvtEfficiency = None,
958  systematicsModelJES = None, systematicsModelJER = None):
959  """Add algorithms for the R=0.4 jets.
960 
961  Keyword arguments
962  seq -- The sequence to add the algorithms to
963  jetCollection -- The jet container to run on.
964  jetInput -- The type of input used, read from the collection name.
965  runJvtUpdate -- Determines whether or not to update JVT on the jets
966  runNNJvtUpdate -- Determines whether or not to update NN JVT on the jets
967  runJvtSelection -- Determines whether or not to run JVT selection on the jets
968  runFJvtSelection -- Determines whether or not to run forward JVT selection on the jets
969  jvtWP -- Defines the NNJvt WP to apply on the jets
970  fJvtWP -- Defines the fJvt WP to apply on the jets
971  runJvtEfficiency -- Determines whether or not to calculate the JVT efficiency
972  runFJvtEfficiency -- Determines whether or not to calculate the forward JVT efficiency
973  systematicsModelJES -- Which NP systematicsModelJES scheme should be used (All, Global, Category, Scenario)
974  systematicsModelJER -- Which variant of the systematicsModelJES should be used (All, Full, Simple). Note that not all combinations of systematicsModelJES and systematicsModelJER are valid!
975  """
976 
977  if jetInput not in ["EMTopo", "EMPFlow", "HI"]:
978  raise ValueError(
979  "Unsupported input type '{0}' for R=0.4 jets!".format(jetInput) )
980 
981  config = SmallRJetAnalysisConfig()
982  config.setOptionValue ('containerName', containerName)
983  config.setOptionValue ('jetCollection', jetCollection)
984  config.setOptionValue ('jetInput', jetInput)
985  config.setOptionValue ('runJvtUpdate', runJvtUpdate)
986  config.setOptionValue ('runNNJvtUpdate', runNNJvtUpdate)
987  config.setOptionValue ('runJvtSelection', runJvtSelection)
988  config.setOptionValue ('runFJvtSelection', runFJvtSelection)
989  config.setOptionValue ('jvtWP', jvtWP)
990  config.setOptionValue ('fJvtWP', fJvtWP)
991  config.setOptionValue ('runJvtEfficiency', runJvtEfficiency)
992  config.setOptionValue ('runFJvtEfficiency', runFJvtEfficiency)
993  config.setOptionValue ('systematicsModelJES', systematicsModelJES)
994  config.setOptionValue ('systematicsModelJER', systematicsModelJER)
995  seq.append (config)
996 
997 
998 def makeRScanJetAnalysisConfig( seq, containerName, jetCollection,
999  jetInput, radius ):
1000  """Add algorithms for the R-scan jets.
1001 
1002  Keyword arguments
1003  seq -- The sequence to add the algorithms to
1004  jetCollection -- The jet container to run on.
1005  jetInput -- The type of input used, read from the collection name.
1006  radius -- The radius of the r-scan jets.
1007  """
1008 
1009  config = RScanJetAnalysisConfig()
1010  config.setOptionValue ('containerName', containerName)
1011  config.setOptionValue ('jetCollection', jetCollection)
1012  config.setOptionValue ('jetInput', jetInput)
1013  config.setOptionValue ('radius', radius)
1014  seq.append (config)
1015 
1016 
1017 
1018 
1019 def makeLargeRJetAnalysisConfig( seq, containerName, jetCollection,
1020  jetInput, largeRMass = None):
1021  """Add algorithms for the R=1.0 jets.
1022 
1023  Keyword arguments
1024  seq -- The sequence to add the algorithms to
1025  jetCollection -- The jet container to run on.
1026  jetInput -- The type of input used, read from the collection name.
1027  largeRMass -- Which large-R mass definition to use. Ignored if not running on large-R jets ("Comb", "Calo", "TA")
1028  """
1029  config = LargeRJetAnalysisConfig()
1030  config.setOptionValue ('containerName', containerName)
1031  config.setOptionValue ('jetCollection', jetCollection)
1032  config.setOptionValue ('jetInput', jetInput)
1033  config.setOptionValue ('largeRMass', largeRMass)
1034  seq.append (config)
1035 
python.JetAnalysisConfig.LargeRJetAnalysisConfig.instanceName
def instanceName(self)
Definition: JetAnalysisConfig.py:611
python.JetAnalysisConfig._largeLCTopoConfigFile
def _largeLCTopoConfigFile(config, self)
Definition: JetAnalysisConfig.py:513
SystemOfUnits
python.JetAnalysisConfig.makeSmallRJetAnalysisConfig
def makeSmallRJetAnalysisConfig(seq, containerName, jetCollection, jetInput, runJvtUpdate=None, runNNJvtUpdate=None, runJvtSelection=None, runFJvtSelection=None, jvtWP=None, fJvtWP=None, runJvtEfficiency=None, runFJvtEfficiency=None, systematicsModelJES=None, systematicsModelJER=None)
Definition: JetAnalysisConfig.py:953
vtune_athena.format
format
Definition: vtune_athena.py:14
python.JetAnalysisConfig.SmallRJetAnalysisConfig.systematicsModelJES
systematicsModelJES
Definition: JetAnalysisConfig.py:188
python.JetAnalysisConfig.LargeRJetAnalysisConfig.createFFSmearingTool
def createFFSmearingTool(self, jetFFSmearingAlg, config)
Definition: JetAnalysisConfig.py:700
python.JetAnalysisConfig.SmallRJetAnalysisConfig.getUncertaintyToolSettings
def getUncertaintyToolSettings(self, config)
Definition: JetAnalysisConfig.py:180
python.JetAnalysisConfig.PreJetAnalysisConfig.jetCollection
jetCollection
Definition: JetAnalysisConfig.py:46
python.JetAnalysisConfig.PreJetAnalysisConfig.makeAlgs
def makeAlgs(self, config)
Definition: JetAnalysisConfig.py:43
python.JetAnalysisConfig.PreJetAnalysisConfig
Definition: JetAnalysisConfig.py:15
python.JetAnalysisConfig.SmallRJetAnalysisConfig.jetInput
jetInput
Definition: JetAnalysisConfig.py:216
python.JetAnalysisConfig.LargeRJetAnalysisConfig
Definition: JetAnalysisConfig.py:533
python.JetAnalysisConfig.RScanJetAnalysisConfig
Definition: JetAnalysisConfig.py:455
python.JetAnalysisConfig.RScanJetAnalysisConfig.makeAlgs
def makeAlgs(self, config)
Definition: JetAnalysisConfig.py:483
python.JetAnalysisConfig.RScanJetAnalysisConfig.jetCollection
jetCollection
Definition: JetAnalysisConfig.py:488
python.JetAnalysisConfig.makeLargeRJetAnalysisConfig
def makeLargeRJetAnalysisConfig(seq, containerName, jetCollection, jetInput, largeRMass=None)
Definition: JetAnalysisConfig.py:1019
python.JetAnalysisConfig.PreJetAnalysisConfig.__init__
def __init__(self)
Definition: JetAnalysisConfig.py:18
python.JetAnalysisConfig.SmallRJetAnalysisConfig.__init__
def __init__(self)
Definition: JetAnalysisConfig.py:109
python.JetAnalysisConfig.LargeRJetAnalysisConfig.getUncertaintyToolSettings
def getUncertaintyToolSettings(self, config)
Definition: JetAnalysisConfig.py:615
python.JetAnalysisConfig.SmallRJetAnalysisConfig.systematicsModelJER
systematicsModelJER
Definition: JetAnalysisConfig.py:188
python.JetAnalysisConfig.LargeRJetAnalysisConfig.createUncertaintyTool
def createUncertaintyTool(self, jetUncertaintiesAlg, config, jetCollectionName, doPseudoData=False)
Definition: JetAnalysisConfig.py:662
python.JetAnalysisConfig.SmallRJetAnalysisConfig.makeAlgs
def makeAlgs(self, config)
Definition: JetAnalysisConfig.py:289
python.JetAnalysisConfig.PreJetAnalysisConfig.instanceName
def instanceName(self)
Definition: JetAnalysisConfig.py:39
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
python.JetAnalysisConfig.LargeRJetAnalysisConfig.__init__
def __init__(self)
Definition: JetAnalysisConfig.py:536
python.JetAnalysisConfig.SmallRJetAnalysisConfig.instanceName
def instanceName(self)
Definition: JetAnalysisConfig.py:176
python.JetAnalysisConfig.makeRScanJetAnalysisConfig
def makeRScanJetAnalysisConfig(seq, containerName, jetCollection, jetInput, radius)
Definition: JetAnalysisConfig.py:998
python.JetAnalysisConfig.SmallRJetAnalysisConfig.jetCollection
jetCollection
Definition: JetAnalysisConfig.py:292
python.JetAnalysisConfig.SmallRJetAnalysisConfig
Definition: JetAnalysisConfig.py:106
python.JetAnalysisConfig.makeJetAnalysisConfig
def makeJetAnalysisConfig(seq, containerName, jetCollection, runGhostMuonAssociation=None)
Definition: JetAnalysisConfig.py:886
if
if(febId1==febId2)
Definition: LArRodBlockPhysicsV0.cxx:567
python.JetAnalysisConfig.LargeRJetAnalysisConfig.jetCollection
jetCollection
Definition: JetAnalysisConfig.py:747
python.JetAnalysisConfig.SmallRJetAnalysisConfig.createUncertaintyTool
def createUncertaintyTool(self, jetUncertaintiesAlg, config, jetCollectionName, doPseudoData=False)
Definition: JetAnalysisConfig.py:251
python.JetAnalysisConfig.LargeRJetAnalysisConfig.jetInput
jetInput
Definition: JetAnalysisConfig.py:758
python.JetAnalysisConfig.LargeRJetAnalysisConfig.makeAlgs
def makeAlgs(self, config)
Definition: JetAnalysisConfig.py:740
python.JetAnalysisConfig.RScanJetAnalysisConfig.instanceName
def instanceName(self)
Definition: JetAnalysisConfig.py:479
python.JetAnalysisConfig.RScanJetAnalysisConfig.__init__
def __init__(self)
Definition: JetAnalysisConfig.py:458