ATLAS Offline Software
AsgAnalysisConfig.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2 
3 # AnaAlgorithm import(s):
4 from AnalysisAlgorithmsConfig.ConfigBlock import ConfigBlock
5 from AnalysisAlgorithmsConfig.ConfigSequence import groupBlocks
6 from AthenaConfiguration.Enums import LHCPeriod
7 from AnalysisAlgorithmsConfig.ConfigAccumulator import DataType, ExpertModeWarning
8 from enum import Enum
9 import warnings
10 
11 try:
12  from AthenaCommon.Logging import logging
13 except ImportError:
14  import logging
15 
17  JETS = ['JET_']
18  JER = ['JET_JER']
19  ELECTRONS = ['EG_', 'EL_']
20  MUONS = ['MUON_']
21  PHOTONS = ['EG_', 'PH_']
22  TAUS = ['TAUS_']
23  MET = ['MET_']
24  TRACKS = ['TRK_']
25  EVENT = ['GEN_', 'PRW_']
26  FTAG = ['FT_']
27 
28 class CommonServicesConfig (ConfigBlock) :
29  """the ConfigBlock for common services
30 
31  The idea here is that all algorithms need some common services, and I should
32  provide configuration blocks for those. For now there is just a single
33  block, but in the future I might break out e.g. the systematics service.
34  """
35 
36  def __init__ (self) :
37  super (CommonServicesConfig, self).__init__ ()
38  self.addOption ('runSystematics', None, type=bool,
39  info="whether to turn on the computation of systematic variations. "
40  "The default is to run them on MC.")
41  self.addOption ('filterSystematics', None, type=str,
42  info="a regexp string against which the systematics names will be "
43  "matched. Only positive matches are retained and used in the evaluation "
44  "of the various algorithms.")
45  self.addOption ('onlySystematicsCategories', None, type=list,
46  info="a list of strings defining categories of systematics to enable "
47  "(only recommended for studies / partial ntuple productions). Choose amongst: "
48  "jets, electrons, muons, photons, taus, met, tracks, ftag, event. This option is overridden "
49  "by 'filterSystematics'.")
50  self.addOption ('systematicsHistogram', None , type=str,
51  info="the name (string) of the histogram to which a list of executed "
52  "systematics will be printed. The default is None (don't write out "
53  "the histogram).")
54  self.addOption ('separateWeightSystematics', False, type=bool,
55  info="if 'systematicsHistogram' is enabled, whether to create a separate "
56  "histogram holding only the names of weight-based systematics. This is useful "
57  "to help make histogramming frameworks more efficient by knowing in advance which "
58  "systematics need to recompute the observable and which don't.")
59  self.addOption ('metadataHistogram', None , type=str,
60  info="the name (string) of the metadata histogram which contains information about "
61  "data type, campaign, etc. The default is None (don't write out "
62  "the histogram).")
63  self.addOption ('enableExpertMode', False, type=bool,
64  info="allows CP experts and CPAlgorithm devs to use non-recommended configurations. "
65  "DO NOT USE FOR ANALYSIS.")
66  self.addOption ('streamName', 'ANALYSIS', type=str,
67  info="name of the output stream to save the cut bookkeeper in. "
68  "The default is ANALYSIS.")
69 
70  def instanceName (self) :
71  """Return the instance name for this block"""
72  return '' # no instance name, this is a singleton
73 
74  def makeAlgs (self, config) :
75 
76  sysService = config.createService( 'CP::SystematicsSvc', 'SystematicsSvc' )
77 
78  if self.runSystematics is False :
79  runSystematics = self.runSystematics
80  elif config.noSystematics() is not None :
81  # if option not set:
82  # check to see if set in config accumulator
83  self.runSystematics = not config.noSystematics()
84  runSystematics = self.runSystematics
85  else :
86  runSystematics = True
87 
88  if runSystematics :
89  sysService.sigmaRecommended = 1
90  if config.dataType() is DataType.Data:
91  # Only one type of allowed systematics on data: the JER variations!
93  if self.onlySystematicsCategories is not None:
94  # Convert strings to enums and validate
95  requested_categories = []
96  for category_str in self.onlySystematicsCategories:
97  try:
98  category_enum = SystematicsCategories[category_str.upper()]
99  requested_categories += category_enum.value
100  except KeyError:
101  raise ValueError(f"Invalid systematics category passed to option 'onlySystematicsCategories': {category_str}. Must be one of {', '.join(category.name for category in SystematicsCategories)}")
102  # Construct regex pattern as logical-OR of category names
103  if len(requested_categories):
104  sysService.systematicsRegex = "^(?=.*(" + "|".join(requested_categories) + ")|$).*"
105  if self.filterSystematics is not None:
106  sysService.systematicsRegex = self.filterSystematics
107  config.createService( 'CP::SelectionNameSvc', 'SelectionNameSvc')
108 
109  if self.systematicsHistogram is not None:
110  # print out all systematics
111  allSysDumper = config.createAlgorithm( 'CP::SysListDumperAlg', 'SystematicsPrinter' )
112  allSysDumper.histogramName = self.systematicsHistogram
113  allSysDumper.RootStreamName = self.streamName
114 
115  if self.separateWeightSystematics:
116  # print out only the weight systematics (for more efficient histogramming down the line)
117  weightSysDumper = config.createAlgorithm( 'CP::SysListDumperAlg', 'OnlyWeightSystematicsPrinter' )
118  weightSysDumper.histogramName = f"{self.systematicsHistogram}OnlyWeights"
119  weightSysDumper.systematicsRegex = "^(GEN_|EL_EFF_|MUON_EFF_|PH_EFF_|TAUS_TRUEHADTAU_EFF_|FT_EFF_|extrapolation_pt_|JET_.*JvtEfficiency_|PRW_).*"
120 
121  if self.metadataHistogram is not None:
122  # add histogram with metadata
123  if not config.flags:
124  raise ValueError ("Writing out the metadata histogram requires to pass config flags")
125  metadataHistAlg = config.createAlgorithm( 'CP::MetadataHistAlg', 'MetadataHistAlg' )
126  metadataHistAlg.histogramName = self.metadataHistogram
127  metadataHistAlg.dataType = str(config.dataType().value)
128  metadataHistAlg.campaign = str(config.dataYear()) if config.dataType() is DataType.Data else str(config.campaign().value)
129  metadataHistAlg.mcChannelNumber = str(config.dsid())
130  if config.dataType() is DataType.Data:
131  etag = "unavailable"
132  else:
133  from AthenaConfiguration.AutoConfigFlags import GetFileMD
134  metadata = GetFileMD(config.flags.Input.Files)
135  amiTags = metadata.get("AMITag", "not found!")
136  etag = str(amiTags.split("_")[0])
137  metadataHistAlg.etag = etag
138 
139  if self.enableExpertMode and config._pass == 0:
140  # set any expert-mode errors to be ignored instead
141  warnings.simplefilter('ignore', ExpertModeWarning)
142  # just warning users they might be doing something dangerous
143  log = logging.getLogger('CommonServices')
144  bold = "\033[1m"
145  red = "\033[91m"
146  yellow = "\033[93m"
147  reset = "\033[0m"
148  log.warning(red +r"""
149  ________ _______ ______ _____ _______ __ __ ____ _____ ______ ______ _ _ ____ _ ______ _____
150  | ____\ \ / / __ \| ____| __ \__ __| | \/ |/ __ \| __ \| ____| | ____| \ | | /\ | _ \| | | ____| __ \
151  | |__ \ V /| |__) | |__ | |__) | | | | \ / | | | | | | | |__ | |__ | \| | / \ | |_) | | | |__ | | | |
152  | __| > < | ___/| __| | _ / | | | |\/| | | | | | | | __| | __| | . ` | / /\ \ | _ <| | | __| | | | |
153  | |____ / . \| | | |____| | \ \ | | | | | | |__| | |__| | |____ | |____| |\ |/ ____ \| |_) | |____| |____| |__| |
154  |______/_/ \_\_| |______|_| \_\ |_| |_| |_|\____/|_____/|______| |______|_| \_/_/ \_\____/|______|______|_____/
155 
156 """
157  +reset)
158  log.warning(f"{bold}{yellow}These settings are not recommended for analysis. Make sure you know what you're doing, or disable them with `enableExpertMode: False` in `CommonServices`.{reset}")
159 
160 
161 
162 @groupBlocks
163 def CommonServices(seq):
164  seq.append(CommonServicesConfig())
165  from AsgAnalysisAlgorithms.TruthCollectionsFixerConfig import TruthCollectionsFixerBlock
166  seq.append(TruthCollectionsFixerBlock())
167 
168 class IOStatsBlock(ConfigBlock):
169  """Print what branches are used in analysis"""
170 
171  def __init__(self):
172  super(IOStatsBlock, self).__init__()
173  self.addOption("printOption", "Summary", type=str,
174  info='option to pass the standard ROOT printing function. Can be "Summary", "ByEntries" or "ByBytes".')
175 
176  def instanceName (self) :
177  """Return the instance name for this block"""
178  return '' # no instance name, this is a singleton
179 
180  def makeAlgs(self, config):
181  alg = config.createAlgorithm('CP::IOStatsAlg', 'IOStatsAlg')
182  alg.printOption = self.printOption
183 
184 
185 class PileupReweightingBlock (ConfigBlock):
186  """the ConfigBlock for pileup reweighting"""
187 
188  def __init__ (self) :
189  super (PileupReweightingBlock, self).__init__ ()
190  self.addOption ('campaign', None, type=None,
191  info="the MC campaign for the PRW auto-configuration.")
192  self.addOption ('files', None, type=None,
193  info="the input files being processed (list of strings). "
194  "Alternative to auto-configuration.")
195  self.addOption ('useDefaultConfig', True, type=bool,
196  info="whether to use the central PRW files. The default is True.")
197  self.addOption ('userLumicalcFiles', None, type=None,
198  info="user-provided lumicalc files (list of strings). Alternative "
199  "to auto-configuration.")
200  self.addOption ('userLumicalcFilesPerCampaign', None, type=None,
201  info="user-provided lumicalc files (dictionary of list of strings, "
202  "with MC campaigns as the keys). Alternative to auto-configuration.")
203  self.addOption ('userPileupConfigs', None, type=None,
204  info="user-provided PRW files (list of strings). Alternative to "
205  "auto-configuration. Alternative to auto-configuration.")
206  self.addOption ('userPileupConfigsPerCampaign', None, type=None,
207  info="user-provided PRW files (dictionary of list of strings, with "
208  "MC campaigns as the keys)")
209  self.addOption ('postfix', '', type=str,
210  info="a postfix to apply to decorations and algorithm names. "
211  "Typically not needed unless several instances of PileupReweighting are scheduled.")
212  self.addOption ('alternativeConfig', False, type=bool,
213  info="whether this is used as an additional alternative config for PileupReweighting. "
214  "Will only store the alternative pile up weight in that case.")
215  self.addOption ('writeColumnarToolVariables', False, type=bool,
216  info="whether to add EventInfo variables needed for running the columnar tool(s) on the output n-tuple. (EXPERIMENTAL)",
217  expertMode=True)
218 
219  def instanceName (self) :
220  """Return the instance name for this block"""
221  return self.postfix
222 
223  def makeAlgs (self, config) :
224 
225  from Campaigns.Utils import Campaign
226 
227  log = logging.getLogger('makePileupAnalysisSequence')
228 
229  eventInfoVar = ['runNumber', 'eventNumber', 'actualInteractionsPerCrossing', 'averageInteractionsPerCrossing']
230  if config.dataType() is not DataType.Data:
231  eventInfoVar += ['mcChannelNumber']
232  if self.writeColumnarToolVariables:
233  # This is not strictly necessary, as the columnar users
234  # could recreate this, but it is also a single constant int,
235  # that should compress exceedingly well.
236  eventInfoVar += ['eventTypeBitmask']
237 
238  if config.isPhyslite() and not self.alternativeConfig:
239  # PHYSLITE already has these variables defined, just need to copy them to the output
240  log.info(f'Physlite does not need pileup reweighting. Variables will be copied from input instead. {config.isPhyslite}')
241  for var in eventInfoVar:
242  config.addOutputVar ('EventInfo', var, var, noSys=True)
243 
244  if config.dataType() is not DataType.Data:
245  config.addOutputVar ('EventInfo', 'PileupWeight_%SYS%', 'weight_pileup')
246  if config.geometry() is LHCPeriod.Run2:
247  config.addOutputVar ('EventInfo', 'beamSpotWeight', 'weight_beamspot', noSys=True)
248  return
249 
250  # check files from flags
251  if self.files is None and config.flags is not None:
252  self.files = config.flags.Input.Files
253 
254  campaign = self.campaign
255  # if user didn't explicitly configure campaign, let's try setting it from metadata
256  # only needed on MC
257  if config.dataType() is not DataType.Data and self.campaign is None:
258  # if we used flags, campaign is auto-determined
259  if config.campaign() is not None and config.campaign() is not Campaign.Unknown:
260  campaign = config.campaign()
261  log.info(f'Auto-configuring campaign for PRW from flags: {campaign.value}')
262  else:
263  # we try to determine campaign from files if above failed
264  if self.files is not None:
265  from Campaigns.Utils import getMCCampaign
266  campaign = getMCCampaign(self.files)
267  if campaign and campaign is not Campaign.Unknown:
268  log.info(f'Auto-configuring campaign for PRW from files: {campaign.value}')
269  else:
270  log.info('Campaign could not be determined.')
271 
272 
273  toolConfigFiles = []
274  toolLumicalcFiles = []
275 
276  # PRW config files should only be configured if we run on MC
277  # Run 4 not supported yet
278  if (config.dataType() is not DataType.Data and
279  config.geometry() is not LHCPeriod.Run4):
280  # check if user provides per-campaign pileup config list
281  if self.userPileupConfigs is not None and self.userPileupConfigsPerCampaign is not None:
282  raise ValueError('Both userPileupConfigs and userPileupConfigsPerCampaign specified, '
283  'use only one of the options!')
284  if self.userPileupConfigsPerCampaign is not None:
285  if not campaign:
286  raise Exception('userPileupConfigsPerCampaign requires campaign to be configured!')
287  if campaign is Campaign.Unknown:
288  raise Exception('userPileupConfigsPerCampaign used, but campaign = Unknown!')
289  try:
290  toolConfigFiles = self.userPileupConfigsPerCampaign[campaign.value][:]
291  log.info('Using user provided per-campaign PRW configuration')
292  except KeyError as e:
293  raise KeyError(f'Unconfigured campaign {e} for userPileupConfigsPerCampaign!')
294 
295  elif self.userPileupConfigs is not None:
296  toolConfigFiles = self.userPileupConfigs[:]
297  log.info('Using user provided PRW configuration')
298 
299  else:
300  if self.useDefaultConfig and self.files is None:
301  raise ValueError('useDefaultConfig requires files to be configured! '
302  'Either pass them as an option or use flags.')
303 
304  from PileupReweighting.AutoconfigurePRW import getConfigurationFiles
305  if campaign and campaign is not Campaign.Unknown:
306  toolConfigFiles = getConfigurationFiles(campaign=campaign,
307  files=self.files,
308  useDefaultConfig=self.useDefaultConfig,
309  data_type=config.dataType())
310  if self.useDefaultConfig:
311  log.info('Auto-configuring universal/default PRW config')
312  else:
313  log.info('Auto-configuring per-sample PRW config files based on input files')
314  else:
315  log.info('No campaign specified, no PRW config files configured')
316 
317  # check if user provides per-campaign lumical config list
318  if self.userLumicalcFilesPerCampaign is not None and self.userLumicalcFiles is not None:
319  raise ValueError('Both userLumicalcFiles and userLumicalcFilesYear specified, '
320  'use only one of the options!')
321  if self.userLumicalcFilesPerCampaign is not None:
322  try:
323  toolLumicalcFiles = self.userLumicalcFilesPerCampaign[campaign.value][:]
324  log.info('Using user-provided per-campaign lumicalc files')
325  except KeyError as e:
326  raise KeyError(f'Unconfigured campaign {e} for userLumicalcFilesPerCampaign!')
327  elif self.userLumicalcFiles is not None:
328  toolLumicalcFiles = self.userLumicalcFiles[:]
329  log.info('Using user-provided lumicalc files')
330  else:
331  if campaign and campaign is not Campaign.Unknown:
332  from PileupReweighting.AutoconfigurePRW import getLumicalcFiles
333  toolLumicalcFiles = getLumicalcFiles(campaign)
334  log.info('Using auto-configured lumicalc files')
335  else:
336  log.info('No campaign specified, no lumicalc files configured for PRW')
337  else:
338  log.info('Data needs no lumicalc and PRW configuration files')
339 
340  # Set up the only algorithm of the sequence:
341  if config.geometry() is LHCPeriod.Run4:
342  log.warning ('Pileup reweighting is not yet supported for Run 4 geometry')
343  alg = config.createAlgorithm( 'CP::EventDecoratorAlg', 'EventDecoratorAlg' )
344  alg.uint32Decorations = { 'RandomRunNumber' :
345  config.flags.Input.RunNumbers[0] }
346 
347  else:
348  alg = config.createAlgorithm( 'CP::PileupReweightingAlg',
349  'PileupReweightingAlg' )
350  config.addPrivateTool( 'pileupReweightingTool', 'CP::PileupReweightingTool' )
351  alg.pileupReweightingTool.ConfigFiles = toolConfigFiles
352  if not toolConfigFiles and config.dataType() is not DataType.Data:
353  log.info("No PRW config files provided. Disabling reweighting")
354  # Setting the weight decoration to the empty string disables the reweighting
355  alg.pileupWeightDecoration = ""
356  else:
357  alg.pileupWeightDecoration = "PileupWeight" + self.postfix + "_%SYS%"
358  alg.pileupReweightingTool.LumiCalcFiles = toolLumicalcFiles
359 
360  if not self.alternativeConfig:
361  for var in eventInfoVar:
362  config.addOutputVar ('EventInfo', var, var, noSys=True)
363 
364  if config.dataType() is not DataType.Data and config.geometry() is LHCPeriod.Run2:
365  config.addOutputVar ('EventInfo', 'beamSpotWeight', 'weight_beamspot', noSys=True)
366 
367  if config.dataType() is not DataType.Data and toolConfigFiles:
368  config.addOutputVar ('EventInfo', 'PileupWeight' + self.postfix + '_%SYS%',
369  'weight_pileup'+self.postfix)
370 
371 
372 class GeneratorAnalysisBlock (ConfigBlock):
373  """the ConfigBlock for generator algorithms"""
374 
375  def __init__ (self) :
376  super (GeneratorAnalysisBlock, self).__init__ ()
377  self.addOption ('saveCutBookkeepers', True, type=bool,
378  info="whether to save the cut bookkeepers information into the "
379  "output file. The default is True.")
380  self.addOption ('runNumber', None, type=int,
381  info="the MC runNumber (int). The default is None (autoconfigure "
382  "from metadata).")
383  self.addOption ('cutBookkeepersSystematics', None, type=bool,
384  info="whether to also save the cut bookkeepers systematics. The "
385  "default is None (follows the global systematics flag). Set to "
386  "False or True to override.")
387  self.addOption ('histPattern', None, type=str,
388  info="the histogram name pattern for the cut-bookkeeper histogram names")
389  self.addOption ('streamName', 'ANALYSIS', type=str,
390  info="name of the output stream to save the cut bookkeeper in. "
391  "The default is ANALYSIS.")
392  self.addOption ('detailedPDFinfo', False, type=bool,
393  info="save the necessary information to run the LHAPDF tool offline. "
394  "The default is False.")
395  self.addOption ('doHFProdFracReweighting', False, type=bool,
396  info="whether to apply HF production fraction reweighting. "
397  "The default is False.")
398  self.addOption ('truthParticleContainer', 'TruthParticles', type=str,
399  info="the name of the truth particle container to use for HF production fraction reweighting. "
400  "The default is 'TruthParticles'. ")
401  def instanceName (self) :
402  """Return the instance name for this block"""
403  return self.streamName
404 
405  def makeAlgs (self, config) :
406 
407  if config.dataType() is DataType.Data:
408  # there are no generator weights in data!
409  return
410  log = logging.getLogger('makeGeneratorAnalysisSequence')
411 
412  if self.runNumber is None:
413  self.runNumber = config.runNumber()
414 
415  if self.saveCutBookkeepers and not self.runNumber:
416  raise ValueError ("invalid run number: " + str(self.runNumber))
417 
418  # Set up the CutBookkeepers algorithm:
419  if self.saveCutBookkeepers:
420  alg = config.createAlgorithm('CP::AsgCutBookkeeperAlg', 'CutBookkeeperAlg')
421  alg.RootStreamName = self.streamName
422  alg.runNumber = self.runNumber
423  if self.cutBookkeepersSystematics is None:
424  alg.enableSystematics = not config.noSystematics()
425  else:
426  alg.enableSystematics = self.cutBookkeepersSystematics
427  if self.histPattern:
428  alg.histPattern = self.histPattern
429  config.addPrivateTool( 'truthWeightTool', 'PMGTools::PMGTruthWeightTool' )
430 
431  # Set up the weights algorithm:
432  alg = config.createAlgorithm( 'CP::PMGTruthWeightAlg', 'PMGTruthWeightAlg' )
433  config.addPrivateTool( 'truthWeightTool', 'PMGTools::PMGTruthWeightTool' )
434  alg.decoration = 'generatorWeight_%SYS%'
435  config.addOutputVar ('EventInfo', 'generatorWeight_%SYS%', 'weight_mc')
436 
437  if self.detailedPDFinfo:
438  alg = config.createAlgorithm( 'CP::PDFinfoAlg', 'PDFinfoAlg', reentrant=True )
439  for var in ["PDFID1","PDFID2","PDGID1","PDGID2","Q","X1","X2","XF1","XF2"]:
440  config.addOutputVar ('EventInfo', var, 'PDFinfo_' + var, noSys=True)
441 
442  if self.doHFProdFracReweighting:
443  generatorInfo = config.flags.Input.GeneratorsInfo
444  log.info(f"Loaded generator info: {generatorInfo}")
445 
446  DSID = "000000"
447 
448  if not generatorInfo:
449  log.warning("No generator info found.")
450  DSID = "000000"
451  elif isinstance(generatorInfo, dict):
452  if "Pythia8" in generatorInfo:
453  DSID = "410470"
454  elif "Sherpa" in generatorInfo and "2.2.8" in generatorInfo["Sherpa"]:
455  DSID = "421152"
456  elif "Sherpa" in generatorInfo and "2.2.10" in generatorInfo["Sherpa"]:
457  DSID = "700122"
458  elif "Sherpa" in generatorInfo and "2.2.11" in generatorInfo["Sherpa"]:
459  log.warning("HF production fraction reweighting is not configured for Sherpa 2.2.11. Using weights for Sherpa 2.2.10 instead.")
460  DSID = "700122"
461  elif "Sherpa" in generatorInfo and "2.2.12" in generatorInfo["Sherpa"]:
462  log.warning("HF production fraction reweighting is not configured for Sherpa 2.2.12. Using weights for Sherpa 2.2.10 instead.")
463  DSID = "700122"
464  elif "Sherpa" in generatorInfo and "2.2.14" in generatorInfo["Sherpa"]:
465  log.warning("HF production fraction reweighting is not configured for Sherpa 2.2.14. New weights need to be calculated.")
466  DSID = "000000"
467  elif "Sherpa" in generatorInfo and "2.2.1" in generatorInfo["Sherpa"]:
468  DSID = "410250"
469  elif "Herwig7" in generatorInfo and "7.1.3" in generatorInfo["Herwig7"]:
470  DSID = "411233"
471  elif "Herwig7" in generatorInfo and "7.2.1" in generatorInfo["Herwig7"]:
472  DSID = "600666"
473  elif "Herwig7" in generatorInfo and "7." in generatorInfo["Herwig7"]:
474  DSID = "410558"
475  elif "amc@NLO" in generatorInfo:
476  DSID = "410464"
477  else:
478  log.warning(f"HF production fraction reweighting is not configured for this generator: {generatorInfo}")
479  log.warning("New weights need to be calculated.")
480  DSID = "000000"
481  else:
482  log.warning("Failed to determine generator from metadata")
483  DSID = "000000"
484 
485  log.info(f"Using HF production fraction weights calculated using DSID {DSID}")
486  if DSID == "000000":
487  log.warning("HF production fraction reweighting will return dummy weights of 1.0")
488 
489  alg = config.createAlgorithm( 'CP::SysTruthWeightAlg', 'SysTruthWeightAlg' + self.streamName )
490  config.addPrivateTool( 'sysTruthWeightTool', 'PMGTools::PMGHFProductionFractionTool' )
491  alg.decoration = 'prodFracWeight_%SYS%'
492  alg.TruthParticleContainer = self.truthParticleContainer
493  alg.sysTruthWeightTool.ShowerGenerator = DSID
494  config.addOutputVar ('EventInfo', 'prodFracWeight_%SYS%', 'weight_HF_prod_frac')
495 
496 class PtEtaSelectionBlock (ConfigBlock):
497  """the ConfigBlock for a pt-eta selection"""
498 
499  def __init__ (self) :
500  super (PtEtaSelectionBlock, self).__init__ ()
501  self.addOption ('containerName', '', type=str,
502  noneAction='error',
503  info="the name of the input container.")
504  self.addOption ('selectionName', '', type=str,
505  noneAction='error',
506  info="the name of the selection to append this to. The default is "
507  "'' (empty string), meaning that the cuts are applied to every "
508  "object within the container. Specifying a name (e.g. loose) "
509  "applies the cut only to those object who also pass that selection.")
510  self.addOption ('minPt', None, type=float,
511  info="minimum pT value to cut on, in MeV. No default value.")
512  self.addOption ('maxPt', None, type=float,
513  info="maximum pT value to cut on, in MeV. No default value.")
514  self.addOption ('minEta', None, type=float,
515  info="minimum |eta| value to cut on. No default value.")
516  self.addOption ('maxEta', None, type=float,
517  info="maximum |eta| value to cut on. No default value.")
518  self.addOption ('maxRapidity', None, type=float,
519  info="maximum rapidity value to cut on. No default value.")
520  self.addOption ('etaGapLow', None, type=float,
521  info="low end of the |eta| gap. No default value.")
522  self.addOption ('etaGapHigh', None, type=float,
523  info="high end of the |eta| gap. No default value.")
524  self.addOption ('selectionDecoration', None, type=str,
525  info="the name of the decoration to set. If 'None', will be set "
526  "to 'selectPtEta' followed by the selection name.")
527  self.addOption ('useClusterEta', False, type=bool,
528  info="whether to use the cluster eta (etaBE(2)) instead of the object "
529  "eta (for electrons and photons). The default is False.")
530  self.addOption ('useDressedProperties', False, type=bool,
531  info="whether to use the dressed kinematic properties "
532  "(for truth particles only). The default is False.")
533 
534  def instanceName (self) :
535  """Return the instance name for this block"""
536  return self.containerName + "_" + self.selectionName
537 
538  def makeAlgs (self, config) :
539 
540  alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'PtEtaSelectionAlg' )
541  config.addPrivateTool( 'selectionTool', 'CP::AsgPtEtaSelectionTool' )
542  if self.minPt is not None :
543  alg.selectionTool.minPt = self.minPt
544  if self.maxPt is not None:
545  alg.selectionTool.maxPt = self.maxPt
546  if self.minEta is not None:
547  alg.selectionTool.minEta = self.minEta
548  if self.maxEta is not None :
549  alg.selectionTool.maxEta = self.maxEta
550  if self.maxRapidity is not None :
551  alg.selectionTool.maxRapidity = self.maxRapidity
552  if self.etaGapLow is not None:
553  alg.selectionTool.etaGapLow = self.etaGapLow
554  if self.etaGapHigh is not None:
555  alg.selectionTool.etaGapHigh = self.etaGapHigh
556  if self.selectionDecoration is None:
557  self.selectionDecoration = 'selectPtEta' + (f'_{self.selectionName}' if self.selectionName else '')
558  alg.selectionTool.useClusterEta = self.useClusterEta
559  alg.selectionTool.useDressedProperties = self.useDressedProperties
560  alg.selectionDecoration = self.selectionDecoration
561  alg.particles = config.readName (self.containerName)
562  alg.preselection = config.getPreselection (self.containerName, '')
563  config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration)
564 
565 
566 
567 class ObjectCutFlowBlock (ConfigBlock):
568  """the ConfigBlock for an object cutflow"""
569 
570  def __init__ (self) :
571  super (ObjectCutFlowBlock, self).__init__ ()
572  self.addOption ('containerName', '', type=str,
573  noneAction='error',
574  info="the name of the input container.")
575  self.addOption ('selectionName', '', type=str,
576  noneAction='error',
577  info="the name of the selection to perform the cutflow for. The "
578  "default is '' (empty string), meaning that the cutflow is "
579  "performed for every object within the container. Specifying a "
580  "name (e.g. loose) generates the cutflow only for those object "
581  "that also pass that selection.")
582  self.addOption ('forceCutSequence', False, type=bool,
583  info="whether to force the cut sequence and not accept objects "
584  "if previous cuts failed. The default is False.")
585 
586  def instanceName (self) :
587  """Return the instance name for this block"""
588  return self.containerName + '_' + self.selectionName
589 
590  def makeAlgs (self, config) :
591 
592  alg = config.createAlgorithm( 'CP::ObjectCutFlowHistAlg', 'CutFlowDumperAlg' )
593  alg.histPattern = 'cflow_' + self.containerName + "_" + self.selectionName + '_%SYS%'
594  alg.selections = config.getSelectionCutFlow (self.containerName, self.selectionName)
595  alg.input = config.readName (self.containerName)
596  alg.histTitle = "Object Cutflow: " + self.containerName + "." + self.selectionName
597  alg.forceCutSequence = self.forceCutSequence
598 
599 
600 class EventCutFlowBlock (ConfigBlock):
601  """the ConfigBlock for an event-level cutflow"""
602 
603  def __init__ (self) :
604  super (EventCutFlowBlock, self).__init__ ()
605  self.addOption ('containerName', '', type=str,
606  noneAction='error',
607  info="the name of the input container, typically EventInfo.")
608  self.addOption ('selectionName', '', type=str,
609  noneAction='error',
610  info="the name of an optional selection decoration to use.")
611  self.addOption ('customSelections', [], type=None,
612  info="the selections for which to generate cutflow histograms. If "
613  "a single string, corresponding to a particular event selection, "
614  "the event cutflow for that selection will be looked up. If a list "
615  "of strings, will use explicitly those selections. If left blank, "
616  "all selections attached to the container will be looked up.")
617  self.addOption ('postfix', '', type=str,
618  info="a postfix to apply in the naming of cutflow histograms. Set "
619  "it when defining multiple cutflows.")
620 
621  def instanceName (self) :
622  """Return the instance name for this block"""
623  return self.containerName + '_' + self.selectionName + self.postfix
624 
625  def makeAlgs (self, config) :
626 
627  postfix = self.postfix
628  if postfix != '' and postfix[0] != '_' :
629  postfix = '_' + postfix
630 
631  alg = config.createAlgorithm( 'CP::EventCutFlowHistAlg', 'CutFlowDumperAlg' )
632  alg.histPattern = 'cflow_' + self.containerName + "_" + self.selectionName + postfix + '_%SYS%'
633  # find out which selection decorations to use
634  if isinstance(self.customSelections, str):
635  # user provides a dynamic reference to selections, corresponding to an EventSelection alg
636  alg.selections = config.getEventCutFlow(self.customSelections)
637  elif len(self.customSelections) > 0:
638  # user provides a list of hardcoded selections
639  alg.selections = self.customSelections
640  else:
641  # user provides nothing: get all available selections from EventInfo directly
642  alg.selections = config.getSelectionCutFlow (self.containerName, self.selectionName)
643  alg.selections = [sel+',as_char' for sel in alg.selections]
644  if self.selectionName:
645  alg.preselection = self.selectionName + '_%SYS%'
646  alg.eventInfo = config.readName (self.containerName)
647  alg.histTitle = "Event Cutflow: " + self.containerName + "." + self.selectionName
648 
649 
650 class OutputThinningBlock (ConfigBlock):
651  """the ConfigBlock for output thinning"""
652 
653  def __init__ (self) :
654  super (OutputThinningBlock, self).__init__ ()
655  self.addOption ('containerName', '', type=str,
656  noneAction='error',
657  info="the name of the input container.")
658  self.addOption ('postfix', '', type=str,
659  info="a postfix to apply to decorations and algorithm names. "
660  "Typically not needed here.")
661  self.addOption ('selection', '', type=str,
662  info="the name of an optional selection decoration to use.")
663  self.addOption ('selectionName', '', type=str,
664  info="the name of the selection to append this to. The default is "
665  "'' (empty string), meaning that the cuts are applied to every "
666  "object within the container. Specifying a name (e.g. loose) "
667  "applies the cut only to those object who also pass that selection.")
668  self.addOption ('outputName', None, type=str,
669  info="an optional name for the output container.")
670  # TODO: add info string
671  self.addOption ('deepCopy', False, type=bool,
672  info="")
673  self.addOption ('sortPt', False, type=bool,
674  info="whether to sort objects in pt")
675  # TODO: add info string
676  self.addOption ('noUniformSelection', False, type=bool,
677  info="")
678 
679  def instanceName (self) :
680  """Return the instance name for this block"""
681  return self.containerName + '_' + self.selectionName + self.postfix
682 
683  def makeAlgs (self, config) :
684 
685  postfix = self.postfix
686  if postfix != '' and postfix[0] != '_' :
687  postfix = '_' + postfix
688 
689  selection = config.getFullSelection (self.containerName, self.selectionName)
690  if selection == '' :
691  selection = self.selection
692  elif self.selection != '' :
693  selection = selection + '&&' + self.selection
694 
695  if selection != '' and not self.noUniformSelection :
696  alg = config.createAlgorithm( 'CP::AsgUnionSelectionAlg', 'UnionSelectionAlg')
697  alg.preselection = selection
698  alg.particles = config.readName (self.containerName)
699  alg.selectionDecoration = 'outputSelect' + postfix
700  config.addSelection (self.containerName, alg.selectionDecoration, selection)
701  selection = 'outputSelect' + postfix
702 
703  alg = config.createAlgorithm( 'CP::AsgViewFromSelectionAlg', 'DeepCopyAlg' )
704  alg.input = config.readName (self.containerName)
705  if self.outputName is not None :
706  alg.output = self.outputName + '_%SYS%'
707  config.addOutputContainer (self.containerName, self.outputName)
708  else :
709  alg.output = config.copyName (self.containerName)
710  if selection != '' :
711  alg.selection = [selection]
712  else :
713  alg.selection = []
714  alg.deepCopy = self.deepCopy
715  if self.sortPt and not config.noSystematics() :
716  raise ValueError ("Sorting by pt is not supported with systematics")
717  alg.sortPt = self.sortPt
718 
719 
720 class IFFLeptonDecorationBlock (ConfigBlock):
721  """the ConfigBlock for the IFF classification of leptons"""
722 
723  def __init__ (self) :
724  super (IFFLeptonDecorationBlock, self).__init__()
725  self.addOption ('containerName', '', type=str,
726  noneAction='error',
727  info="the name of the input electron or muon container.")
728  self.addOption ('separateChargeFlipElectrons', True, type=bool,
729  info="whether to consider charged-flip electrons as a separate class. "
730  "The default is True (recommended).")
731  self.addOption ('decoration', 'IFFClass_%SYS%', type=str,
732  info="the name (str) of the decoration set by the IFF "
733  "TruthClassificationTool. The default is 'IFFClass_%SYS%'.")
734  # Always skip on data
735  self.setOptionValue('skipOnData', True)
736 
737  def instanceName (self) :
738  """Return the instance name for this block"""
739  return self.containerName
740 
741  def makeAlgs (self, config) :
742  particles = config.readName(self.containerName)
743 
744  alg = config.createAlgorithm( 'CP::AsgClassificationDecorationAlg', 'IFFClassifierAlg' )
745  # the IFF classification tool
746  config.addPrivateTool( 'tool', 'TruthClassificationTool')
747  # label charge-flipped electrons as such
748  alg.tool.separateChargeFlipElectrons = self.separateChargeFlipElectrons
749  alg.decoration = self.decoration
750  alg.particles = particles
751 
752  # write the decoration only once to the output
753  config.addOutputVar(self.containerName, alg.decoration, alg.decoration.split("_%SYS%")[0], noSys=True)
754 
755 
756 class MCTCLeptonDecorationBlock (ConfigBlock):
757 
758  def __init__ (self) :
759  super (MCTCLeptonDecorationBlock, self).__init__ ()
760 
761  self.addOption ("containerName", '', type=str,
762  noneAction='error',
763  info="the input lepton container, with a possible selection, "
764  "in the format container or container.selection.")
765  self.addOption ("prefix", 'MCTC_', type=str,
766  info="the prefix (str) of the decorations based on the MCTC "
767  "classification. The default is 'MCTC_'.")
768  # Always skip on data
769  self.setOptionValue('skipOnData', True)
770 
771  def instanceName (self) :
772  """Return the instance name for this block"""
773  return self.containerName
774 
775  def makeAlgs (self, config) :
776  particles, selection = config.readNameAndSelection(self.containerName)
777 
778  alg = config.createAlgorithm ("CP::MCTCDecorationAlg", "MCTCDecorationAlg")
779  alg.particles = particles
780  alg.preselection = selection
781  alg.affectingSystematicsFilter = '.*'
782  config.addOutputVar (self.containerName, "MCTC_isPrompt", f"{self.prefix}isPrompt", noSys=True)
783  config.addOutputVar (self.containerName, "MCTC_fromHadron", f"{self.prefix}fromHadron", noSys=True)
784  config.addOutputVar (self.containerName, "MCTC_fromBSM", f"{self.prefix}fromBSM", noSys=True)
785  config.addOutputVar (self.containerName, "MCTC_fromTau", f"{self.prefix}fromTau", noSys=True)
786 
787 
788 class PerEventSFBlock (ConfigBlock):
789  """the ConfigBlock for the AsgEventScaleFactorAlg"""
790 
791  def __init__ (self):
792  super(PerEventSFBlock, self).__init__()
793  self.addOption('algoName', None, type=str,
794  info="unique name given to the underlying algorithm computing the "
795  "per-event scale factors")
796  self.addOption('particles', '', type=str,
797  info="the input object container, with a possible selection, in the "
798  "format container or container.selection.")
799  self.addOption('objectSF', '', type=str,
800  info="the name of the per-object SF decoration to be used.")
801  self.addOption('eventSF', '', type=str,
802  info="the name of the per-event SF decoration.")
803 
804  def instanceName (self) :
805  """Return the instance name for this block"""
806  return self.particles + '_' + self.objectSF + '_' + self.eventSF
807 
808  def makeAlgs(self, config):
809  if config.dataType() is DataType.Data:
810  return
811  particles, selection = config.readNameAndSelection(self.particles)
812  alg = config.createAlgorithm('CP::AsgEventScaleFactorAlg', self.algoName if self.algoName else 'AsgEventScaleFactorAlg')
813  alg.particles = particles
814  alg.preselection = selection
815  alg.scaleFactorInputDecoration = self.objectSF
816  alg.scaleFactorOutputDecoration = self.eventSF
817 
818  config.addOutputVar('EventInfo', alg.scaleFactorOutputDecoration,
819  alg.scaleFactorOutputDecoration.split("_%SYS%")[0])
820 
821 
822 class SelectionDecorationBlock (ConfigBlock):
823  """the ConfigBlock to add selection decoration to a container"""
824 
825  def __init__ (self) :
826  super (SelectionDecorationBlock, self).__init__ ()
827  # TODO: add info string
828  self.addOption('containers', [], type=list,
829  noneAction='error',
830  info="")
831 
832  def instanceName (self) :
833  """Return the instance name for this block"""
834  return ''
835 
836  def makeAlgs(self, config):
837  for container in self.containers:
838  originContainerName = config.getOutputContainerOrigin(container)
839  selectionNames = config.getSelectionNames(originContainerName)
840  for selectionName in selectionNames:
841  # skip default selection
842  if selectionName == '':
843  continue
844  alg = config.createAlgorithm(
845  'CP::AsgSelectionAlg',
846  f'SelectionDecoration_{originContainerName}_{selectionName}')
847  selectionDecoration = f'baselineSelection_{selectionName}_%SYS%'
848  alg.selectionDecoration = f'{selectionDecoration},as_char'
849  alg.particles = config.readName (originContainerName)
850  alg.preselection = config.getFullSelection (originContainerName,
851  selectionName)
852  config.addOutputVar(
853  originContainerName, selectionDecoration, selectionName)
854 
855 def makeEventCutFlowConfig(seq, containerName,
856  *, postfix=None, selectionName, customSelections=None):
857  """Create an event-level cutflow config
858 
859  Keyword arguments:
860  containerName -- name of the container
861  postfix -- a postfix to apply to decorations and algorithm names.
862  selectionName -- the name of the selection to do the cutflow for
863  customSelections -- a list of decorations to use in the cutflow, to override the retrieval of all decorations
864  """
865 
866  config = EventCutFlowBlock()
867  config.setOptionValue('containerName', containerName)
868  config.setOptionValue('selectionName', selectionName)
869  config.setOptionValue('postfix', postfix)
870  config.setOptionValue('customSelections', customSelections)
871  seq.append(config)
python.AsgAnalysisConfig.PerEventSFBlock.__init__
def __init__(self)
Definition: AsgAnalysisConfig.py:791
python.AutoConfigFlags.GetFileMD
def GetFileMD(filenames, allowEmpty=True, maxLevel='peeker')
Definition: AutoConfigFlags.py:65
python.AsgAnalysisConfig.GeneratorAnalysisBlock
Definition: AsgAnalysisConfig.py:372
python.AsgAnalysisConfig.PileupReweightingBlock
Definition: AsgAnalysisConfig.py:185
python.AsgAnalysisConfig.IOStatsBlock
Definition: AsgAnalysisConfig.py:168
python.AsgAnalysisConfig.PtEtaSelectionBlock.makeAlgs
def makeAlgs(self, config)
Definition: AsgAnalysisConfig.py:538
python.AsgAnalysisConfig.SelectionDecorationBlock.instanceName
def instanceName(self)
Definition: AsgAnalysisConfig.py:832
python.AsgAnalysisConfig.PtEtaSelectionBlock.__init__
def __init__(self)
Definition: AsgAnalysisConfig.py:499
python.AsgAnalysisConfig.PtEtaSelectionBlock.selectionDecoration
selectionDecoration
Definition: AsgAnalysisConfig.py:557
python.AsgAnalysisConfig.OutputThinningBlock.__init__
def __init__(self)
Definition: AsgAnalysisConfig.py:653
python.AsgAnalysisConfig.makeEventCutFlowConfig
def makeEventCutFlowConfig(seq, containerName, *postfix=None, selectionName, customSelections=None)
Definition: AsgAnalysisConfig.py:855
python.AsgAnalysisConfig.MCTCLeptonDecorationBlock.__init__
def __init__(self)
Definition: AsgAnalysisConfig.py:758
python.AsgAnalysisConfig.ObjectCutFlowBlock.makeAlgs
def makeAlgs(self, config)
Definition: AsgAnalysisConfig.py:590
python.AsgAnalysisConfig.ObjectCutFlowBlock.instanceName
def instanceName(self)
Definition: AsgAnalysisConfig.py:586
python.AsgAnalysisConfig.SelectionDecorationBlock
Definition: AsgAnalysisConfig.py:822
python.AsgAnalysisConfig.EventCutFlowBlock
Definition: AsgAnalysisConfig.py:600
python.AsgAnalysisConfig.PerEventSFBlock
Definition: AsgAnalysisConfig.py:788
python.AsgAnalysisConfig.CommonServicesConfig.runSystematics
runSystematics
Definition: AsgAnalysisConfig.py:83
python.AsgAnalysisConfig.IOStatsBlock.makeAlgs
def makeAlgs(self, config)
Definition: AsgAnalysisConfig.py:180
python.AsgAnalysisConfig.SystematicsCategories
Definition: AsgAnalysisConfig.py:16
python.AsgAnalysisConfig.IFFLeptonDecorationBlock.__init__
def __init__(self)
Definition: AsgAnalysisConfig.py:723
python.AsgAnalysisConfig.OutputThinningBlock
Definition: AsgAnalysisConfig.py:650
python.AsgAnalysisConfig.GeneratorAnalysisBlock.makeAlgs
def makeAlgs(self, config)
Definition: AsgAnalysisConfig.py:405
python.AsgAnalysisConfig.OutputThinningBlock.makeAlgs
def makeAlgs(self, config)
Definition: AsgAnalysisConfig.py:683
python.AsgAnalysisConfig.PileupReweightingBlock.files
files
Definition: AsgAnalysisConfig.py:252
python.AsgAnalysisConfig.CommonServicesConfig.__init__
def __init__(self)
Definition: AsgAnalysisConfig.py:36
python.AsgAnalysisConfig.PileupReweightingBlock.instanceName
def instanceName(self)
Definition: AsgAnalysisConfig.py:219
python.AutoconfigurePRW.getConfigurationFiles
def getConfigurationFiles(campaign=None, dsid=None, data_type=None, files=None, useDefaultConfig=False)
Definition: AutoconfigurePRW.py:127
python.AsgAnalysisConfig.PerEventSFBlock.makeAlgs
def makeAlgs(self, config)
Definition: AsgAnalysisConfig.py:808
python.AsgAnalysisConfig.OutputThinningBlock.instanceName
def instanceName(self)
Definition: AsgAnalysisConfig.py:679
python.AsgAnalysisConfig.GeneratorAnalysisBlock.__init__
def __init__(self)
Definition: AsgAnalysisConfig.py:375
python.AsgAnalysisConfig.PileupReweightingBlock.__init__
def __init__(self)
Definition: AsgAnalysisConfig.py:188
python.AsgAnalysisConfig.ObjectCutFlowBlock
Definition: AsgAnalysisConfig.py:567
python.AsgAnalysisConfig.ObjectCutFlowBlock.__init__
def __init__(self)
Definition: AsgAnalysisConfig.py:570
python.AsgAnalysisConfig.IFFLeptonDecorationBlock.instanceName
def instanceName(self)
Definition: AsgAnalysisConfig.py:737
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
python.AsgAnalysisConfig.SelectionDecorationBlock.__init__
def __init__(self)
Definition: AsgAnalysisConfig.py:825
python.AsgAnalysisConfig.EventCutFlowBlock.instanceName
def instanceName(self)
Definition: AsgAnalysisConfig.py:621
python.AsgAnalysisConfig.CommonServicesConfig
Definition: AsgAnalysisConfig.py:28
python.AsgAnalysisConfig.MCTCLeptonDecorationBlock
Definition: AsgAnalysisConfig.py:756
python.AsgAnalysisConfig.IOStatsBlock.__init__
def __init__(self)
Definition: AsgAnalysisConfig.py:171
python.AsgAnalysisConfig.CommonServicesConfig.makeAlgs
def makeAlgs(self, config)
Definition: AsgAnalysisConfig.py:74
python.AsgAnalysisConfig.EventCutFlowBlock.makeAlgs
def makeAlgs(self, config)
Definition: AsgAnalysisConfig.py:625
python.AsgAnalysisConfig.MCTCLeptonDecorationBlock.instanceName
def instanceName(self)
Definition: AsgAnalysisConfig.py:771
python.AsgAnalysisConfig.CommonServices
def CommonServices(seq)
Definition: AsgAnalysisConfig.py:163
python.AsgAnalysisConfig.EventCutFlowBlock.__init__
def __init__(self)
Definition: AsgAnalysisConfig.py:603
python.AsgAnalysisConfig.IFFLeptonDecorationBlock
Definition: AsgAnalysisConfig.py:720
python.AsgAnalysisConfig.GeneratorAnalysisBlock.instanceName
def instanceName(self)
Definition: AsgAnalysisConfig.py:401
python.AsgAnalysisConfig.IFFLeptonDecorationBlock.makeAlgs
def makeAlgs(self, config)
Definition: AsgAnalysisConfig.py:741
python.AsgAnalysisConfig.IOStatsBlock.instanceName
def instanceName(self)
Definition: AsgAnalysisConfig.py:176
python.AsgAnalysisConfig.CommonServicesConfig.instanceName
def instanceName(self)
Definition: AsgAnalysisConfig.py:70
str
Definition: BTagTrackIpAccessor.cxx:11
python.AsgAnalysisConfig.GeneratorAnalysisBlock.runNumber
runNumber
Definition: AsgAnalysisConfig.py:413
python.AutoconfigurePRW.getLumicalcFiles
def getLumicalcFiles(campaign)
Definition: AutoconfigurePRW.py:6
python.AsgAnalysisConfig.PerEventSFBlock.instanceName
def instanceName(self)
Definition: AsgAnalysisConfig.py:804
python.AsgAnalysisConfig.PileupReweightingBlock.makeAlgs
def makeAlgs(self, config)
Definition: AsgAnalysisConfig.py:223
python.AsgAnalysisConfig.SelectionDecorationBlock.makeAlgs
def makeAlgs(self, config)
Definition: AsgAnalysisConfig.py:836
python.AsgAnalysisConfig.MCTCLeptonDecorationBlock.makeAlgs
def makeAlgs(self, config)
Definition: AsgAnalysisConfig.py:775
python.AsgAnalysisConfig.PtEtaSelectionBlock.instanceName
def instanceName(self)
Definition: AsgAnalysisConfig.py:534
python.AsgAnalysisConfig.CommonServicesConfig.onlySystematicsCategories
onlySystematicsCategories
Definition: AsgAnalysisConfig.py:92
python.Utils.getMCCampaign
def getMCCampaign(files)
Definition: Tools/Campaigns/python/Utils.py:38
python.AsgAnalysisConfig.PtEtaSelectionBlock
Definition: AsgAnalysisConfig.py:496