ATLAS Offline Software
PhotonAnalysisConfig.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 AthenaCommon.SystemOfUnits import GeV
6 from AthenaConfiguration.Enums import LHCPeriod
7 from AnalysisAlgorithmsConfig.ConfigAccumulator import DataType
8 from AthenaCommon.Logging import logging
9 
10 import ROOT
11 
12 # E/gamma import(s).
13 from xAODEgamma.xAODEgammaParameters import xAOD
14 
16 
17 class PhotonCalibrationConfig (ConfigBlock) :
18  """the ConfigBlock for the photon four-momentum correction"""
19 
20  def __init__ (self, containerName='') :
21  super (PhotonCalibrationConfig, self).__init__ ()
22  self.setBlockName('Photons')
23  self.addOption ('containerName', containerName, type=str,
24  noneAction='error',
25  info="the name of the output container after calibration.")
26  self.addOption ('ESModel', '', type=str,
27  info="flag of egamma calibration recommendation.")
28  self.addOption ('decorrelationModel', '1NP_v1', type=str,
29  info="egamma energy scale decorrelationModel. The default is 1NP_v1. "
30  "Supported Model: 1NP_v1, FULL_v1.")
31  self.addOption ('postfix', '', type=str,
32  info="a postfix to apply to decorations and algorithm names. "
33  "Typically not needed here since the calibration is common to "
34  "all photons.")
35  self.addOption ('crackVeto', False, type=bool,
36  info="whether to perform LAr crack veto based on the cluster eta, "
37  "i.e. remove photons within 1.37<|eta|<1.52. "
38  "The default is False.")
39  self.addOption ('enableCleaning', True, type=bool,
40  info="whether to enable photon cleaning (DFCommonPhotonsCleaning). "
41  "The default is True.")
42  self.addOption ('cleaningAllowLate', False, type=bool,
43  info="whether to ignore timing information in cleaning "
44  "(DFCommonPhotonsCleaningNoTime). The default is False.")
45  self.addOption ('recomputeIsEM', False, type=bool,
46  info="whether to recompute the photon shower shape fudge "
47  "corrections (sets up an instance of CP::PhotonShowerShapeFudgeAlg). "
48  "The default is False, i.e. to use derivation variables.")
49  self.addOption ('recalibratePhyslite', True, type=bool,
50  info="whether to run the CP::EgammaCalibrationAndSmearingAlg on "
51  "PHYSLITE derivations. The default is True.")
52  self.addOption ('minPt', 10*GeV, type=float,
53  info="the minimum pT cut to apply to calibrated photons. "
54  "The default is 10 GeV.")
55  self.addOption ('maxEta', 2.37, type=float,
56  info="maximum photon |eta| (float). The default is 2.37.")
57  self.addOption ('forceFullSimConfig', False, type=bool,
58  info="whether to force the tool to use the configuration meant for "
59  "full simulation samples. Only for testing purposes. "
60  "The default is False.")
61  self.addOption ('splitCalibrationAndSmearing', False, type=bool,
62  info="EXPERIMENTAL: This splits the EgammaCalibrationAndSmearingTool "
63  " into two steps. The first step applies a baseline calibration that "
64  "is not affected by systematics. The second step then applies the "
65  "systematics dependent corrections. The net effect is that the "
66  "slower first step only has to be run once, while the second is run "
67  "once per systematic. ATLASG-2358")
68  self.addOption ('decorateTruth', False, type=bool,
69  info="decorate truth particle information on the reconstructed one")
70  self.addOption ('decorateCaloClusterEta', False, type=bool,
71  info="decorate the calo cluster eta on the reconstructed one")
72 
73 
74  def makeCalibrationAndSmearingAlg (self, config, name) :
75  """Create the calibration and smearing algorithm
76 
77  Factoring this out into its own function, as we want to
78  instantiate it in multiple places"""
79  log = logging.getLogger('PhotonCalibrationConfig')
80 
81  # Set up the calibration and smearing algorithm:
82  alg = config.createAlgorithm( 'CP::EgammaCalibrationAndSmearingAlg', name + self.postfix )
83  config.addPrivateTool( 'calibrationAndSmearingTool',
84  'CP::EgammaCalibrationAndSmearingTool' )
85  # Set default ESModel per period
86  if self.ESModel:
87  alg.calibrationAndSmearingTool.ESModel = self.ESModel
88  else:
89  if config.geometry() is LHCPeriod.Run2:
90  alg.calibrationAndSmearingTool.ESModel = 'es2023_R22_Run2_v1'
91  elif config.geometry() is LHCPeriod.Run3:
92  alg.calibrationAndSmearingTool.ESModel = 'es2022_R22_PRE'
93  elif config.geometry() is LHCPeriod.Run4:
94  log.warning("No ESModel set for Run4, using Run3 model")
95  alg.calibrationAndSmearingTool.ESModel = 'es2022_R22_PRE'
96  else:
97  raise ValueError (f"Can't set up the ElectronCalibrationConfig with {config.geometry().value}, "
98  "there must be something wrong!")
99 
100  alg.calibrationAndSmearingTool.decorrelationModel = self.decorrelationModel
101  alg.calibrationAndSmearingTool.useFastSim = (
102  0 if self.forceFullSimConfig
103  else int( config.dataType() is DataType.FastSim ))
104  alg.egammas = config.readName (self.containerName)
105  alg.egammasOut = config.copyName (self.containerName)
106  alg.preselection = config.getPreselection (self.containerName, '')
107  return alg
108 
109 
110  def makeAlgs (self, config) :
111 
112  log = logging.getLogger('PhotonCalibrationConfig')
113 
114  postfix = self.postfix
115  if postfix != '' and postfix[0] != '_' :
116  postfix = '_' + postfix
117 
118  if self.forceFullSimConfig:
119  log.warning("You are running PhotonCalibrationConfig forcing full sim config")
120  log.warning("This is only intended to be used for testing purposes")
121 
122  if config.isPhyslite() :
123  config.setSourceName (self.containerName, "AnalysisPhotons")
124  else :
125  config.setSourceName (self.containerName, "Photons")
126 
127  cleaningWP = 'NoTime' if self.cleaningAllowLate else ''
128 
129  # Decorate calo cluster eta if required
130  if self.decorateCaloClusterEta:
131  alg = config.createAlgorithm( 'CP::EgammaCaloClusterEtaAlg', 'ElectronEgammaCaloClusterEtaAlg' + self.postfix )
132  alg.particles = config.readName(self.containerName)
133  config.addOutputVar (self.containerName, 'caloEta2', 'caloEta2', noSys=True)
134 
135  # Set up a shallow copy to decorate
136  if config.wantCopy (self.containerName) :
137  alg = config.createAlgorithm( 'CP::AsgShallowCopyAlg', 'PhotonShallowCopyAlg' + postfix )
138  alg.input = config.readName (self.containerName)
139  alg.output = config.copyName (self.containerName)
140 
141  # Set up the eta-cut on all photons prior to everything else
142  alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'PhotonEtaCutAlg' + postfix )
143  alg.selectionDecoration = 'selectEta' + postfix + ',as_bits'
144  config.addPrivateTool( 'selectionTool', 'CP::AsgPtEtaSelectionTool' )
145  alg.selectionTool.maxEta = self.maxEta
146  if self.crackVeto:
147  alg.selectionTool.etaGapLow = 1.37
148  alg.selectionTool.etaGapHigh = 1.52
149  alg.selectionTool.useClusterEta = True
150  alg.particles = config.readName (self.containerName)
151  alg.preselection = config.getPreselection (self.containerName, '')
152  config.addSelection (self.containerName, '', alg.selectionDecoration)
153 
154  # Setup shower shape fudge
155  if self.recomputeIsEM and config.dataType() is DataType.FullSim:
156  alg = config.createAlgorithm( 'CP::PhotonShowerShapeFudgeAlg',
157  'PhotonShowerShapeFudgeAlg' + postfix )
158  config.addPrivateTool( 'showerShapeFudgeTool',
159  'ElectronPhotonVariableCorrectionTool' )
160  if config.geometry is LHCPeriod.Run2:
161  alg.showerShapeFudgeTool.ConfigFile = \
162  'EGammaVariableCorrection/TUNE25/ElPhVariableNominalCorrection.conf'
163  if config.geometry is LHCPeriod.Run3:
164  alg.showerShapeFudgeTool.ConfigFile = \
165  'EGammaVariableCorrection/TUNE23/ElPhVariableNominalCorrection.conf'
166  alg.photons = config.readName (self.containerName)
167  alg.photonsOut = config.copyName (self.containerName)
168  alg.preselection = config.getPreselection (self.containerName, '')
169 
170  # Select photons only with good object quality.
171  alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'PhotonObjectQualityAlg' + postfix )
172  alg.selectionDecoration = 'goodOQ,as_bits'
173  config.addPrivateTool( 'selectionTool', 'CP::EgammaIsGoodOQSelectionTool' )
174  alg.selectionTool.Mask = xAOD.EgammaParameters.BADCLUSPHOTON
175  alg.particles = config.readName (self.containerName)
176  alg.preselection = config.getPreselection (self.containerName, '')
177  config.addSelection (self.containerName, '', alg.selectionDecoration)
178 
179  # Select clean photons
180  if self.enableCleaning:
181  alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'PhotonCleaningAlg' + postfix)
182  config.addPrivateTool( 'selectionTool', 'CP::AsgFlagSelectionTool' )
183  alg.selectionDecoration = 'isClean,as_bits'
184  alg.selectionTool.selectionFlags = ['DFCommonPhotonsCleaning' + cleaningWP]
185  alg.particles = config.readName (self.containerName)
186  alg.preselection = config.getPreselection (self.containerName, '')
187  config.addSelection (self.containerName, '', alg.selectionDecoration)
188 
189  # Change the origin of Photons from (0,0,0) to (0,0,z)
190  # where z comes from the position of a vertex
191  # Default the one tagged as Primary
192  alg = config.createAlgorithm( 'CP::PhotonOriginCorrectionAlg',
193  'PhotonOriginCorrectionAlg' + postfix )
194  alg.photons = config.readName (self.containerName)
195  alg.photonsOut = config.copyName (self.containerName)
196  alg.preselection = config.getPreselection (self.containerName, '')
197 
198  if not self.splitCalibrationAndSmearing :
199  # Set up the calibration and smearing algorithm:
200  alg = self.makeCalibrationAndSmearingAlg (config, 'PhotonCalibrationAndSmearingAlg')
201  if config.isPhyslite() and not self.recalibratePhyslite :
202  alg.skipNominal = True
203  else:
204  # This splits the EgammaCalibrationAndSmearingTool into two
205  # steps. The first step applies a baseline calibration that
206  # is not affected by systematics. The second step then
207  # applies the systematics dependent corrections. The net
208  # effect is that the slower first step only has to be run
209  # once, while the second is run once per systematic.
210  #
211  # For now (22 May 24) this has to happen in the same job, as
212  # the output of the first step is not part of PHYSLITE, and
213  # even for the nominal the output of the first and second
214  # step are different. In the future the plan is to put both
215  # the output of the first and second step into PHYSLITE,
216  # allowing to skip the first step when running on PHYSLITE.
217  #
218  # WARNING: All of this is experimental, see: ATLASG-2358
219 
220  # Set up the calibration algorithm:
221  alg = self.makeCalibrationAndSmearingAlg (config, 'PhotonBaseCalibrationAlg')
222  # turn off systematics for the calibration step
223  alg.noToolSystematics = True
224  # turn off smearing for the calibration step
225  alg.calibrationAndSmearingTool.doSmearing = False
226 
227  # Set up the smearing algorithm:
228  alg = self.makeCalibrationAndSmearingAlg (config, 'PhotonCalibrationSystematicsAlg')
229  # turn off scale corrections for the smearing step
230  alg.calibrationAndSmearingTool.doScaleCorrection = False
231  alg.calibrationAndSmearingTool.useMVACalibration = False
232 
233  if self.minPt > 0:
234  # Set up the the pt selection
235  alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'PhotonPtCutAlg' + postfix )
236  alg.selectionDecoration = 'selectPt' + postfix + ',as_bits'
237  config.addPrivateTool( 'selectionTool', 'CP::AsgPtEtaSelectionTool' )
238  alg.selectionTool.minPt = self.minPt
239  alg.particles = config.readName (self.containerName)
240  alg.preselection = config.getPreselection (self.containerName, '')
241  config.addSelection (self.containerName, '', alg.selectionDecoration,
242  preselection=True)
243 
244  # Set up the isolation correction algorithm.
245  alg = config.createAlgorithm( 'CP::EgammaIsolationCorrectionAlg',
246  'PhotonIsolationCorrectionAlg' + postfix )
247  config.addPrivateTool( 'isolationCorrectionTool',
248  'CP::IsolationCorrectionTool' )
249  alg.isolationCorrectionTool.IsMC = config.dataType() is not DataType.Data
250  alg.isolationCorrectionTool.AFII_corr = (
251  0 if self.forceFullSimConfig
252  else config.dataType() is DataType.FastSim)
253  alg.egammas = config.readName (self.containerName)
254  alg.egammasOut = config.copyName (self.containerName)
255  alg.preselection = config.getPreselection (self.containerName, '')
256 
257  # Additional decorations
258  alg = config.createAlgorithm( 'CP::AsgEnergyDecoratorAlg', 'EnergyDecorator' + self.containerName + self.postfix )
259  alg.particles = config.readName (self.containerName)
260 
261  config.addOutputVar (self.containerName, 'pt', 'pt')
262  config.addOutputVar (self.containerName, 'eta', 'eta', noSys=True)
263  config.addOutputVar (self.containerName, 'phi', 'phi', noSys=True)
264  config.addOutputVar (self.containerName, 'e_%SYS%', 'e')
265 
266  # decorate truth information on the reconstructed object:
267  if self.decorateTruth and config.dataType() is not DataType.Data:
268  config.addOutputVar (self.containerName, "truthType", "truth_type", noSys=True)
269  config.addOutputVar (self.containerName, "truthOrigin", "truth_origin", noSys=True)
270 
271 
272 class PhotonWorkingPointConfig (ConfigBlock) :
273  """the ConfigBlock for the photon working point
274 
275  This may at some point be split into multiple blocks (29 Aug 22)."""
276 
277  def __init__ (self, containerName='', selectionName='') :
278  super (PhotonWorkingPointConfig, self).__init__ ()
279  self.addOption ('containerName', containerName, type=str,
280  noneAction='error',
281  info="the name of the input container.")
282  self.addOption ('selectionName', selectionName, type=str,
283  noneAction='error',
284  info="the name of the photon selection to define (e.g. tight or "
285  "loose).")
286  self.addOption ('postfix', selectionName, type=str,
287  info="a postfix to apply to decorations and algorithm names. "
288  "Typically not needed here as selectionName is used internally.")
289  self.addOption ('qualityWP', None, type=str,
290  info="the ID WP (string) to use. Supported ID WPs: Tight, Medium and Loose.")
291  self.addOption ('isolationWP', None, type=str,
292  info="the ID WP (string) to use. Supported isolation WPs: "
293  "FixedCutLoose, FixedCutTight, TightCaloOnly, NonIso.")
294  self.addOption ('addSelectionToPreselection', True, type=bool,
295  info="whether to retain only photons satisfying the working point "
296  "requirements. The default is True.")
297  self.addOption ('closeByCorrection', False, type=bool,
298  info="whether to use close-by-corrected isolation working points")
299  self.addOption ('recomputeIsEM', False, type=bool,
300  info="whether to rerun the cut-based selection. The default is "
301  "False, i.e. to use derivation flags.")
302  self.addOption ('doFSRSelection', False, type=bool,
303  info="whether to accept additional photons close to muons for the "
304  "purpose of FSR corrections to these muons. Expert feature "
305  "requested by the H4l analysis running on PHYSLITE. "
306  "The default is False.")
307  self.addOption ('noEffSF', False, type=bool,
308  info="disables the calculation of efficiencies and scale factors. "
309  "Experimental! only useful to test a new WP for which scale "
310  "factors are not available. The default is False.")
311  self.addOption ('saveDetailedSF', True, type=bool,
312  info="save all the independent detailed object scale factors. "
313  "The default is True.")
314  self.addOption ('saveCombinedSF', False, type=bool,
315  info="save the combined object scale factor. "
316  "The default is False.")
317  self.addOption ('forceFullSimConfig', False, type=bool,
318  info="whether to force the tool to use the configuration meant "
319  "for full simulation samples. Only for testing purposes. "
320  "The default is False.")
321 
322  def makeAlgs (self, config) :
323 
324  log = logging.getLogger('PhotonWorkingPointConfig')
325 
326  # The setup below is inappropriate for Run 1
327  if config.geometry() is LHCPeriod.Run1:
328  raise ValueError ("Can't set up the PhotonWorkingPointConfig with %s, there must be something wrong!" % config.geometry().value)
329 
330  if self.forceFullSimConfig:
331  log.warning("You are running PhotonWorkingPointConfig forcing full sim config")
332  log.warning("This is only intended to be used for testing purposes")
333 
334  postfix = self.postfix
335  if postfix != '' and postfix[0] != '_' :
336  postfix = '_' + postfix
337 
338  if self.qualityWP == 'Tight' :
339  quality = ROOT.egammaPID.PhotonTight
340  elif self.qualityWP == 'Medium' :
341  quality = ROOT.egammaPID.PhotonMedium
342  elif self.qualityWP == 'Loose' :
343  quality = ROOT.egammaPID.PhotonLoose
344  else :
345  raise Exception ('unknown photon quality working point "' + self.qualityWP + '" should be Tight, Medium or Loose')
346 
347  # Set up the photon selection algorithm:
348  alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'PhotonIsEMSelectorAlg' + postfix )
349  alg.selectionDecoration = 'selectEM' + postfix + ',as_char'
350  if self.recomputeIsEM:
351  # Rerun the cut-based ID
352  config.addPrivateTool( 'selectionTool', 'AsgPhotonIsEMSelector' )
353  alg.selectionTool.isEMMask = quality
354  if config.geometry() is LHCPeriod.Run2:
355  if self.qualityWP == 'Tight':
356  alg.selectionTool.ConfigFile = 'ElectronPhotonSelectorTools/offline/mc20_20240510/PhotonIsEMTightSelectorCutDefs_pTdep_mc20_smooth.conf'
357  elif self.qualityWP == 'Loose':
358  alg.selectionTool.ConfigFile = 'ElectronPhotonSelectorTools/offline/mc15_20150712/PhotonIsEMLooseSelectorCutDefs.conf'
359  elif self.qualityWP == 'Medium':
360  alg.selectionTool.ConfigFile = 'ElectronPhotonSelectorTools/offline/mc20_20240510/PhotonIsEMMediumSelectorCutDefs_pTdep_smooth.conf'
361  if config.geometry() is LHCPeriod.Run3:
362  if self.qualityWP == 'Tight':
363  alg.selectionTool.ConfigFile = 'ElectronPhotonSelectorTools/offline/20180825/PhotonIsEMTightSelectorCutDefs.conf'
364  elif self.qualityWP == 'Loose':
365  alg.selectionTool.ConfigFile = 'ElectronPhotonSelectorTools/offline/mc15_20150712/PhotonIsEMLooseSelectorCutDefs.conf'
366  elif self.qualityWP == 'Medium':
367  raise ValueError('No Medium menu available for Run-3. Please get in contact with egamma')
368  else:
369  # Select from Derivation Framework flags
370  config.addPrivateTool( 'selectionTool', 'CP::AsgFlagSelectionTool' )
371  dfFlag = 'DFCommonPhotonsIsEM' + self.qualityWP
372  alg.selectionTool.selectionFlags = [ dfFlag ]
373  alg.particles = config.readName (self.containerName)
374  alg.preselection = config.getPreselection (self.containerName, self.selectionName)
375  config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration,
376  preselection=self.addSelectionToPreselection)
377 
378  # Set up the FSR selection
379  if self.doFSRSelection :
380  # save the flag set for the WP
381  wpFlag = alg.selectionDecoration.split(",")[0]
382  alg = config.createAlgorithm( 'CP::EgammaFSRForMuonsCollectorAlg', 'EgammaFSRForMuonsCollectorAlg' + postfix + '_ph') # added extra postfix to avoid name clash with electrons
383  alg.selectionDecoration = wpFlag
384  alg.ElectronOrPhotonContKey = config.readName (self.containerName)
385 
386  # Set up the isolation selection algorithm:
387  if self.isolationWP != 'NonIso' :
388  alg = config.createAlgorithm( 'CP::EgammaIsolationSelectionAlg',
389  'PhotonIsolationSelectionAlg' + postfix )
390  alg.selectionDecoration = 'isolated' + postfix + ',as_char'
391  config.addPrivateTool( 'selectionTool', 'CP::IsolationSelectionTool' )
392  alg.selectionTool.PhotonWP = self.isolationWP
393  if self.closeByCorrection:
394  alg.selectionTool.IsoDecSuffix = "CloseByCorr"
395  alg.isPhoton = True
396  alg.egammas = config.readName (self.containerName)
397  alg.preselection = config.getPreselection (self.containerName, self.selectionName)
398  config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration,
399  preselection=self.addSelectionToPreselection)
400 
401  sfList = []
402  # Set up the ID/reco photon efficiency correction algorithm:
403  if config.dataType() is not DataType.Data and not self.noEffSF:
404  alg = config.createAlgorithm( 'CP::PhotonEfficiencyCorrectionAlg',
405  'PhotonEfficiencyCorrectionAlgID' + postfix )
406  config.addPrivateTool( 'efficiencyCorrectionTool',
407  'AsgPhotonEfficiencyCorrectionTool' )
408  alg.scaleFactorDecoration = 'ph_id_effSF' + postfix + '_%SYS%'
409  if config.dataType() is DataType.FastSim:
410  alg.efficiencyCorrectionTool.ForceDataType = (
411  PATCore.ParticleDataType.Full if self.forceFullSimConfig else
412  PATCore.ParticleDataType.Fast)
413  elif config.dataType() is DataType.FullSim:
414  alg.efficiencyCorrectionTool.ForceDataType = \
415  PATCore.ParticleDataType.Full
416  if config.geometry() >= LHCPeriod.Run2:
417  alg.efficiencyCorrectionTool.MapFilePath = 'PhotonEfficiencyCorrection/2015_2025/rel22.2/2024_FinalRun2_Recommendation_v1/map1.txt'
418  alg.outOfValidity = 2 #silent
419  alg.outOfValidityDeco = 'ph_id_bad_eff' + postfix
420  alg.photons = config.readName (self.containerName)
421  alg.preselection = config.getPreselection (self.containerName, self.selectionName)
422  if self.saveDetailedSF:
423  config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
424  'id_effSF' + postfix)
425  sfList += [alg.scaleFactorDecoration]
426 
427  # Set up the ISO photon efficiency correction algorithm:
428  if config.dataType() is not DataType.Data and self.isolationWP != 'NonIso' and not self.noEffSF:
429  alg = config.createAlgorithm( 'CP::PhotonEfficiencyCorrectionAlg',
430  'PhotonEfficiencyCorrectionAlgIsol' + postfix )
431  config.addPrivateTool( 'efficiencyCorrectionTool',
432  'AsgPhotonEfficiencyCorrectionTool' )
433  alg.scaleFactorDecoration = 'ph_isol_effSF' + postfix + '_%SYS%'
434  if config.dataType() is DataType.FastSim:
435  alg.efficiencyCorrectionTool.ForceDataType = (
436  PATCore.ParticleDataType.Full if self.forceFullSimConfig else
437  PATCore.ParticleDataType.Fast)
438  elif config.dataType() is DataType.FullSim:
439  alg.efficiencyCorrectionTool.ForceDataType = \
440  PATCore.ParticleDataType.Full
441  alg.efficiencyCorrectionTool.IsoKey = self.isolationWP.replace("FixedCut","")
442  if config.geometry() >= LHCPeriod.Run2:
443  alg.efficiencyCorrectionTool.MapFilePath = 'PhotonEfficiencyCorrection/2015_2025/rel22.2/2022_Summer_Prerecom_v1/map0.txt'
444  alg.outOfValidity = 2 #silent
445  alg.outOfValidityDeco = 'ph_isol_bad_eff' + postfix
446  alg.photons = config.readName (self.containerName)
447  alg.preselection = config.getPreselection (self.containerName, self.selectionName)
448  if self.saveDetailedSF:
449  config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
450  'isol_effSF' + postfix)
451  sfList += [alg.scaleFactorDecoration]
452 
453  if config.dataType() is not DataType.Data and not self.noEffSF and self.saveCombinedSF:
454  alg = config.createAlgorithm( 'CP::AsgObjectScaleFactorAlg',
455  'PhotonCombinedEfficiencyScaleFactorAlg' + postfix )
456  alg.particles = config.readName (self.containerName)
457  alg.inScaleFactors = sfList
458  alg.outScaleFactor = 'effSF' + postfix + '_%SYS%'
459  config.addOutputVar (self.containerName, alg.outScaleFactor, 'effSF' + postfix)
460 
replace
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition: hcg.cxx:307
SystemOfUnits
PATCore::ParticleDataType
Definition: PATCoreEnums.h:21
python.PhotonAnalysisConfig.PhotonCalibrationConfig.__init__
def __init__(self, containerName='')
Definition: PhotonAnalysisConfig.py:20
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
python.PhotonAnalysisConfig.PhotonWorkingPointConfig
Definition: PhotonAnalysisConfig.py:272
python.PhotonAnalysisConfig.PhotonWorkingPointConfig.__init__
def __init__(self, containerName='', selectionName='')
Definition: PhotonAnalysisConfig.py:277
python.PhotonAnalysisConfig.PhotonCalibrationConfig.makeAlgs
def makeAlgs(self, config)
Definition: PhotonAnalysisConfig.py:110
python.PhotonAnalysisConfig.PhotonWorkingPointConfig.makeAlgs
def makeAlgs(self, config)
Definition: PhotonAnalysisConfig.py:322
python.PhotonAnalysisConfig.PhotonCalibrationConfig
Definition: PhotonAnalysisConfig.py:17
python.PhotonAnalysisConfig.PhotonWorkingPointConfig.qualityWP
qualityWP
Definition: PhotonAnalysisConfig.py:338
python.PhotonAnalysisConfig.PhotonCalibrationConfig.makeCalibrationAndSmearingAlg
def makeCalibrationAndSmearingAlg(self, config, name)
Definition: PhotonAnalysisConfig.py:74