ATLAS Offline Software
MuonAnalysisConfig.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 AnalysisAlgorithmsConfig.ConfigAccumulator import DataType
7 from AthenaConfiguration.Enums import LHCPeriod
8 from TrigGlobalEfficiencyCorrection.TriggerLeg_DictHelpers import TriggerDict
9 from Campaigns.Utils import Campaign
10 from AthenaCommon.Logging import logging
11 
12 
13 class MuonCalibrationConfig (ConfigBlock):
14  """the ConfigBlock for the muon four-momentum correction"""
15 
16  def __init__ (self, containerName='') :
17  super (MuonCalibrationConfig, self).__init__ ()
18  self.setBlockName('Muons')
19  self.addOption ('containerName', containerName, type=str,
20  noneAction='error',
21  info="the name of the output container after calibration.")
22  self.addOption ('postfix', "", type=str,
23  info="a postfix to apply to decorations and algorithm names. "
24  "Typically not needed here since the calibration is common to "
25  "all muons.")
26  self.addOption ('minPt', 3.0*GeV, type=float,
27  info="pT cut to apply to calibrated muons, in MeV. "
28  "The default is 3.0 GeV.")
29  self.addOption ('recalibratePhyslite', True, type=bool,
30  info="whether to run the CP::EgammaCalibrationAndSmearingAlg on "
31  "PHYSLITE derivations. The default is True.")
32  self.addOption ('maxEta', 2.7, type=float,
33  info="maximum muon |eta| (float). The default is 2.7.")
34  self.addOption ('excludeNSWFromPrecisionLayers', False, type=bool,
35  info="only for testing purposes, turn on to ignore NSW hits and "
36  "fix a crash with older derivations (p-tag <p5834)")
37  self.addOption ('calibMode', 'correctData_CB', type=str, info='calibration mode of the MuonCalibTool needed to turn on the sagitta bias corrections and to select the muon track calibration type (CB or ID+MS)')
38  self.addOption ('decorateTruth', False, type=bool,
39  info="decorate truth particle information on the reconstructed one")
40 
41  def makeAlgs (self, config) :
42 
43  #make sure that this is sync with
44  #PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonMomentumCorrections/MuonMomentumCorrections/MuonCalibTool.h#L31-37
45  if self.calibMode == 'correctData_CB':
46  calibMode = 0
47  elif self.calibMode == 'correctData_IDMS':
48  calibMode = 1
49  elif self.calibMode == 'notCorrectData_IDMS':
50  calibMode = 2
51  elif self.calibMode == 'notCorrectData_CB':
52  calibMode = 3
53  else :
54  raise ValueError ("invalid calibMode: \"" + self.calibMode + "\". Allowed values are correctData_CB, correctData_IDMS, notCorrectData_IDMS, notCorrectData_CB")
55 
56  config.setSourceName (self.containerName,
57  "AnalysisMuons" if config.isPhyslite() else "Muons",
58  calibMode=calibMode)
59 
60  # Set up a shallow copy to decorate
61  if config.wantCopy (self.containerName) :
62  alg = config.createAlgorithm( 'CP::AsgShallowCopyAlg', 'MuonShallowCopyAlg' + self.postfix )
63  alg.input = config.readName (self.containerName)
64  alg.output = config.copyName (self.containerName)
65 
66  # Set up the eta-cut on all muons prior to everything else
67  alg = config.createAlgorithm( 'CP::AsgSelectionAlg',
68  'MuonEtaCutAlg' + self.postfix )
69  config.addPrivateTool( 'selectionTool', 'CP::AsgPtEtaSelectionTool' )
70  alg.selectionTool.maxEta = self.maxEta
71  alg.selectionDecoration = 'selectEta' + self.postfix + ',as_bits'
72  alg.particles = config.readName (self.containerName)
73  alg.preselection = config.getPreselection (self.containerName, '')
74  config.addSelection (self.containerName, '', alg.selectionDecoration)
75 
76  # Set up the muon calibration and smearing algorithm:
77  alg = config.createAlgorithm( 'CP::MuonCalibrationAndSmearingAlg',
78  'MuonCalibrationAndSmearingAlg' + self.postfix )
79  config.addPrivateTool( 'calibrationAndSmearingTool',
80  'CP::MuonCalibTool' )
81 
82  alg.calibrationAndSmearingTool.IsRun3Geo = config.geometry() >= LHCPeriod.Run3
83  alg.calibrationAndSmearingTool.calibMode = calibMode
84  if config.geometry() is LHCPeriod.Run4:
85  logging.warning("MuonCalibrationConfig: disabling NSW hits for Run4 geometry")
86  alg.calibrationAndSmearingTool.ExcludeNSWFromPrecisionLayers = True
87  else:
88  alg.calibrationAndSmearingTool.ExcludeNSWFromPrecisionLayers = self.excludeNSWFromPrecisionLayers and (config.geometry() >= LHCPeriod.Run3)
89  alg.muons = config.readName (self.containerName)
90  alg.muonsOut = config.copyName (self.containerName)
91  alg.preselection = config.getPreselection (self.containerName, '')
92  if config.isPhyslite() and not self.recalibratePhyslite :
93  alg.skipNominal = True
94 
95  # Set up the the pt selection
96  if self.minPt > 0:
97  alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'MuonPtCutAlg' + self.postfix )
98  alg.selectionDecoration = 'selectPt' + self.postfix + ',as_bits'
99  config.addPrivateTool( 'selectionTool', 'CP::AsgPtEtaSelectionTool' )
100  alg.particles = config.readName (self.containerName)
101  alg.selectionTool.minPt = self.minPt
102  alg.preselection = config.getPreselection (self.containerName, '')
103  config.addSelection (self.containerName, '', alg.selectionDecoration,
104  preselection = True)
105 
106  # Additional decorations
107  alg = config.createAlgorithm( 'CP::AsgEnergyDecoratorAlg', 'EnergyDecorator' + self.containerName + self.postfix )
108  alg.particles = config.readName (self.containerName)
109 
110  config.addOutputVar (self.containerName, 'pt', 'pt')
111  config.addOutputVar (self.containerName, 'eta', 'eta', noSys=True)
112  config.addOutputVar (self.containerName, 'phi', 'phi', noSys=True)
113  config.addOutputVar (self.containerName, 'e_%SYS%', 'e')
114  config.addOutputVar (self.containerName, 'charge', 'charge', noSys=True)
115 
116  # decorate truth information on the reconstructed object:
117  if self.decorateTruth and config.dataType() is not DataType.Data:
118  config.addOutputVar (self.containerName, "truthType", "truth_type", noSys=True)
119  config.addOutputVar (self.containerName, "truthOrigin", "truth_origin", noSys=True)
120 
121 class MuonWorkingPointConfig (ConfigBlock) :
122  """the ConfigBlock for the muon working point
123 
124  This may at some point be split into multiple blocks (10 Mar 22)."""
125 
126  def __init__ (self, containerName='', selectionName='') :
127  super (MuonWorkingPointConfig, self).__init__ ()
128  self.setBlockName('MuonsWorkingPoint')
129  self.addOption ('containerName', containerName, type=str,
130  noneAction='error',
131  info="the name of the input container.")
132  self.addOption ('selectionName', selectionName, type=str,
133  noneAction='error',
134  info="the name of the muon selection to define (e.g. tight or loose).")
135  self.addOption ('postfix', selectionName, type=str,
136  info="a postfix to apply to decorations and algorithm names. "
137  "Typically not needed here as selectionName is used internally.")
138  self.addOption ('trackSelection', True, type=bool,
139  info="whether or not to set up an instance of "
140  "CP::AsgLeptonTrackSelectionAlg, with the recommended d_0 and "
141  "z_0 sin(theta) cuts. The default is True.")
142  self.addOption ('maxD0Significance', 3, type=float,
143  info="maximum d0 significance used for the trackSelection"
144  "The default is 3")
145  self.addOption ('maxDeltaZ0SinTheta', 0.5, type=float,
146  info="maximum Delta z0sinTheta in mm used for the trackSelection"
147  "The default is 0.5 mm")
148  self.addOption ('writeTrackD0Z0', False, type = bool,
149  info="save the d0 significance and z0sinTheta variables so they can be written out")
150  self.addOption ('quality', None, type=str,
151  info="the ID WP (string) to use. Supported ID WPs: Tight, Medium, "
152  "Loose, LowPt, HighPt.")
153  self.addOption ('isolation', None, type=str,
154  info="the isolation WP (string) to use. Supported isolation WPs: "
155  "PflowLoose_VarRad, PflowTight_VarRad, Loose_VarRad, "
156  "Tight_VarRad, NonIso.")
157  self.addOption ('addSelectionToPreselection', True, type=bool,
158  info="whether to retain only muons satisfying the working point "
159  "requirements. The default is True.")
160  self.addOption ('closeByCorrection', False, type=bool,
161  info="whether to use close-by-corrected isolation working points.")
162  self.addOption ('systematicBreakdown', False, type=bool,
163  info="enables the full breakdown of efficiency SF systematics "
164  "(1 NP per uncertainty source, instead of 1 NP in total). "
165  "The default is False.")
166  self.addOption ('onlyRecoEffSF', False, type=bool,
167  info="same as noEffSF, but retains the ID scale factor. "
168  "Experimental! only useful for CI tests. The default is False.")
169  self.addOption ('noEffSF', False, type=bool,
170  info="disables the calculation of efficiencies and scale factors. "
171  "Experimental! only useful to test a new WP for which scale "
172  "factors are not available. The default is False.")
173  self.addOption ('excludeNSWFromPrecisionLayers', False, type=bool,
174  info="only for testing purposes, turn on to ignore NSW hits and "
175  "fix a crash with older derivations (p-tag <p5834)")
176 
177  def makeAlgs (self, config) :
178  from xAODMuon.xAODMuonEnums import xAODMuonEnums
179  if self.quality == 'Tight' :
180  quality = xAODMuonEnums.Quality.Tight
181  elif self.quality == 'Medium' :
182  quality = xAODMuonEnums.Quality.Medium
183  elif self.quality == 'Loose' :
184  quality = xAODMuonEnums.Quality.Loose
185  elif self.quality == 'VeryLoose' :
186  quality = xAODMuonEnums.Quality.VeryLoose
187  elif self.quality == 'HighPt' :
188  quality = 4
189  elif self.quality == 'LowPtEfficiency' :
190  quality = 5
191  else :
192  raise ValueError ("invalid muon quality: \"" + self.quality +
193  "\", allowed values are Tight, Medium, Loose, " +
194  "VeryLoose, HighPt, LowPtEfficiency")
195 
196  # The setup below is inappropriate for Run 1
197  if config.geometry() is LHCPeriod.Run1:
198  raise ValueError ("Can't set up the MuonWorkingPointConfig with %s, there must be something wrong!" % config.geometry().value)
199 
200  postfix = self.postfix
201  if postfix != '' and postfix[0] != '_' :
202  postfix = '_' + postfix
203 
204  # Set up the track selection algorithm:
205  if self.writeTrackD0Z0 or self.trackSelection:
206  alg = config.createAlgorithm( 'CP::AsgLeptonTrackSelectionAlg',
207  'MuonTrackSelectionAlg' + postfix )
208  alg.selectionDecoration = 'trackSelection' + postfix + ',as_bits'
209  alg.decorateTTVAVars = self.writeTrackD0Z0
210  alg.maxD0Significance = self.maxD0Significance
211  alg.maxDeltaZ0SinTheta = self.maxDeltaZ0SinTheta
212  alg.particles = config.readName (self.containerName)
213  alg.preselection = config.getPreselection (self.containerName, '')
214  if self.trackSelection :
215  config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration, preselection=self.addSelectionToPreselection)
216  if self.writeTrackD0Z0 :
217  alg.d0sigDecoration = 'd0sig' + postfix
218  alg.z0sinthetaDecoration = 'z0sintheta' + postfix
219  config.addOutputVar (self.containerName, alg.d0sigDecoration, alg.d0sigDecoration,noSys=True)
220  config.addOutputVar (self.containerName, alg.z0sinthetaDecoration, alg.z0sinthetaDecoration,noSys=True)
221 
222  # Setup the muon quality selection
223  alg = config.createAlgorithm( 'CP::MuonSelectionAlgV2',
224  'MuonSelectionAlg' + postfix )
225  config.addPrivateTool( 'selectionTool', 'CP::MuonSelectionTool' )
226  alg.selectionTool.MuQuality = quality
227  alg.selectionTool.IsRun3Geo = config.geometry() >= LHCPeriod.Run3
228  if config.geometry() is LHCPeriod.Run4:
229  logging.warning("MuonCalibrationConfig: disabling NSW hits for Run4 geometry")
230  alg.selectionTool.ExcludeNSWFromPrecisionLayers = True
231  else:
232  alg.selectionTool.ExcludeNSWFromPrecisionLayers = self.excludeNSWFromPrecisionLayers and (config.geometry() >= LHCPeriod.Run3)
233  alg.selectionDecoration = 'good_muon' + postfix + ',as_char'
234  alg.badMuonVetoDecoration = 'is_bad' + postfix + ',as_char'
235  alg.muons = config.readName (self.containerName)
236  alg.preselection = config.getPreselection (self.containerName, self.selectionName)
237  config.addSelection (self.containerName, self.selectionName,
238  alg.selectionDecoration,
239  preselection=self.addSelectionToPreselection)
240 
241  # Set up the isolation calculation algorithm:
242  if self.isolation != 'NonIso' :
243  alg = config.createAlgorithm( 'CP::MuonIsolationAlg',
244  'MuonIsolationAlg' + postfix )
245  config.addPrivateTool( 'isolationTool', 'CP::IsolationSelectionTool' )
246  alg.isolationTool.MuonWP = self.isolation
247  if self.closeByCorrection:
248  alg.isolationTool.IsoDecSuffix = "CloseByCorr"
249  alg.isolationDecoration = 'isolated_muon' + postfix + ',as_char'
250  alg.muons = config.readName (self.containerName)
251  alg.preselection = config.getPreselection (self.containerName, self.selectionName)
252  config.addSelection (self.containerName, self.selectionName,
253  alg.isolationDecoration,
254  preselection=self.addSelectionToPreselection)
255 
256  # Set up the reco/ID efficiency scale factor calculation algorithm:
257  if config.dataType() is not DataType.Data and (not self.noEffSF or self.onlyRecoEffSF):
258  alg = config.createAlgorithm( 'CP::MuonEfficiencyScaleFactorAlg',
259  'MuonEfficiencyScaleFactorAlgReco' + postfix )
260  config.addPrivateTool( 'efficiencyScaleFactorTool',
261  'CP::MuonEfficiencyScaleFactors' )
262  alg.scaleFactorDecoration = 'muon_reco_effSF' + postfix + "_%SYS%"
263  alg.outOfValidity = 2 #silent
264  alg.outOfValidityDeco = 'muon_reco_bad_eff' + postfix
265  alg.efficiencyScaleFactorTool.WorkingPoint = self.quality
266  if config.geometry() >= LHCPeriod.Run3:
267  alg.efficiencyScaleFactorTool.CalibrationRelease = '240711_Preliminary_r24run3'
268  alg.efficiencyScaleFactorTool.BreakDownSystematics = self.systematicBreakdown
269  alg.muons = config.readName (self.containerName)
270  alg.preselection = config.getPreselection (self.containerName, self.selectionName)
271  config.addOutputVar (self.containerName, alg.scaleFactorDecoration, 'reco_effSF' + postfix)
272 
273  # Set up the HighPt-specific BadMuonVeto efficiency scale factor calculation algorithm:
274  if config.dataType() is not DataType.Data and self.quality == 'HighPt' and not self.onlyRecoEffSF and not self.noEffSF:
275  alg = config.createAlgorithm( 'CP::MuonEfficiencyScaleFactorAlg',
276  'MuonEfficiencyScaleFactorAlgBMVHighPt' + postfix )
277  config.addPrivateTool( 'efficiencyScaleFactorTool',
278  'CP::MuonEfficiencyScaleFactors' )
279  alg.scaleFactorDecoration = 'muon_BadMuonVeto_effSF' + postfix + "_%SYS%"
280  alg.outOfValidity = 2 #silent
281  alg.outOfValidityDeco = 'muon_BadMuonVeto_bad_eff' + postfix
282  alg.efficiencyScaleFactorTool.WorkingPoint = 'BadMuonVeto_HighPt'
283  if config.geometry() >= LHCPeriod.Run3:
284  alg.efficiencyScaleFactorTool.CalibrationRelease = '220817_Preliminary_r22run3' # not available as part of '230123_Preliminary_r22run3'!
285  alg.efficiencyScaleFactorTool.BreakDownSystematics = self.systematicBreakdown
286  alg.muons = config.readName (self.containerName)
287  alg.preselection = config.getPreselection (self.containerName, self.selectionName)
288  config.addOutputVar (self.containerName, alg.scaleFactorDecoration, 'BadMuonVeto_effSF' + postfix)
289 
290  # Set up the isolation efficiency scale factor calculation algorithm:
291  if config.dataType() is not DataType.Data and self.isolation != 'NonIso' and not self.onlyRecoEffSF and not self.noEffSF:
292  alg = config.createAlgorithm( 'CP::MuonEfficiencyScaleFactorAlg',
293  'MuonEfficiencyScaleFactorAlgIsol' + postfix )
294  config.addPrivateTool( 'efficiencyScaleFactorTool',
295  'CP::MuonEfficiencyScaleFactors' )
296  alg.scaleFactorDecoration = 'muon_isol_effSF' + postfix + "_%SYS%"
297  alg.outOfValidity = 2 #silent
298  alg.outOfValidityDeco = 'muon_isol_bad_eff' + postfix
299  alg.efficiencyScaleFactorTool.WorkingPoint = self.isolation + 'Iso'
300  if config.geometry() >= LHCPeriod.Run3:
301  alg.efficiencyScaleFactorTool.CalibrationRelease = '240711_Preliminary_r24run3'
302  alg.efficiencyScaleFactorTool.BreakDownSystematics = self.systematicBreakdown
303  alg.muons = config.readName (self.containerName)
304  alg.preselection = config.getPreselection (self.containerName, self.selectionName)
305  config.addOutputVar (self.containerName, alg.scaleFactorDecoration, 'isol_effSF' + postfix)
306 
307  # Set up the TTVA scale factor calculation algorithm:
308  if config.dataType() is not DataType.Data and not self.onlyRecoEffSF and not self.noEffSF:
309  alg = config.createAlgorithm( 'CP::MuonEfficiencyScaleFactorAlg',
310  'MuonEfficiencyScaleFactorAlgTTVA' + postfix )
311  config.addPrivateTool( 'efficiencyScaleFactorTool',
312  'CP::MuonEfficiencyScaleFactors' )
313  alg.scaleFactorDecoration = 'muon_TTVA_effSF' + postfix + "_%SYS%"
314  alg.outOfValidity = 2 #silent
315  alg.outOfValidityDeco = 'muon_TTVA_bad_eff' + postfix
316  alg.efficiencyScaleFactorTool.WorkingPoint = 'TTVA'
317  if config.geometry() >= LHCPeriod.Run3:
318  alg.efficiencyScaleFactorTool.CalibrationRelease = '240711_Preliminary_r24run3'
319  alg.efficiencyScaleFactorTool.BreakDownSystematics = self.systematicBreakdown
320  alg.muons = config.readName (self.containerName)
321  alg.preselection = config.getPreselection (self.containerName, self.selectionName)
322  config.addOutputVar (self.containerName, alg.scaleFactorDecoration, 'TTVA_effSF' + postfix)
323 
324 
325 def makeMuonCalibrationConfig( seq, containerName,
326  postfix = None):
327  """Create muon calibration analysis algorithms
328 
329  This makes all the algorithms that need to be run first befor
330  all working point specific algorithms and that can be shared
331  between the working points.
332 
333  Keyword arguments:
334  containerName -- name of the output container
335  postfix -- a postfix to apply to decorations and algorithm
336  names. this is mostly used/needed when using this
337  sequence with multiple working points to ensure all
338  names are unique.
339  """
340 
341  config = MuonCalibrationConfig (containerName)
342  config.setOptionValue ('postfix', postfix)
343  seq.append (config)
344 
345 
346 
347 
348 
349 def makeMuonWorkingPointConfig( seq, containerName, workingPoint, selectionName,
350  addSelectionToPreselection = None,
351  systematicBreakdown = None,
352  noEffSF = None,
353  onlyRecoEffSF = None ):
354  """Create muon analysis algorithms for a single working point
355 
356  Keyword arguments:
357  workingPoint -- The working point to use
358  selectionName -- a postfix to apply to decorations and algorithm
359  names. this is mostly used/needed when using this
360  sequence with multiple working points to ensure all
361  names are unique.
362  addSelectionToPreselection -- Whether or not to apply muon quality selection
363  when creating output containers.
364  systematicBreakdown -- enables the full breakdown of eff SF systematics
365  noEffSF -- Disables the calculation of efficiencies and scale factors
366  onlyRecoEffSF -- Only enables the reconstruction scale factor
367  """
368 
369 
370  config = MuonWorkingPointConfig (containerName, selectionName)
371  if workingPoint is not None :
372  splitWP = workingPoint.split ('.')
373  if len (splitWP) != 2 :
374  raise ValueError ('working point should be of format "quality.isolation", not ' + workingPoint)
375  config.setOptionValue ('quality', splitWP[0])
376  config.setOptionValue ('isolation', splitWP[1])
377  config.setOptionValue ('addSelectionToPreselection', addSelectionToPreselection)
378  config.setOptionValue ('systematicBreakdown', systematicBreakdown)
379  config.setOptionValue ('noEffSF', noEffSF)
380  config.setOptionValue ('onlyRecoEffSF', onlyRecoEffSF)
381  seq.append (config)
382 
383 
384 class MuonTriggerAnalysisSFBlock (ConfigBlock):
385 
386  def __init__ (self, configName='') :
387  super (MuonTriggerAnalysisSFBlock, self).__init__ ()
388 
389  self.addOption ('triggerChainsPerYear', {}, type=None,
390  info="a dictionary with key (string) the year and value (list of "
391  "strings) the trigger chains. The default is {} (empty dictionary).")
392  self.addOption ('muonID', '', type=str,
393  info="the muon quality WP (string) to use.")
394  self.addOption ('saveEff', False, type=bool,
395  info="define whether we decorate also the trigger scale efficiency "
396  "The default is false.")
397  self.addOption ('containerName', '', type=str,
398  info="the input muon container, with a possible selection, in "
399  "the format container or container.selection.")
400 
401  def makeAlgs (self, config) :
402 
403  if config.dataType() is not DataType.Data:
404 
405  # Dictionary from TrigGlobalEfficiencyCorrection/Triggers.cfg
406  # Key is trigger chain (w/o HLT prefix)
407  # Value is empty for single leg trigger or list of legs
408  triggerDict = TriggerDict()
409 
410  if config.campaign() is Campaign.MC20a:
411  years = [2015, 2016]
412  elif config.campaign() is Campaign.MC20d:
413  years = [2017]
414  elif config.campaign() is Campaign.MC20e:
415  years = [2018]
416  elif config.campaign() in [Campaign.MC21a, Campaign.MC23a]:
417  years = [2022]
418  elif config.campaign() in [Campaign.MC23c, Campaign.MC23d]:
419  years = [2023]
420 
421  triggerConfigs = {}
422  triggerConfigYears = {}
423  for year in years:
424  triggerChains = self.triggerChainsPerYear.get(int(year), self.triggerChainsPerYear.get(str(year), []))
425  for chain in triggerChains:
426  chain = chain.replace(" || ", "_OR_")
427  chain_noHLT = chain.replace("HLT_","")
428  legs = triggerDict[chain_noHLT]
429  if len(legs)==0:
430  if chain_noHLT.startswith('mu') and chain_noHLT[2].isdigit:
431  # Need to support HLT_mu26_ivarmedium_OR_HLT_mu50
432  triggerConfigs[chain_noHLT] = chain
433  if chain_noHLT in triggerConfigYears.keys():
434  triggerConfigYears[chain_noHLT].append(year)
435  else:
436  triggerConfigYears[chain_noHLT] = [year]
437  else:
438  for leg in legs:
439  if leg.startswith('mu') and leg[2].isdigit:
440  # Need to support HLT_mu14_ivarloose
441  triggerConfigs[leg] = 'HLT_' + leg
442  if chain_noHLT in triggerConfigYears.keys():
443  triggerConfigYears[leg].append(year)
444  else:
445  triggerConfigYears[leg] = [year]
446 
447  for trig_short, trig in triggerConfigs.items():
448  alg = config.createAlgorithm('CP::MuonTriggerEfficiencyScaleFactorAlg',
449  'MuonTrigEfficiencyCorrectionsAlg_' + trig_short)
450  config.addPrivateTool( 'efficiencyScaleFactorTool',
451  'CP::MuonTriggerScaleFactors' )
452 
453  # Reproduce config from TrigGlobalEfficiencyAlg
454  alg.efficiencyScaleFactorTool.MuonQuality = self.muonID
455  alg.efficiencyScaleFactorTool.AllowZeroSF = True
456 
457  # Avoid warnings for MC20a 2015-2016 triggers covering a single year
458  if config.campaign() is Campaign.MC20a:
459  if triggerConfigYears[trig_short] == [2015]:
460  alg.maxRunNumber = 290000
461  elif triggerConfigYears[trig_short] == [2016]:
462  alg.minRunNumber = 290000
463 
464  alg.trigger = trig
465  alg.scaleFactorDecoration = 'muon_trigEffSF_' + trig_short + '_%SYS%'
466  if(self.saveEff):
467  alg.mcEfficiencyDecoration = 'muon_trigEff_' + trig_short + '_%SYS%'
468  alg.outOfValidity = 2 #silent
469  alg.outOfValidityDeco = 'bad_eff_muontrig_' + trig_short
470  alg.muons = config.readName (self.containerName)
471  alg.preselection = config.getPreselection (self.containerName, '')
472  config.addOutputVar (self.containerName, alg.scaleFactorDecoration, 'trigEffSF_' + trig_short)
473  if(self.saveEff):
474  config.addOutputVar (self.containerName, alg.scaleFactorDecoration, 'trigEff_' + trig_short)
SystemOfUnits
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
python.MuonAnalysisConfig.MuonCalibrationConfig.makeAlgs
def makeAlgs(self, config)
Definition: MuonAnalysisConfig.py:41
dumpHVPathFromNtuple.append
bool append
Definition: dumpHVPathFromNtuple.py:91
python.MuonAnalysisConfig.MuonTriggerAnalysisSFBlock.__init__
def __init__(self, configName='')
Definition: MuonAnalysisConfig.py:386
python.MuonAnalysisConfig.MuonCalibrationConfig.__init__
def __init__(self, containerName='')
Definition: MuonAnalysisConfig.py:16
python.MuonAnalysisConfig.MuonTriggerAnalysisSFBlock.makeAlgs
def makeAlgs(self, config)
Definition: MuonAnalysisConfig.py:401
python.MuonAnalysisConfig.makeMuonWorkingPointConfig
def makeMuonWorkingPointConfig(seq, containerName, workingPoint, selectionName, addSelectionToPreselection=None, systematicBreakdown=None, noEffSF=None, onlyRecoEffSF=None)
Definition: MuonAnalysisConfig.py:349
python.MuonAnalysisConfig.MuonTriggerAnalysisSFBlock
Definition: MuonAnalysisConfig.py:384
TriggerLeg_DictHelpers.TriggerDict
def TriggerDict()
Definition: TriggerLeg_DictHelpers.py:7
python.MuonAnalysisConfig.MuonWorkingPointConfig.__init__
def __init__(self, containerName='', selectionName='')
Definition: MuonAnalysisConfig.py:126
python.MuonAnalysisConfig.MuonWorkingPointConfig
Definition: MuonAnalysisConfig.py:121
python.MuonAnalysisConfig.MuonWorkingPointConfig.quality
quality
Definition: MuonAnalysisConfig.py:179
if
if(febId1==febId2)
Definition: LArRodBlockPhysicsV0.cxx:567
get
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition: hcg.cxx:127
python.MuonAnalysisConfig.makeMuonCalibrationConfig
def makeMuonCalibrationConfig(seq, containerName, postfix=None)
Definition: MuonAnalysisConfig.py:325
str
Definition: BTagTrackIpAccessor.cxx:11
python.MuonAnalysisConfig.MuonCalibrationConfig.calibMode
calibMode
Definition: MuonAnalysisConfig.py:45
python.MuonAnalysisConfig.MuonWorkingPointConfig.makeAlgs
def makeAlgs(self, config)
Definition: MuonAnalysisConfig.py:177
python.MuonAnalysisConfig.MuonCalibrationConfig
Definition: MuonAnalysisConfig.py:13