7 from AsgAnalysisAlgorithms.AnalysisObjectSharedSequence
import makeSharedObjectSequence
8 from AnaAlgorithm.AnaAlgSequence
import AnaAlgSequence
9 from AnaAlgorithm.DualUseConfig
import createAlgorithm, addPrivateTool
12 from xAODEgamma.xAODEgammaParameters
import xAOD
17 deepCopyOutput = False,
18 shallowViewOutput = True,
21 enableCleaning = True,
22 cleaningAllowLate = False,
23 recomputeIsEM = False,
24 ptSelectionOutput = False,
25 enableCutflow = False,
26 enableKinematicHistograms = False,
27 defineSystObjectLinks = False,
28 forceFullSimConfig = False):
29 """Create a photon analysis algorithm sequence
32 dataType -- The data type to run on ("data", "mc" or "afii")
33 workingPoint -- The working point to use
34 deepCopyOutput -- If set to 'True', the output containers will be
35 standalone, deep copies (slower, but needed for xAOD
37 shallowViewOutput -- Create a view container if required
38 postfix -- a postfix to apply to decorations and algorithm
39 names. this is mostly used/needed when using this
40 sequence with multiple working points to ensure all
42 crackVeto -- Whether or not to perform eta crack veto
43 enableCleaning -- Enable photon cleaning
44 cleaningAllowLate -- Whether to ignore timing information in cleaning.
45 recomputeIsEM -- Whether to rerun the cut-based selection. If not, use derivation flags
46 ptSelectionOutput -- Whether or not to apply pt selection when creating
48 enableCutflow -- Whether or not to dump the cutflow
49 enableKinematicHistograms -- Whether or not to dump the kinematic histograms
53 if dataType
not in [
'data',
'mc',
'afii' ]:
54 raise ValueError(
'Invalid data type: %s' % dataType )
57 postfix =
'_' + postfix
61 seq = AnaAlgSequence(
"PhotonAnalysisSequence" + postfix )
63 seq.addMetaConfigDefault (
"selectionDecorNames", [])
64 seq.addMetaConfigDefault (
"selectionDecorNamesOutput", [])
65 seq.addMetaConfigDefault (
"selectionDecorCount", [])
67 makePhotonCalibrationSequence (seq, dataType, postfix = postfix,
68 crackVeto = crackVeto,
69 enableCleaning = enableCleaning, cleaningAllowLate = cleaningAllowLate,
70 recomputeIsEM = recomputeIsEM,
71 ptSelectionOutput = ptSelectionOutput,
72 forceFullSimConfig = forceFullSimConfig)
73 makePhotonWorkingPointSequence (seq, dataType, workingPoint, postfix = postfix,
74 recomputeIsEM = recomputeIsEM,
75 forceFullSimConfig = forceFullSimConfig)
76 makeSharedObjectSequence (seq, deepCopyOutput = deepCopyOutput,
77 shallowViewOutput = shallowViewOutput,
78 postfix =
'_Photon' + postfix,
79 enableCutflow = enableCutflow,
80 enableKinematicHistograms = enableKinematicHistograms,
81 defineSystObjectLinks = defineSystObjectLinks )
93 enableCleaning = True,
94 cleaningAllowLate = False,
95 recomputeIsEM = False,
96 ptSelectionOutput = False,
97 forceFullSimConfig = False):
98 """Create photon calibration analysis algorithms
100 This makes all the algorithms that need to be run first befor
101 all working point specific algorithms and that can be shared
102 between the working points.
105 dataType -- The data type to run on ("data", "mc" or "afii")
106 postfix -- a postfix to apply to decorations and algorithm
107 names. this is mostly used/needed when using this
108 sequence with multiple working points to ensure all
110 crackVeto -- Whether or not to perform eta crack veto
111 enableCleaning -- Enable photon cleaning
112 cleaningAllowLate -- Whether to ignore timing information in cleaning.
113 recomputeIsEM -- Whether to rerun the cut-based selection. If not, use derivation flags
114 ptSelectionOutput -- Whether or not to apply pt selection when creating
119 if dataType
not in [
'data',
'mc',
'afii' ]:
120 raise ValueError(
'Invalid data type: %s' % dataType )
122 if forceFullSimConfig:
123 print(
"WARNING! You are running makePhotonCalibrationSequence forcing full sim config")
124 print(
"WARNING! This is only intended to be used for testing purposes")
126 cleaningWP =
'NoTime' if cleaningAllowLate
else ''
129 alg =
createAlgorithm(
'CP::AsgShallowCopyAlg',
'PhotonShallowCopyAlg' + postfix )
130 seq.append( alg, inputPropName =
'input',
131 outputPropName =
'output',
132 stageName =
'prepare')
135 alg =
createAlgorithm(
'CP::AsgSelectionAlg',
'PhotonEtaCutAlg' + postfix )
136 alg.selectionDecoration =
'selectEta' + postfix +
',as_bits'
137 addPrivateTool( alg,
'selectionTool',
'CP::AsgPtEtaSelectionTool' )
138 alg.selectionTool.maxEta = 2.37
140 alg.selectionTool.etaGapLow = 1.37
141 alg.selectionTool.etaGapHigh = 1.52
142 alg.selectionTool.useClusterEta =
True
143 seq.append( alg, inputPropName =
'particles',
144 stageName =
'calibration',
145 metaConfig = {
'selectionDecorNames' : [alg.selectionDecoration],
146 'selectionDecorNamesOutput' : [alg.selectionDecoration],
147 'selectionDecorCount' : [5
if crackVeto
else 4]},
148 dynConfig = {
'preselection' :
lambda meta :
"&&".join (meta[
"selectionDecorNamesOutput"])} )
151 if recomputeIsEM
and dataType ==
'mc':
153 'PhotonShowerShapeFudgeAlg' + postfix )
155 'ElectronPhotonVariableCorrectionTool' )
156 alg.showerShapeFudgeTool.ConfigFile = \
157 'EGammaVariableCorrection/TUNE23/ElPhVariableNominalCorrection.conf'
158 seq.append( alg, inputPropName =
'photons', outputPropName =
'photonsOut',
159 stageName =
'calibration',
160 dynConfig = {
'preselection' :
lambda meta :
"&&".join (meta[
"selectionDecorNamesOutput"])} )
164 alg =
createAlgorithm(
'CP::AsgSelectionAlg',
'PhotonObjectQualityAlg' + postfix )
165 alg.selectionDecoration =
'goodOQ,as_bits'
166 addPrivateTool( alg,
'selectionTool',
'CP::EgammaIsGoodOQSelectionTool' )
167 alg.selectionTool.Mask = xAOD.EgammaParameters.BADCLUSPHOTON
168 seq.append( alg, inputPropName =
'particles',
169 stageName =
'calibration',
170 metaConfig = {
'selectionDecorNames' : [alg.selectionDecoration],
171 'selectionDecorNamesOutput' : [alg.selectionDecoration],
172 'selectionDecorCount' : [1]},
173 dynConfig = {
'preselection' :
lambda meta :
"&&".join (meta[
"selectionDecorNamesOutput"])} )
177 alg =
createAlgorithm(
'CP::AsgSelectionAlg',
'PhotonCleaningAlg' + postfix)
178 addPrivateTool( alg,
'selectionTool',
'CP::AsgFlagSelectionTool' )
179 alg.selectionDecoration =
'isClean,as_bits'
180 alg.selectionTool.selectionFlags = [
'DFCommonPhotonsCleaning' + cleaningWP]
181 seq.append( alg, inputPropName =
'particles',
182 stageName =
'calibration',
183 metaConfig = {
'selectionDecorNames' : [alg.selectionDecoration],
184 'selectionDecorNamesOutput' : [alg.selectionDecoration],
185 'selectionDecorCount' : [1]},
186 dynConfig = {
'preselection' :
lambda meta :
"&&".join (meta[
"selectionDecorNamesOutput"])} )
192 'PhotonOriginCorrectionAlg' + postfix)
193 seq.append( alg, inputPropName =
'photons', outputPropName =
'photonsOut',
194 stageName =
'calibration',
195 dynConfig = {
'preselection' :
lambda meta :
"&&".join (meta[
"selectionDecorNamesOutput"])} )
199 'PhotonCalibrationAndSmearingAlg' + postfix )
201 'CP::EgammaCalibrationAndSmearingTool' )
202 alg.calibrationAndSmearingTool.ESModel =
'es2022_R22_PRE'
203 alg.calibrationAndSmearingTool.decorrelationModel =
'1NP_v1'
204 alg.calibrationAndSmearingTool.useFastSim = (0
if forceFullSimConfig
205 else int(dataType ==
'afii'))
206 seq.append( alg, inputPropName =
'egammas', outputPropName =
'egammasOut',
207 stageName =
'calibration',
208 dynConfig = {
'preselection' :
lambda meta :
"&&".join (meta[
"selectionDecorNamesOutput"])} )
211 alg =
createAlgorithm(
'CP::AsgSelectionAlg',
'PhotonPtCutAlg' + postfix )
212 alg.selectionDecoration =
'selectPt' + postfix +
',as_bits'
213 addPrivateTool( alg,
'selectionTool',
'CP::AsgPtEtaSelectionTool' )
214 alg.selectionTool.minPt = 10e3
215 seq.append( alg, inputPropName =
'particles',
216 stageName =
'selection',
217 metaConfig = {
'selectionDecorNames' : [alg.selectionDecoration],
218 'selectionDecorNamesOutput' : [alg.selectionDecoration]
if ptSelectionOutput
else [],
219 'selectionDecorCount' : [2]},
220 dynConfig = {
'preselection' :
lambda meta :
"&&".join (meta[
"selectionDecorNamesOutput"])} )
224 'PhotonIsolationCorrectionAlg' + postfix )
226 'CP::IsolationCorrectionTool' )
227 alg.isolationCorrectionTool.IsMC =
int(dataType !=
'data')
228 alg.isolationCorrectionTool.AFII_corr = (0
if forceFullSimConfig
229 else dataType ==
'afii')
230 seq.append( alg, inputPropName =
'egammas', outputPropName =
'egammasOut',
231 stageName =
'selection',
232 dynConfig = {
'preselection' :
lambda meta :
"&&".join (meta[
"selectionDecorNamesOutput"])} )
240 recomputeIsEM = False,
241 forceFullSimConfig = False):
242 """Create photon analysis algorithms for a single working point
245 dataType -- The data type to run on ("data", "mc" or "afii")
246 workingPoint -- The working point to use
247 postfix -- a postfix to apply to decorations and algorithm
248 names. this is mostly used/needed when using this
249 sequence with multiple working points to ensure all
251 recomputeIsEM -- Whether to rerun the cut-based selection. If not, use derivation flags
255 if dataType
not in [
'data',
'mc',
'afii' ]:
256 raise ValueError(
'Invalid data type: %s' % dataType )
258 if forceFullSimConfig:
259 print(
"WARNING! You are running makePhotonWorkingPointSequence forcing full sim config")
260 print(
"WARNING! This is only intended to be used for testing purposes")
262 splitWP = workingPoint.split (
'.')
263 if len (splitWP) != 2 :
264 raise ValueError (
'working point should be of format "quality.isolation", not ' + workingPoint)
266 qualityWP = splitWP[0]
267 isolationWP = splitWP[1]
269 if qualityWP ==
'Tight' :
270 quality = ROOT.egammaPID.PhotonTight
272 elif qualityWP ==
'Loose' :
273 quality = ROOT.egammaPID.PhotonLoose
276 raise Exception (
'unknown photon quality working point "' + qualityWP +
'" should be Tight or Loose')
279 alg =
createAlgorithm(
'CP::AsgSelectionAlg',
'PhotonIsEMSelectorAlg' + postfix )
280 alg.selectionDecoration =
'selectEM,as_bits'
284 alg.selectionTool.isEMMask = quality
285 alg.selectionTool.ConfigFile = \
286 'ElectronPhotonSelectorTools/offline/20180116/PhotonIsEMTightSelectorCutDefs.conf'
289 addPrivateTool( alg,
'selectionTool',
'CP::AsgFlagSelectionTool' )
290 dfFlag =
'DFCommonPhotonsIsEM' + qualityWP
291 alg.selectionTool.selectionFlags = [ dfFlag ]
293 seq.append( alg, inputPropName =
'particles',
294 stageName =
'calibration',
295 metaConfig = {
'selectionDecorNames' : [alg.selectionDecoration],
296 'selectionDecorNamesOutput' : [alg.selectionDecoration],
297 'selectionDecorCount' : [32
if recomputeIsEM
else 1]},
298 dynConfig = {
'preselection' :
lambda meta :
"&&".join (meta[
"selectionDecorNamesOutput"])} )
301 if isolationWP !=
'NonIso' :
303 'PhotonIsolationSelectionAlg' + postfix )
304 alg.selectionDecoration =
'isolated' + postfix +
',as_bits'
305 addPrivateTool( alg,
'selectionTool',
'CP::IsolationSelectionTool' )
306 alg.selectionTool.PhotonWP = isolationWP
308 seq.append( alg, inputPropName =
'egammas',
309 stageName =
'selection',
310 metaConfig = {
'selectionDecorNames' : [alg.selectionDecoration],
311 'selectionDecorNamesOutput' : [alg.selectionDecoration],
312 'selectionDecorCount' : [1]},
313 dynConfig = {
'preselection' :
lambda meta :
"&&".join (meta[
"selectionDecorNamesOutput"])} )
318 'PhotonEfficiencyCorrectionAlg' + postfix )
320 'AsgPhotonEfficiencyCorrectionTool' )
321 alg.scaleFactorDecoration =
'ph_effSF' + postfix +
'_%SYS%'
322 if dataType ==
'afii':
323 print(
"WARNING! No AFII ID SFs are available for now for photon efficiency")
324 alg.efficiencyCorrectionTool.ForceDataType = \
325 PATCore.ParticleDataType.Full
326 elif dataType ==
'mc':
327 alg.efficiencyCorrectionTool.ForceDataType = \
328 PATCore.ParticleDataType.Full
330 alg.outOfValidity = 2
331 alg.outOfValidityDeco =
'bad_eff' + postfix
332 if dataType !=
'data':
333 seq.append( alg, inputPropName =
'photons',
334 stageName =
'efficiency',
335 dynConfig = {
'preselection' :
lambda meta :
"&&".join (meta[
"selectionDecorNamesOutput"])} )
342 'PhotonSelectionSummary' + postfix )
343 alg.selectionDecoration =
'baselineSelection' + postfix +
',as_char'
344 seq.append( alg, inputPropName =
'particles',
345 stageName =
'selection',
346 dynConfig = {
'preselection' :
lambda meta :
"&&".join (meta[
"selectionDecorNames"])} )