Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 from __future__ import print_function
5 
6 # AnaAlgorithm import(s):
7 from AnalysisAlgorithmsConfig.ConfigBlock import ConfigBlock
8 from AnalysisAlgorithmsConfig.ConfigSequence import groupBlocks
9 from AnalysisAlgorithmsConfig.ConfigAccumulator import DataType
10 from AthenaCommon.SystemOfUnits import GeV
11 from AthenaConfiguration.Enums import LHCPeriod
12 from AthenaCommon.Logging import logging
13 import re
14 
15 
16 class PreJetAnalysisConfig (ConfigBlock) :
17  """the ConfigBlock for the common preprocessing of jet sequences"""
18 
19  def __init__ (self, containerName='', jetCollection='') :
20  super (PreJetAnalysisConfig, self).__init__ ()
21  self.addOption ('containerName', containerName, type=str,
22  noneAction='error',
23  info="the name of the output container after calibration.")
24  self.addOption ('jetCollection', jetCollection, type=str,
25  noneAction='error',
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')
30  # TODO: add info string
31  self.addOption ('runOriginalObjectLink', False, type=bool,
32  info="")
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.")
39 
40 
41  def makeAlgs (self, config) :
42 
43 
44  if config.isPhyslite() and self.jetCollection == 'AntiKt4EMPFlowJets' :
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)
48  else :
49  config.setSourceName (self.containerName, self.jetCollection, originalName = self.jetCollection)
50 
51  # Relink original jets in case of b-tagging calibration
52  if self.runOriginalObjectLink :
53  alg = config.createAlgorithm( 'CP::AsgOriginalObjectLinkAlg',
54  'JetOriginalObjectLinkAlg'+self.containerName,
55  reentrant=True )
56  alg.baseContainerName = self.jetCollection
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, '')
61 
62  # Set up the jet ghost muon association algorithm:
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)
72 
73  # NB: I'm assuming that the truth tagging is done in PHYSLITE, if not this will
74  # need to change
75  if self.runTruthJetTagging or (
76  self.runTruthJetTagging is None
77  and config.dataType() is not DataType.Data
78  ):
79  # Decorate jets with isHS labels (required to retrieve Jvt SFs)
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
86 
87  # Set up shallow copy if needed and not yet done
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)
92 
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)
97 
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)
101 
102 
103 
104 class SmallRJetAnalysisConfig (ConfigBlock) :
105  """the ConfigBlock for the small-r jet sequence"""
106 
107  def __init__ (self, containerName='', jetCollection='', jetInput='') :
108  super (SmallRJetAnalysisConfig, self).__init__ ()
109  self.addOption ('containerName', containerName, type=str,
110  noneAction='error',
111  info="the name of the output container after calibration.")
112  self.addOption ('jetCollection', jetCollection, type=str,
113  noneAction='error',
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.")
116  # TODO: add info string
117  self.addOption ('jetInput', jetInput, type=str,
118  noneAction='error',
119  info="")
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 "
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 
177  def getUncertaintyToolSettings(self, config):
178 
179  # Retrieve appropriate JES/JER recommendations for the JetUncertaintiesTool.
180  # We do this separately from the tool declaration, as we may need to set uo
181  # two such tools, but they have to be private.
182 
183  # Config file:
184  config_file = None
185  if self.systematicsModelJES == "All" and self.systematicsModelJER == "All":
186  config_file = "R4_AllNuisanceParameters_AllJERNP.config"
187  elif "Scenario" in self.systematicsModelJES:
188  if self.systematicsModelJER != "Simple":
189  raise ValueError(
190  "Invalid uncertainty configuration - Scenario* systematicsModelJESs can "
191  "only be used together with the Simple systematicsModelJER")
192  config_file = "R4_{0}_SimpleJER.config".format(self.systematicsModelJES)
193  elif self.systematicsModelJES in ["Global", "Category"] and self.systematicsModelJER in ["Simple", "Full"]:
194  config_file = "R4_{0}Reduction_{1}JER.config".format(self.systematicsModelJES, self.systematicsModelJER)
195  else:
196  raise ValueError(
197  "Invalid combination of systematicsModelJES and systematicsModelJER settings: "
198  "systematicsModelJES: {0}, systematicsModelJER: {1}".format(self.systematicsModelJES, self.systematicsModelJER) )
199 
200  # Calibration area:
201  calib_area = None
202  if self.uncertToolCalibArea is not None:
203  calib_area = self.uncertToolCalibArea
204 
205  # Expert override for config path:
206  if self.uncertToolConfigPath is not None:
207  config_file = self.uncertToolConfigPath
208  else:
209  if config.geometry() is LHCPeriod.Run2:
210  if config.dataType() is DataType.FastSim:
211  config_file = "rel22/Fall2024_PreRec/" + config_file
212  else:
213  if self.jetInput == "HI":
214  config_file = "HIJetUncertainties/Spring2023/HI" + config_file
215  else:
216  config_file = "rel22/Summer2023_PreRec/" + config_file
217  else:
218  if config.dataType() is DataType.FastSim:
219  config_file = "rel22/Winter2025_AF3_PreRec/" + config_file
220  else:
221  if self.jetInput == "HI":
222  config_file = "HIJetUncertainties/Spring2023/HI" + config_file
223  else:
224  config_file = "rel22/Winter2025_PreRec/" + config_file
225 
226  # MC type:
227  mc_type = None
228  if self.uncertToolMCType is not None:
229  mc_type = self.uncertToolMCType
230  else:
231  if config.geometry() is LHCPeriod.Run2:
232  if config.dataType() is DataType.FastSim:
233  mc_type = "AF3"
234  else:
235  mc_type = "MC20"
236  else:
237  if config.dataType() is DataType.FastSim:
238  mc_type = "MC23AF3"
239  else:
240  if self.jetInput == "HI":
241  mc_type = "MC16"
242  else:
243  mc_type = "MC23"
244 
245  return config_file, calib_area, mc_type
246 
247 
248  def createUncertaintyTool(self, jetUncertaintiesAlg, config, jetCollectionName, doPseudoData=False):
249 
250  # Create an instance of JetUncertaintiesTool, following JetETmiss recommendations.
251  # To run Jet Energy Resolution (JER) uncertainties in the "Full" or "All" schemes,
252  # we need two sets of tools: one configured as normal (MC), the other with the
253  # exact same settings but pretending to run on data (pseudo-data).
254  # This is achieved by passing "isPseudoData=True" to the arguments.
255 
256  # Retrieve the common configuration settings
257  configFile, calibArea, mcType = self.getUncertaintyToolSettings(config)
258 
259  # The main tool for all JES+JER combinations
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
268 
269  if config.dataType() is DataType.Data and not (doPseudoData and self.runJERsystematicsOnData):
270  # we don't want any systematics on data if we're not using the right JER model!
271  jetUncertaintiesAlg.affectingSystematicsFilter = '.*'
272  if config.dataType() is not DataType.Data and doPseudoData and not self.runJERsystematicsOnData:
273  # The secondary tool for pseudo-data JER smearing
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
280 
281  # This is the part that is different!
282  jetUncertaintiesAlg.uncertaintiesToolPD.IsData = True
283  jetUncertaintiesAlg.uncertaintiesToolPD.PseudoDataJERsmearingMode = True
284 
285 
286  def makeAlgs (self, config) :
287 
288  jetCollectionName=self.jetCollection
289  if(self.jetCollection=="AnalysisJets") :
290  jetCollectionName="AntiKt4EMPFlowJets"
291  if(self.jetCollection=="AnalysisLargeRJets") :
292  jetCollectionName="AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets"
293 
294  if self.jetInput not in ["EMTopo", "EMPFlow", "HI"]:
295  raise ValueError(
296  "Unsupported input type '{0}' for R=0.4 jets!".format(self.jetInput) )
297 
298  if self.jvtWP not in ["FixedEffPt"]:
299  raise ValueError(
300  "Unsupported NNJvt WP '{0}'".format(self.jvtWP) )
301 
302  if self.fJvtWP not in ["Loose", "Tight", "Tighter"]:
303  raise ValueError(
304  "Unsupported fJvt WP '{0}'".format(self.fJvtWP) )
305 
306  if not config.isPhyslite() or self.recalibratePhyslite:
307  # Prepare the jet calibration algorithm
308  alg = config.createAlgorithm( 'CP::JetCalibrationAlg', 'JetCalibrationAlg'+self.containerName )
309  config.addPrivateTool( 'calibrationTool', 'JetCalibrationTool' )
310  alg.calibrationTool.JetCollection = jetCollectionName[:-4]
311  # Get the correct string to use in the config file name
312  if self.jetInput == "EMPFlow":
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"
319  elif self.jetInput == "HI":
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"
325  else:
326  if config.dataType() is DataType.FastSim:
327  configFile = "JES_MC16Recommendation_AFII_{0}_Apr2019_Rel21.config"
328  else:
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:
337  if self.jetInput == "HI":
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'
342  else:
343  alg.calibrationTool.CalibSequence = 'JetArea_Residual_EtaJES_GSC_Insitu'
344  else:
345  if self.jetInput == "EMPFlow":
346  alg.calibrationTool.CalibSequence = 'JetArea_Residual_EtaJES_GSC'
347  elif self.jetInput == "HI":
348  alg.calibrationTool.CalibSequence = 'EtaJES'
349  else:
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)
356 
357  # Jet uncertainties
358  alg = config.createAlgorithm( 'CP::JetUncertaintiesAlg', 'JetUncertaintiesAlg'+self.containerName )
359  self.createUncertaintyTool(alg, config, jetCollectionName, doPseudoData=( self.systematicsModelJER in ["Full","All"] ))
360  alg.jets = config.readName (self.containerName)
361  alg.jetsOut = config.copyName (self.containerName)
362  alg.preselection = config.getPreselection (self.containerName, '')
363 
364  # Set up the JVT update algorithm:
365  if self.runJvtUpdate :
366  alg = config.createAlgorithm( 'CP::JvtUpdateAlg', 'JvtUpdateAlg'+self.containerName )
367  config.addPrivateTool( 'jvtTool', 'JetVertexTaggerTool' )
368  alg.jvtTool.JetContainer = self.jetCollection
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, '')
373 
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' )
378  # Set this actually to the *output* collection
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
384 
385  if self.runFJvtUpdate :
386  alg = config.createAlgorithm( 'CP::JetModifierAlg', 'JetModifierAlg'+self.containerName )
387  config.addPrivateTool( 'modifierTool', 'JetForwardJvtTool')
388  alg.modifierTool.OutputDec = "passFJVT_internal" #Output decoration
389  alg.modifierTool.FJVTName = "fJVT"
390  # fJVT WPs depend on the MET WP
391  # see https://twiki.cern.ch/twiki/bin/view/AtlasProtected/EtmissRecommendationsRel21p2#fJVT_and_MET
392  alg.modifierTool.EtaThresh = 2.5 # Eta dividing central from forward jets
393  alg.modifierTool.ForwardMaxPt = 120*GeV #Max Pt to define fwdJets for JVT
394  alg.modifierTool.RenounceOutputs = True
395  alg.jets = config.readName (self.containerName)
396  alg.jetsOut = config.copyName (self.containerName)
397 
398  # Set up the jet efficiency scale factor calculation algorithm
399  # Change the truthJetCollection property to AntiKt4TruthWZJets if preferred
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)
409 
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"
418  else:
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)
429 
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)
438 
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"
446  else:
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)
457 
458  # Additional decorations
459  alg = config.createAlgorithm( 'CP::AsgEnergyDecoratorAlg', 'EnergyDecorator' + self.containerName )
460  alg.particles = config.readName (self.containerName)
461 
462  config.addOutputVar (self.containerName, 'e_%SYS%', 'e')
463 
464 
465 class RScanJetAnalysisConfig (ConfigBlock) :
466  """the ConfigBlock for the r-scan jet sequence"""
467 
468  def __init__ (self, containerName='', jetCollection='', jetInput='', radius=None) :
469  super (RScanJetAnalysisConfig, self).__init__ ()
470  self.addOption ('containerName', containerName, type=str,
471  noneAction='error',
472  info="the name of the output container after calibration.")
473  self.addOption ('jetCollection', jetCollection, type=str,
474  noneAction='error',
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.")
477  # TODO: add info string
478  self.addOption ('jetInput', jetInput, type=str,
479  noneAction='error',
480  info="")
481  # TODO: add info string
482  self.addOption (radius, radius, type=int,
483  noneAction='error',
484  info="")
485  self.addOption ('recalibratePhyslite', True, type=bool,
486  info="whether to run the CP::JetCalibrationAlg on PHYSLITE "
487  "derivations. The default is True.")
488 
489 
490  def makeAlgs (self, config) :
491 
492  log = logging.getLogger('RScanJetAnalysisConfig')
493 
494  jetCollectionName=self.jetCollection
495  if(self.jetCollection=="AnalysisJets") :
496  jetCollectionName="AntiKt4EMPFlowJets"
497  if(self.jetCollection=="AnalysisLargeRJets") :
498  jetCollectionName="AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets"
499 
500  if not config.isPhyslite() or self.recalibratePhyslite:
501  if self.jetInput != "LCTopo":
502  raise ValueError(
503  "Unsupported input type '{0}' for R-scan jets!".format(self.jetInput) )
504  # Prepare the jet calibration algorithm
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"
512  else:
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)
516  # Logging would be good
517  log.warning("Uncertainties for R-Scan jets are not yet released!")
518 
519 
520 def _largeLCTopoConfigFile(config, self):
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"
525  if is_sim:
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"
530  if is_sim:
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"
535  if is_sim:
536  return "JES_MC16recommendation_FatJet_Trimmed_JMS_TA_12Oct2018.config"
537  return None
538 
539 
540 class LargeRJetAnalysisConfig (ConfigBlock) :
541  """the ConfigBlock for the large-r jet sequence"""
542 
543  def __init__ (self, containerName='', jetCollection='', jetInput='') :
544  super (LargeRJetAnalysisConfig, self).__init__ ()
545  self.addOption ('containerName', containerName, type=str,
546  noneAction='error',
547  info="the name of the output container after calibration.")
548  self.addOption ('jetCollection', jetCollection, type=str,
549  noneAction='error',
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.")
552  # TODO: add info string
553  self.addOption ('jetInput', jetInput, type=str,
554  noneAction='error',
555  info="")
556  # TODO: add info string
557  self.addOption ('largeRMass', "Comb", type=str,
558  info="")
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!")
568  # Adding these options to override the jet uncertainty config file when we have new recommendations
569  # Calibration tool options
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 "
573  "default is None.")
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 "
577  "default is None.")
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.")
582  # Uncertainties tool options
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 "
586  "default is None.")
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 "
590  "default is None.")
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. "
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 getUncertaintyToolSettings(self, config):
612  # Retrieve appropriate JES/JER recommendations for the JetUncertaintiesTool.
613  # We do this separately from the tool declaration, as we may need to set uo
614  # two such tools, but they have to be private.
615 
616  log = logging.getLogger('LargeRJetAnalysisConfig')
617 
618  # Config file:
619  config_file = None
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)
622  else:
623  raise ValueError(
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:
628  # Expert override
629  config_file = self.uncertToolConfigPath
630  else:
631  if config.geometry() in [LHCPeriod.Run2, LHCPeriod.Run3]:
632  config_file = "rel22/Winter2024_PreRec/" + config_file
633  else:
634  log.warning("Uncertainties for UFO jets are not for Run 4!")
635 
636  # Calibration area:
637  calib_area = None
638  if self.uncertToolCalibArea is not None:
639  calib_area = self.uncertToolCalibArea
640 
641  # MC type:
642  if self.uncertToolMCType is not None:
643  mc_type = self.uncertToolMCType
644  else:
645  if config.dataType() is DataType.FastSim:
646  # To be updated when FastSim recommendatiosn are released
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:
650  mc_type = "MC20"
651  else:
652  mc_type = "MC23"
653  else:
654  if config.geometry() is LHCPeriod.Run2:
655  mc_type = "MC20"
656  else:
657  mc_type = "MC23"
658 
659  return config_file, calib_area, mc_type
660 
661  def createUncertaintyTool(self, jetUncertaintiesAlg, config, jetCollectionName, doPseudoData=False):
662  '''
663  Create instance(s) of JetUncertaintiesTool following JetETmiss recommendations.
664 
665  JER uncertainties under the "Full" scheme must be run on MC samples twice:
666  1. Normal (MC) mode,
667  2. Pseudodata (PD) mode, as if the events are Data.
668  '''
669 
670  # Retrieve the common configuration settings
671  configFile, calibArea, mcType = self.getUncertaintyToolSettings(config)
672 
673  # The main tool for all JER combinations
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
682 
683  # JER smearing on data
684  if config.dataType() is DataType.Data and not (config.isPhyslite() and doPseudoData and self.runJERsystematicsOnData):
685  # we don't want any systematics on data if we're not using the right JER model!
686  jetUncertaintiesAlg.affectingSystematicsFilter = '.*'
687 
688  if config.dataType() is not (DataType.Data and config.isPhyslite()) and doPseudoData and not self.runJERsystematicsOnData:
689  # The secondary tool for pseudo-data JER smearing
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
698 
699  def createFFSmearingTool(self, jetFFSmearingAlg, config):
700  # Retrieve appropriate large-R jet mass resolution recommendations for the FFJetSmearingTool.
701 
702  log = logging.getLogger('LargeRJetAnalysisConfig')
703 
704  # Config file:
705  if self.systematicsModelJMR in ["Simple", "Full"]:
706  config_file = f"R10_{self.systematicsModelJMR}JMR.config"
707  else:
708  raise ValueError(
709  f"Invalid request for systematicsModelJMR settings: {self.systematicsModelJMR}"
710  )
711 
712  # Expert override for config path:
713  if self.uncertToolConfigPath is not None:
714  config_file = self.uncertToolConfigPath
715  else:
716  if config.geometry() in [LHCPeriod.Run2, LHCPeriod.Run3]:
717  config_file = "rel22/Fall2024_PreRec/" + config_file
718  else:
719  log.warning("Uncertainties for UFO jets are not for Run 4!")
720 
721  # MC type:
722  if config.geometry() is LHCPeriod.Run2:
723  if config.dataType() is DataType.FastSim:
724  mc_type = "MC20AF3"
725  else:
726  mc_type = "MC20"
727  elif config.geometry() is LHCPeriod.Run3:
728  mc_type = "MC23"
729 
730  # Set up the FF smearing tool
731  config.addPrivateTool( 'FFSmearingTool', 'CP::FFJetSmearingTool')
732  jetFFSmearingAlg.FFSmearingTool.MassDef = "UFO"
733  jetFFSmearingAlg.FFSmearingTool.MCType = mc_type
734  jetFFSmearingAlg.FFSmearingTool.ConfigFile = config_file
735 
736  def makeAlgs (self, config) :
737 
738  configFile = None
739  calibSeq = None
740  calibArea = None
741 
742  jetCollectionName=self.jetCollection
743  if(self.jetCollection=="AnalysisJets") :
744  jetCollectionName="AntiKt4EMPFlowJets"
745  if(self.jetCollection=="AnalysisLargeRJets") :
746  jetCollectionName="AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets"
747 
748  if self.largeRMass not in ["Comb", "Calo", "TA"]:
749  raise ValueError("Invalid large-R mass defintion {0}!".format(self.largeRMass) )
750 
751  if self.jetInput not in ["LCTopo", "TrackCaloCluster", "UFO"]:
752  raise ValueError("Invalid input type '{0}' for large-R jets!".format(self.jetInput) )
753 
754  if self.jetInput == "TrackCaloCluster":
755  # Only one mass defintion supported
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"
759  if self.jetInput == "LCTopo":
760  configFile = _largeLCTopoConfigFile(config, self)
761  if self.jetInput == "UFO":
762  configFile = "JES_MC20PreRecommendation_R10_UFO_CSSK_SoftDrop_JMS_R21Insitu_02Aug2024.config"
763  if self.calibToolConfigFile is not None:
764  configFile = self.calibToolConfigFile
765 
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
772 
773  if self.calibToolCalibArea is not None:
774  calibArea = self.calibToolCalibArea
775 
776  if not config.isPhyslite() or self.recalibratePhyslite:
777  # Prepare the jet calibration algorithm
778  alg = config.createAlgorithm( 'CP::JetCalibrationAlg', 'JetCalibrationAlg'+self.containerName )
779  config.addPrivateTool( 'calibrationTool', 'JetCalibrationTool' )
780 
781  alg.calibrationTool.JetCollection = jetCollectionName[:-4]
782 
783  if configFile is None:
784  raise ValueError(f'Unsupported: {self.jetInput=}, {config.dataType()=}')
785  alg.calibrationTool.ConfigFile = configFile
786 
787  if calibSeq is None:
788  raise ValueError(f'Unsupported: {self.jetInput=}, {config.dataType()=}')
789  alg.calibrationTool.CalibSequence = calibSeq
790 
791  if calibArea is not None:
792  alg.calibrationTool.CalibArea = calibArea
793 
794  alg.calibrationTool.IsData = (config.dataType() is DataType.Data)
795  alg.jets = config.readName(self.containerName)
796 
797  # Jet uncertainties
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"] ))
801 
802  alg.uncertaintiesTool.JetDefinition = jetCollectionName[:-4]
803 
804  # R=1.0 jets have a validity range
805  alg.outOfValidity = 2 # SILENT
806  alg.outOfValidityDeco = 'outOfValidity'
807 
808  alg.jets = config.readName (self.containerName)
809  alg.jetsOut = config.copyName (self.containerName)
810  alg.preselection = config.getPreselection (self.containerName, '')
811 
812  if self.jetInput != "UFO":
813  alg = config.createAlgorithm( 'CP::JetUncertaintiesAlg', 'JetUncertaintiesAlg'+self.containerName )
814 
815  # R=1.0 jets have a validity range
816  alg.outOfValidity = 2 # SILENT
817  alg.outOfValidityDeco = 'outOfValidity'
818  config.addPrivateTool( 'uncertaintiesTool', 'JetUncertaintiesTool' )
819 
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)
825 
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')
830 
831  if self.jetInput == "UFO" and config.dataType() is not DataType.Data:
832  # set up the FF smearing algorithm
833  alg = config.createAlgorithm( 'CP::JetFFSmearingAlg', 'JetFFSmearingAlg'+self.containerName )
834  self.createFFSmearingTool(alg, config)
835  alg.outOfValidity = 2 # SILENT
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, '')
840 
841  if self.minPt > 0 or self.maxPt > 0 or self.maxEta > 0:
842  # Set up the the pt-eta selection
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,
852  preselection=True)
853 
854  if self.minMass > 0 or self.maxMass > 0:
855  # Set up the the mass selection
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,
864  preselection=True)
865 
866  config.addOutputVar (self.containerName, 'm', 'm')
867 
868 # These algorithms set up the jet recommendations as-of 04/02/2019.
869 # Jet calibration recommendations
870 # https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/ApplyJetCalibrationR21
871 # Jet uncertainties recommendations
872 # Small-R
873 # https://twiki.cern.ch/twiki/bin/view/AtlasProtected/JetUncertaintiesRel21Summer2018SmallR
874 # Large-R
875 # https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/JetUncertaintiesRel21Moriond2018LargeR
876 # JVT recommendations
877 # https://twiki.cern.ch/twiki/bin/view/AtlasProtected/JVTCalibrationRel21
878 
879 @groupBlocks
880 def makeJetAnalysisConfig( seq, containerName, jetCollection,
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
886 
887  Keyword arguments
888  jetCollection -- The jet container to run on.
889  """
890 
891  # Remove b-tagging calibration from the container name
892  btIndex = jetCollection.find('_BTagging')
893  if btIndex != -1:
894  jetCollection = jetCollection[:btIndex]
895 
896  jetCollectionName=jetCollection
897  # needed for PHYSLITE
898  if(jetCollection=="AnalysisJets") :
899  jetCollectionName="AntiKt4EMPFlowJets"
900  if(jetCollection=="AnalysisLargeRJets") :
901  jetCollectionName="AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets"
902 
903  # interpret the jet collection
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)
907  if not match:
908  raise ValueError(
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)
914 
915  if jetCollectionName == 'AntiKtVR30Rmax4Rmin02PV0TrackJets' :
916  # don't to anything on track jets
917  config = PreJetAnalysisConfig (containerName, jetCollection)
918  config.setOptionValue ('runOriginalObjectLink', False)
919  config.setOptionValue ('runGhostMuonAssociation', False)
920  seq.append (config)
921  return
922 
923  config = PreJetAnalysisConfig (containerName, jetCollection)
924  config.runOriginalObjectLink = (btIndex != -1)
925  config.setOptionValue ('runGhostMuonAssociation', runGhostMuonAssociation)
926  seq.append (config)
927 
928  if radius == 4:
929  makeSmallRJetAnalysisConfig(seq, containerName,
930  jetCollection, jetInput=jetInput)
931  elif radius in [2, 6]:
932  makeRScanJetAnalysisConfig(seq, containerName,
933  jetCollection, jetInput=jetInput, radius=radius)
934  else:
935  trim = match.group(3)
936  if trim == "":
937  raise ValueError("Untrimmed large-R jets are not supported!")
938  makeLargeRJetAnalysisConfig(seq, containerName,
939  jetCollection, jetInput=jetInput)
940 
941 
942 
943 def makeSmallRJetAnalysisConfig( seq, containerName, jetCollection, 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.
950 
951  Keyword arguments
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!
966  """
967 
968  if jetInput not in ["EMTopo", "EMPFlow", "HI"]:
969  raise ValueError(
970  "Unsupported input type '{0}' for R=0.4 jets!".format(jetInput) )
971 
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)
984  seq.append (config)
985 
986 
987 def makeRScanJetAnalysisConfig( seq, containerName, jetCollection,
988  jetInput, radius ):
989  """Add algorithms for the R-scan jets.
990 
991  Keyword arguments
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.
996  """
997 
998  config = SmallRJetAnalysisConfig (containerName, jetCollection, jetInput, radius)
999  seq.append (config)
1000 
1001 
1002 
1003 
1004 def makeLargeRJetAnalysisConfig( seq, containerName, jetCollection,
1005  jetInput, largeRMass = None):
1006  """Add algorithms for the R=1.0 jets.
1007 
1008  Keyword arguments
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")
1013  """
1014  config = LargeRJetAnalysisConfig (containerName, jetCollection, jetInput)
1015  config.setOptionValue ('largeRMass', largeRMass)
1016  seq.append (config)
1017 
python.JetAnalysisConfig.LargeRJetAnalysisConfig.__init__
def __init__(self, containerName='', jetCollection='', jetInput='')
Definition: JetAnalysisConfig.py:543
python.JetAnalysisConfig._largeLCTopoConfigFile
def _largeLCTopoConfigFile(config, self)
Definition: JetAnalysisConfig.py:520
SystemOfUnits
vtune_athena.format
format
Definition: vtune_athena.py:14
python.JetAnalysisConfig.SmallRJetAnalysisConfig.systematicsModelJES
systematicsModelJES
Definition: JetAnalysisConfig.py:185
python.JetAnalysisConfig.LargeRJetAnalysisConfig.createFFSmearingTool
def createFFSmearingTool(self, jetFFSmearingAlg, config)
Definition: JetAnalysisConfig.py:699
python.JetAnalysisConfig.PreJetAnalysisConfig.__init__
def __init__(self, containerName='', jetCollection='')
Definition: JetAnalysisConfig.py:19
python.JetAnalysisConfig.SmallRJetAnalysisConfig.getUncertaintyToolSettings
def getUncertaintyToolSettings(self, config)
Definition: JetAnalysisConfig.py:177
python.JetAnalysisConfig.PreJetAnalysisConfig.jetCollection
jetCollection
Definition: JetAnalysisConfig.py:44
python.JetAnalysisConfig.PreJetAnalysisConfig.makeAlgs
def makeAlgs(self, config)
Definition: JetAnalysisConfig.py:41
python.JetAnalysisConfig.PreJetAnalysisConfig
Definition: JetAnalysisConfig.py:16
python.JetAnalysisConfig.SmallRJetAnalysisConfig.jetInput
jetInput
Definition: JetAnalysisConfig.py:213
python.JetAnalysisConfig.LargeRJetAnalysisConfig
Definition: JetAnalysisConfig.py:540
python.JetAnalysisConfig.RScanJetAnalysisConfig
Definition: JetAnalysisConfig.py:465
python.JetAnalysisConfig.RScanJetAnalysisConfig.makeAlgs
def makeAlgs(self, config)
Definition: JetAnalysisConfig.py:490
python.JetAnalysisConfig.RScanJetAnalysisConfig.jetCollection
jetCollection
Definition: JetAnalysisConfig.py:495
python.JetAnalysisConfig.RScanJetAnalysisConfig.__init__
def __init__(self, containerName='', jetCollection='', jetInput='', radius=None)
Definition: JetAnalysisConfig.py:468
python.JetAnalysisConfig.makeLargeRJetAnalysisConfig
def makeLargeRJetAnalysisConfig(seq, containerName, jetCollection, jetInput, largeRMass=None)
Definition: JetAnalysisConfig.py:1004
python.JetAnalysisConfig.LargeRJetAnalysisConfig.getUncertaintyToolSettings
def getUncertaintyToolSettings(self, config)
Definition: JetAnalysisConfig.py:611
python.LArMinBiasAlgConfig.int
int
Definition: LArMinBiasAlgConfig.py:59
python.JetAnalysisConfig.SmallRJetAnalysisConfig.__init__
def __init__(self, containerName='', jetCollection='', jetInput='')
Definition: JetAnalysisConfig.py:107
python.JetAnalysisConfig.SmallRJetAnalysisConfig.systematicsModelJER
systematicsModelJER
Definition: JetAnalysisConfig.py:185
python.JetAnalysisConfig.LargeRJetAnalysisConfig.createUncertaintyTool
def createUncertaintyTool(self, jetUncertaintiesAlg, config, jetCollectionName, doPseudoData=False)
Definition: JetAnalysisConfig.py:661
python.JetAnalysisConfig.SmallRJetAnalysisConfig.makeAlgs
def makeAlgs(self, config)
Definition: JetAnalysisConfig.py:286
python.JetAnalysisConfig.makeSmallRJetAnalysisConfig
def makeSmallRJetAnalysisConfig(seq, containerName, jetCollection, jetInput, runJvtUpdate=None, runNNJvtUpdate=None, runFJvtUpdate=None, runJvtSelection=None, runFJvtSelection=None, jvtWP=None, fJvtWP=None, runJvtEfficiency=None, runFJvtEfficiency=None, systematicsModelJES=None, systematicsModelJER=None)
Definition: JetAnalysisConfig.py:943
python.JetAnalysisConfig.makeRScanJetAnalysisConfig
def makeRScanJetAnalysisConfig(seq, containerName, jetCollection, jetInput, radius)
Definition: JetAnalysisConfig.py:987
python.JetAnalysisConfig.SmallRJetAnalysisConfig.jetCollection
jetCollection
Definition: JetAnalysisConfig.py:289
python.JetAnalysisConfig.SmallRJetAnalysisConfig
Definition: JetAnalysisConfig.py:104
python.JetAnalysisConfig.makeJetAnalysisConfig
def makeJetAnalysisConfig(seq, containerName, jetCollection, runGhostMuonAssociation=None)
Definition: JetAnalysisConfig.py:880
if
if(febId1==febId2)
Definition: LArRodBlockPhysicsV0.cxx:567
python.JetAnalysisConfig.LargeRJetAnalysisConfig.jetCollection
jetCollection
Definition: JetAnalysisConfig.py:743
python.JetAnalysisConfig.SmallRJetAnalysisConfig.createUncertaintyTool
def createUncertaintyTool(self, jetUncertaintiesAlg, config, jetCollectionName, doPseudoData=False)
Definition: JetAnalysisConfig.py:248
python.JetAnalysisConfig.LargeRJetAnalysisConfig.jetInput
jetInput
Definition: JetAnalysisConfig.py:754
python.JetAnalysisConfig.LargeRJetAnalysisConfig.makeAlgs
def makeAlgs(self, config)
Definition: JetAnalysisConfig.py:736