99 """A helper function to create output algorithm"""
100 alg = config.createAlgorithm(
'CP::AsgxAODNTupleMakerAlg', name)
101 alg.TreeName = self.treeName
102 alg.RootStreamName = self.streamName
103 alg.NonContainers = list(self.nonContainers)
104 branchList = list(vars)
106 branchList_nosys = [branch
for branch
in branchList
if "%SYS%" not in branch]
107 branchList_sys = [branch
for branch
in branchList
if "%SYS%" in branch]
108 alg.Branches = branchList_nosys + branchList_sys
109 if self.defaultBasketSize
is not None:
110 alg.DefaultBasketSize = self.defaultBasketSize
115 log = logging.getLogger(
'OutputAnalysisConfig')
128 keys_message = [repr(key)
for key
in overlapping_keys]
129 raise KeyError(f
"containersFullMET would overwrite the following container keys: {', '.join(keys_message)}")
134 if config.dataType()
is not DataType.Data:
142 keys_message = [repr(key)
for key
in overlapping_keys]
143 raise KeyError(f
"containersOnlyForMC would overwrite the following container keys: {', '.join(keys_message)}")
152 log.warning(
"Skipping unrecognised container prefix '%s' for DSID-filtering in OutputAnalysisConfig...", container)
154 if not filter_dsids (dsid_filters, config):
156 log.info(
"Skipping container prefix '%s' due to DSID filtering...", container)
159 var_container = var.split(
'.')[0].
replace(
'_NOSYS',
'').
replace(
'_%SYS%',
'')
160 if var_container == self.
containers[container]:
161 self.
vars.remove(var)
162 log.info(
"Skipping branch definition '%s' for excluded container %s...", var, var_container)
165 var_container = var.split(
'.')[0].
replace(
'_NOSYS',
'').
replace(
'_%SYS%',
'')
166 if var_container == self.
containers[container]:
168 log.info(
"Skipping MET branch definition '%s' for excluded container %s...", var, var_container)
171 var_container = var.split(
'.')[0].
replace(
'_NOSYS',
'').
replace(
'_%SYS%',
'')
172 if var_container == self.
containers[container]:
174 log.info(
"Skipping truth MET branch definition '%s' for excluded container %s...", var, var_container)
180 if not filter_dsids(dsid_filters, config):
183 if var_pattern
in var:
184 self.
vars.remove(var)
185 log.info(
"Skipping branch definition '%s' due to variable-level DSID filtering...", var)
187 if var_pattern
in var:
189 log.info(
"Skipping MET branch definition '%s' due to variable-level DSID filtering...", var)
191 if var_pattern
in var:
193 log.info(
"Skipping truth MET branch definition '%s' due to variable-level DSID filtering...", var)
196 for prefix, container
in self.
containers.items():
197 origName = config.getOutputContainerOrigin(container)
198 if config.getContainerMeta(origName,
"nonContainer",
False):
199 self.nonContainers.append(origName)
207 outputDict = config.getOutputVars (containerName)
208 for outputName
in outputDict :
209 outputConfig = copy.deepcopy (outputDict[outputName])
210 outputConfig.outputContainerName = config.readName(containerName)
211 outputConfig.prefix = prefix
215 outputConfig.enabled =
True
216 outputConfigs[prefix + outputName] = outputConfig
219 for dsid, dsid_commands
in self.commandsOnlyForDSIDs.items():
220 if filter_dsids([dsid], config):
223 outputConfigsRename = {}
225 words = command.split (
' ')
226 if len (words) == 0 :
227 raise ValueError (
'received empty command for "commands" option')
228 optional = words[0] ==
'optional'
231 if words[0] ==
'enable' :
232 if len (words) != 2 :
233 raise ValueError (
'enable takes exactly one argument: ' + command)
235 for name
in outputConfigs :
236 if re.match (words[1], name) :
237 outputConfigs[name].enabled =
True
239 if not used
and not optional
and config.dataType()
is not DataType.Data:
240 raise KeyError (
'unknown branch pattern for enable: ' + words[1])
241 elif words[0] ==
'disable' :
242 if len (words) != 2 :
243 raise ValueError (
'disable takes exactly one argument: ' + command)
245 for name
in outputConfigs :
246 if re.match (words[1], name) :
247 outputConfigs[name].enabled =
False
249 if not used
and not optional
and config.dataType()
is not DataType.Data:
250 raise KeyError (
'unknown branch pattern for disable: ' + words[1])
251 elif words[0] ==
'rename' :
252 if len (words) != 3 :
253 raise ValueError (
'rename takes exactly two arguments: ' + command)
255 for name
in outputConfigs :
256 if re.match (words[1], name) :
257 new_name = re.sub (words[1], words[2], name)
258 outputConfigsRename[new_name] = copy.deepcopy(outputConfigs[name])
259 outputConfigs[name].enabled =
False
261 if not used
and not optional
and config.dataType()
is not DataType.Data:
262 raise KeyError (
'unknown branch pattern for rename: ' + words[1])
264 raise KeyError (
'unknown command for "commands" option: ' + words[0])
267 outputConfigs.update(outputConfigsRename)
271 autoTruthMetVars =
set()
272 for outputName, outputConfig
in outputConfigs.items():
273 if outputConfig.enabled :
274 if config.isMetContainer (outputConfig.origContainerName)
and outputConfig.prefix
not in self.
containersFullMET:
275 if "Truth" in outputConfig.origContainerName:
276 myVars = autoTruthMetVars
281 if outputConfig.noSys :
282 outputConfig.outputContainerName = outputConfig.outputContainerName.replace (
'%SYS%',
'NOSYS')
283 outputConfig.variableName = outputConfig.variableName.replace (
'%SYS%',
'NOSYS')
285 outputName +=
"_NOSYS"
287 outputName +=
'_%SYS%'
288 branchDecl = f
"{outputConfig.outputContainerName}.{outputConfig.variableName} -> {outputName}"
289 if outputConfig.auxType
is not None :
290 branchDecl += f
" type={outputConfig.auxType}"
291 if config.isMetContainer (outputConfig.origContainerName)
and outputConfig.prefix
not in self.
containersFullMET:
292 if "Truth" in outputConfig.origContainerName:
293 branchDecl += f
" metTerm={self.truthMetTermName}"
295 branchDecl += f
" metTerm={self.metTermName}"
296 myVars.add(branchDecl)
300 allBranches |= self.
vars
301 allBranches |= autoVars
307 allBranches |= userMetVars
308 allBranches |= autoMetVars
310 userTruthMetVars =
set()
311 if config.dataType()
is not DataType.Data:
315 allBranches |= userTruthMetVars
316 allBranches |= autoTruthMetVars
320 alg = config.createAlgorithm(
'CP::RNtupleTreeMakerAlg',
'RNtupleMaker')
321 alg.TreeName = self.treeName
322 alg.RootStreamName = self.streamName
323 alg.OutputStreamName = self.streamName
324 alg.NonContainers = list(self.nonContainers)
326 branchList = list(allBranches)
328 alg.Branches = branchList
333 treeMaker = config.createAlgorithm(
'CP::TreeMakerAlg',
'TreeMaker' )
334 treeMaker.TreeName = self.treeName
335 treeMaker.RootStreamName = self.streamName
339 if self.
vars or autoVars:
342 if self.
metVars or autoMetVars:
345 if config.dataType()
is not DataType.Data
and (self.
truthMetVars or autoTruthMetVars):
346 self.
createOutputAlgs(config,
'TruthMetNTupleMaker', userTruthMetVars | autoTruthMetVars)
348 treeFiller = config.createAlgorithm(
'CP::TreeFillerAlg',
'TreeFiller' )
349 treeFiller.TreeName = self.treeName
350 treeFiller.RootStreamName = self.streamName
356 For each container and for each selection, create a single pass variable in output NTuple,
357 which aggregates all the selections flag of the given selection. For example, this can include
358 pT, eta selections, some object ID selection, overlap removal, etc.
359 The goal is to have only one flag per object and working point in the output NTuple.
361 originalContainersSeen = []
364 containerName = config.getOutputContainerOrigin(outputContainerName)
365 if containerName
in originalContainersSeen:
368 originalContainersSeen.append(containerName)
371 if containerName ==
'EventInfo':
376 selectionNames = config.getSelectionNames(containerName, excludeFrom={
'ftag'})
377 for selectionName
in selectionNames:
379 if selectionName ==
'':
382 if self.skipRedundantSelectionFlags
and "outputSelect" in selectionName:
388 Schedule an algorithm to pick up all cut flags for a given selectionName.
389 The summary selection flag is written to output as selectionFlagPrefix_selectionName.
391 alg = config.createAlgorithm(
'CP::AsgSelectionAlg',
392 f
'ObjectSelectionSummary_{containerName}_{selectionName}')
393 selectionDecoration = f
'baselineSelection_{selectionName}_%SYS%'
394 alg.selectionDecoration = f
'{selectionDecoration},as_char'
395 alg.particles = config.readName (containerName)
396 alg.preselection = config.getFullSelection (containerName, selectionName)
397 config.addOutputVar (containerName, selectionDecoration, self.selectionFlagPrefix +
'_' + selectionName)