ATLAS Offline Software
MuonAnalysisSequence.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
2 
3 # AnaAlgorithm import(s):
4 from AsgAnalysisAlgorithms.AnalysisObjectSharedSequence import makeSharedObjectSequence
5 from AnaAlgorithm.AnaAlgSequence import AnaAlgSequence
6 from AnaAlgorithm.DualUseConfig import createAlgorithm, addPrivateTool
7 
8 def makeMuonAnalysisSequence( dataType, workingPoint,
9  deepCopyOutput = False,
10  shallowViewOutput = True,
11  postfix = '',
12  ptSelectionOutput = False,
13  trackSelection = True,
14  maxEta = 2.7,
15  qualitySelectionOutput = True,
16  enableCutflow = False,
17  enableKinematicHistograms = False,
18  isRun3Geo = False,
19  defineSystObjectLinks = False ):
20  """Create a muon analysis algorithm sequence
21 
22  Keyword arguments:
23  dataType -- The data type to run on ("data", "mc" or "afii")
24  workingPoint -- The working point to use
25  deepCopyOutput -- If set to 'True', the output containers will be
26  standalone, deep copies (slower, but needed for xAOD
27  output writing)
28  shallowViewOutput -- Create a view container if required
29  postfix -- a postfix to apply to decorations and algorithm
30  names. this is mostly used/needed when using this
31  sequence with multiple working points to ensure all
32  names are unique.
33  ptSelectionOutput -- Whether or not to apply pt selection when creating
34  output containers.
35  trackSelection -- apply selection on tracks (d0, z0, siHits, etc.)
36  qualitySelectionOutput -- Whether or not to apply muon quality selection
37  when creating output containers.
38  enableCutflow -- Whether or not to dump the cutflow
39  enableKinematicHistograms -- Whether or not to dump the kinematic histograms
40  """
41 
42  if dataType not in ["data", "mc", "afii"] :
43  raise ValueError ("invalid data type: " + dataType)
44 
45  if postfix != '' :
46  postfix = '_' + postfix
47  pass
48 
49  # Create the analysis algorithm sequence object:
50  seq = AnaAlgSequence( "MuonAnalysisSequence" + postfix )
51 
52  seq.addMetaConfigDefault ("selectionDecorNames", [])
53  seq.addMetaConfigDefault ("selectionDecorNamesOutput", [])
54  seq.addMetaConfigDefault ("selectionDecorCount", [])
55 
56  makeMuonCalibrationSequence (seq, dataType, postfix=postfix,
57  ptSelectionOutput = ptSelectionOutput,
58  trackSelection = trackSelection,
59  maxEta = maxEta, isRun3Geo = isRun3Geo)
60  makeMuonWorkingPointSequence (seq, dataType, workingPoint, postfix=postfix,
61  qualitySelectionOutput = qualitySelectionOutput, isRun3Geo = isRun3Geo)
62  makeSharedObjectSequence (seq, deepCopyOutput = deepCopyOutput,
63  shallowViewOutput = shallowViewOutput,
64  postfix = '_Muon' + postfix,
65  enableCutflow = enableCutflow,
66  enableKinematicHistograms = enableKinematicHistograms,
67  defineSystObjectLinks = defineSystObjectLinks )
68 
69  # Return the sequence:
70  return seq
71 
72 
73 
74 
75 
76 def makeMuonCalibrationSequence( seq, dataType,
77  postfix = '', ptSelectionOutput = False, trackSelection = False, maxEta = 2.7, isRun3Geo = False, calibMode = 0):
78  """Create muon calibration analysis algorithms
79 
80  This makes all the algorithms that need to be run first befor
81  all working point specific algorithms and that can be shared
82  between the working points.
83 
84  Keyword arguments:
85  dataType -- The data type to run on ("data", "mc" or "afii")
86  postfix -- a postfix to apply to decorations and algorithm
87  names. this is mostly used/needed when using this
88  sequence with multiple working points to ensure all
89  names are unique.
90  ptSelectionOutput -- Whether or not to apply pt selection when creating
91  output containers.
92  """
93 
94  if dataType not in ["data", "mc", "afii"] :
95  raise ValueError ("invalid data type: " + dataType)
96 
97  # Set up a shallow copy to decorate
98  alg = createAlgorithm( 'CP::AsgShallowCopyAlg', 'MuonShallowCopyAlg' + postfix )
99  seq.append( alg, inputPropName = 'input',
100  outputPropName = 'output',
101  stageName = 'prepare')
102 
103  # Set up the eta-cut on all muons prior to everything else
104  alg = createAlgorithm( 'CP::AsgSelectionAlg',
105  'MuonEtaCutAlg' + postfix )
106  addPrivateTool( alg, 'selectionTool', 'CP::AsgPtEtaSelectionTool' )
107  alg.selectionTool.maxEta = maxEta
108  alg.selectionDecoration = 'selectEta' + postfix + ',as_bits'
109  seq.append( alg, inputPropName = 'particles',
110  stageName = 'selection',
111  metaConfig = {'selectionDecorNames' : [alg.selectionDecoration],
112  'selectionDecorNamesOutput' : [alg.selectionDecoration],
113  'selectionDecorCount' : [2]},
114  dynConfig = {'preselection' : lambda meta : "&&".join (meta["selectionDecorNamesOutput"])})
115 
116  # Set up the track selection algorithm:
117  if trackSelection:
118  alg = createAlgorithm( 'CP::AsgLeptonTrackSelectionAlg',
119  'MuonTrackSelectionAlg' + postfix )
120  alg.selectionDecoration = 'trackSelection' + postfix + ',as_bits'
121  alg.maxD0Significance = 3
122  alg.maxDeltaZ0SinTheta = 0.5
123  seq.append( alg, inputPropName = 'particles',
124  stageName = 'selection',
125  metaConfig = {'selectionDecorNames' : [alg.selectionDecoration],
126  'selectionDecorNamesOutput' : [alg.selectionDecoration],
127  'selectionDecorCount' : [3]},
128  dynConfig = {'preselection' : lambda meta : "&&".join (meta["selectionDecorNamesOutput"])})
129 
130  # Set up the muon calibration and smearing algorithm:
131  alg = createAlgorithm( 'CP::MuonCalibrationAndSmearingAlg',
132  'MuonCalibrationAndSmearingAlg' + postfix )
133  addPrivateTool( alg, 'calibrationAndSmearingTool',
134  'CP::MuonCalibTool' )
135 
136  alg.calibrationAndSmearingTool.IsRun3Geo = isRun3Geo
137  alg.calibrationAndSmearingTool.calibMode = calibMode # choose ID+MS with no sagitta bias
138  seq.append( alg, inputPropName = 'muons', outputPropName = 'muonsOut',
139  stageName = 'calibration',
140  dynConfig = {'preselection' : lambda meta : "&&".join (meta["selectionDecorNamesOutput"])})
141 
142  # Set up the the pt selection
143  alg = createAlgorithm( 'CP::AsgSelectionAlg', 'MuonPtCutAlg' + postfix )
144  alg.selectionDecoration = 'selectPt' + postfix + ',as_bits'
145  addPrivateTool( alg, 'selectionTool', 'CP::AsgPtEtaSelectionTool' )
146  alg.selectionTool.minPt = 3e3
147  seq.append( alg, inputPropName = 'particles',
148  stageName = 'selection',
149  metaConfig = {'selectionDecorNames' : [alg.selectionDecoration],
150  'selectionDecorNamesOutput' : [alg.selectionDecoration] if ptSelectionOutput else [],
151  'selectionDecorCount' : [2]},
152  dynConfig = {'preselection' : lambda meta : "&&".join (meta["selectionDecorNamesOutput"])})
153  pass
154 
155 
156 
157 
158 
159 def makeMuonWorkingPointSequence( seq, dataType, workingPoint, postfix = '',
160  qualitySelectionOutput = True, isRun3Geo = False):
161  """Create muon analysis algorithms for a single working point
162 
163  Keyword arguments:
164  dataType -- The data type to run on ("data", "mc" or "afii")
165  workingPoint -- The working point to use
166  postfix -- a postfix to apply to decorations and algorithm
167  names. this is mostly used/needed when using this
168  sequence with multiple working points to ensure all
169  names are unique.
170  qualitySelectionOutput -- Whether or not to apply muon quality selection
171  when creating output containers.
172  isRun3Geo -- switches the muon selection tool to run 3 geometry
173  """
174 
175  if dataType not in ["data", "mc", "afii"] :
176  raise ValueError ("invalid data type: " + dataType)
177 
178  splitWP = workingPoint.split ('.')
179  if len (splitWP) != 2 :
180  raise ValueError ('working point should be of format "quality.isolation", not ' + workingPoint)
181 
182  sfWorkingPoint = splitWP[0]
183  from xAODMuon.xAODMuonEnums import xAODMuonEnums
184  if splitWP[0] == 'Tight' :
185  quality = xAODMuonEnums.Quality.Tight
186  pass
187  elif splitWP[0] == 'Medium' :
188  quality = xAODMuonEnums.Quality.Medium
189  pass
190  elif splitWP[0] == 'Loose' :
191  quality = xAODMuonEnums.Quality.Loose
192  pass
193  elif splitWP[0] == 'VeryLoose' :
194  quality = xAODMuonEnums.Quality.VeryLoose
195  pass
196  elif splitWP[0] == 'HighPt' :
197  quality = 4
198  pass
199  elif splitWP[0] == 'LowPtEfficiency' :
200  quality = 5
201  pass
202  else :
203  raise ValueError ("invalid muon quality: \"" + splitWP[0] +
204  "\", allowed values are Tight, Medium, Loose, " +
205  "VeryLoose, HighPt, LowPtEfficiency")
206 
207  # Setup the muon quality selection
208  alg = createAlgorithm( 'CP::MuonSelectionAlgV2',
209  'MuonSelectionAlg' + postfix )
210  addPrivateTool( alg, 'selectionTool', 'CP::MuonSelectionTool' )
211  alg.selectionTool.MuQuality = quality
212  alg.selectionTool.IsRun3Geo = isRun3Geo
213  alg.selectionDecoration = 'good_muon' + postfix + ',as_bits'
214  alg.badMuonVetoDecoration = 'is_bad' + postfix + ',as_char'
215  seq.append( alg, inputPropName = 'muons',
216  stageName = 'selection',
217  metaConfig = {'selectionDecorNames' : [alg.selectionDecoration],
218  'selectionDecorNamesOutput' : [alg.selectionDecoration] if qualitySelectionOutput else [],
219  'selectionDecorCount' : [4]},
220  dynConfig = {'preselection' : lambda meta : "&&".join (meta["selectionDecorNamesOutput"])})
221 
222  # Set up the isolation calculation algorithm:
223  if splitWP[1] != 'NonIso' :
224  alg = createAlgorithm( 'CP::MuonIsolationAlg',
225  'MuonIsolationAlg' + postfix )
226  addPrivateTool( alg, 'isolationTool', 'CP::IsolationSelectionTool' )
227  alg.isolationTool.MuonWP = splitWP[1]
228  alg.isolationDecoration = 'isolated_muon' + postfix + ',as_bits'
229  seq.append( alg, inputPropName = 'muons',
230  stageName = 'selection',
231  metaConfig = {'selectionDecorNames' : [alg.isolationDecoration],
232  'selectionDecorNamesOutput' : [alg.isolationDecoration],
233  'selectionDecorCount' : [1]},
234  dynConfig = {'preselection' : lambda meta : "&&".join (meta["selectionDecorNamesOutput"])})
235  pass
236 
237  # Set up the efficiency scale factor calculation algorithm:
238  alg = createAlgorithm( 'CP::MuonEfficiencyScaleFactorAlg',
239  'MuonEfficiencyScaleFactorAlg' + postfix )
240  addPrivateTool( alg, 'efficiencyScaleFactorTool',
241  'CP::MuonEfficiencyScaleFactors' )
242  alg.scaleFactorDecoration = 'muon_effSF' + postfix + "_%SYS%"
243  alg.outOfValidity = 2 #silent
244  alg.outOfValidityDeco = 'bad_eff' + postfix
245  alg.efficiencyScaleFactorTool.WorkingPoint = sfWorkingPoint
246  if isRun3Geo:
247  alg.efficiencyScaleFactorTool.CalibrationRelease = '230309_Preliminary_r22run3'
248  if dataType != 'data':
249  seq.append( alg, inputPropName = 'muons',
250  stageName = 'efficiency',
251  dynConfig = {'preselection' : lambda meta : "&&".join (meta["selectionDecorNamesOutput"])})
252 
253  # Set up an algorithm used for decorating baseline muon selection:
254  alg = createAlgorithm( 'CP::AsgSelectionAlg',
255  'MuonSelectionSummary' + postfix )
256  alg.selectionDecoration = 'baselineSelection' + postfix + ',as_char'
257  seq.append( alg, inputPropName = 'particles',
258  stageName = 'selection',
259  dynConfig = {'preselection' : lambda meta : "&&".join (meta["selectionDecorNames"])})
260  pass
python.DualUseConfig.addPrivateTool
def addPrivateTool(alg, toolName, typeName)
Definition: DualUseConfig.py:180
python.DualUseConfig.createAlgorithm
def createAlgorithm(typeName, instanceName)
Definition: DualUseConfig.py:56
python.MuonAnalysisSequence.makeMuonWorkingPointSequence
def makeMuonWorkingPointSequence(seq, dataType, workingPoint, postfix='', qualitySelectionOutput=True, isRun3Geo=False)
Definition: MuonAnalysisSequence.py:159
python.MuonAnalysisSequence.makeMuonCalibrationSequence
def makeMuonCalibrationSequence(seq, dataType, postfix='', ptSelectionOutput=False, trackSelection=False, maxEta=2.7, isRun3Geo=False, calibMode=0)
Definition: MuonAnalysisSequence.py:76
python.MuonAnalysisSequence.makeMuonAnalysisSequence
def makeMuonAnalysisSequence(dataType, workingPoint, deepCopyOutput=False, shallowViewOutput=True, postfix='', ptSelectionOutput=False, trackSelection=True, maxEta=2.7, qualitySelectionOutput=True, enableCutflow=False, enableKinematicHistograms=False, isRun3Geo=False, defineSystObjectLinks=False)
Definition: MuonAnalysisSequence.py:8