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