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