Forked from
atlas / athena
140100 commits behind, 11109 commits ahead of the upstream repository.
-
Marcelo Vogel authored
Former-commit-id: 20cf8aebf12692d816aa03e99c5c32dbc3d087fd
Marcelo Vogel authoredFormer-commit-id: 20cf8aebf12692d816aa03e99c5c32dbc3d087fd
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
trfArgs.py 36.16 KiB
# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
## @Package PyJobTransforms.trfArgs
# @brief Standard arguments supported by trf infrastructure
# @author atlas-comp-transforms-dev@cern.ch
# @version $Id: trfArgs.py 764176 2016-07-25 16:07:54Z mavogel $
import logging
msg = logging.getLogger(__name__)
import PyJobTransforms.trfArgClasses as trfArgClasses
from PyJobTransforms.trfArgClasses import argFactory
from PyJobTransforms.trfLogger import stdLogLevels
## Add standard transform arguments to an argparse ArgumentParser
def addStandardTrfArgs(parser):
parser.add_argument('--verbose', '--debug', action='store_true', help='Set transform loglevel to DEBUG')
parser.add_argument('--loglevel', choices=stdLogLevels.keys(), help='Set transform logging level')
parser.add_argument('--argJSON', '--argjson', metavar='FILE', help='File containing JSON serialised argument dictionary')
parser.add_argument('--dumpargs', action='store_true', help='Dump transform arguments and exit')
parser.add_argument('--showGraph', action='store_true', help='Show multi-step transform graph, then exit')
parser.add_argument('--showPath', action='store_true', help='Show execution path only, then exit')
parser.add_argument('--showSteps', action='store_true', help='Show list of executor steps only, then exit')
parser.add_argument('--dumpPickle', metavar='FILE', help='Interpret command line arguments and write them out as a pickle file')
parser.add_argument('--dumpJSON', metavar='FILE', help='Interpret command line arguments and write them out as a JSON file')
parser.add_argument('--reportName', type=argFactory(trfArgClasses.argString, runarg=False),
help='Base name for job reports (default name is "jobReport" for most reports, but "metadata" for classic prodsys XML)')
parser.add_argument('--reportType', type=argFactory(trfArgClasses.argList, runarg=False), nargs='+', metavar='TYPE',
help='Job reports to produce: valid values are "text", "json", "classic", "pilotPickle" and "gpickle"')
parser.add_argument('--execOnly', action='store_true',
help='Exec the first substep only, replacing the transform process (no job reports and the return code will be from the substep process)')
parser.add_argument('--env', type=argFactory(trfArgClasses.argSubstepList, runarg=False), metavar='substep:KEY=VALUE', nargs='+',
help='Explicitly set environment variables for an executor (default is all substeps).'
' N.B. this setting is passed to the shell, so reference to shell variables is allowed, e.g.'
' KEY=VALUE:$KEY')
parser.add_argument('--imf', type=argFactory(trfArgClasses.argSubstepBool, runarg=False), metavar="substep:BOOL", nargs='+',
help='Manually include/exclude the Intel IMF maths library '
'(otherwise this is disabled for base releases < 17.7, enabled otherwise)')
parser.add_argument('--tcmalloc', type=argFactory(trfArgClasses.argSubstepBool, runarg=False), metavar="substep:BOOL", nargs='+',
help='Switch preload of the tcmalloc library (disabled by default)')
parser.add_argument('--steering', type=argFactory(trfArgClasses.argSubstepSteering, runarg=False), nargs='+', metavar='substep:{in/out}{+-}DATA',
help='Steer the transform by manipulating the execution graph before the execution path is calculated. '
'Format is substep:{in,out}{+-}DATA,{in,out}{+-}DATA,... to modify the substep\'s input/output '
' by adding/removing a data type. e.g. RAWtoESD:in-RDO,in+RDO_TRIG would remove RDO and add '
'RDO_TRIG to the list of valid input datatypes for the RAWtoESD substep. See current version of '
'trfArgClasses.argSubstepSteering.steeringAlises for supported aliases. '
'https://twiki.cern.ch/twiki/bin/view/AtlasComputing/TransformSteering')
addMetadataArguments(parser)
## Options related to running athena in general
# TODO: Some way to mask certain options (perExec, e.g.)
## @brief Add standard athena options
# @param parser trfArgParser object
# @param maxEventsDefaultSubstep Special option which can change the default substep for maxEvents (needed by
# some special transforms).
def addAthenaArguments(parser, maxEventsDefaultSubstep='first', addValgrind=True):
parser.defineArgGroup('Athena', 'General Athena Options')
parser.add_argument('--athenaopts', group = 'Athena', type=argFactory(trfArgClasses.argSubstepList, splitter=' ', runarg=False), nargs="+", metavar='substep:ATHENAOPTS',
help='Extra options to pass to athena. Opts will split on spaces. '
'Multiple substep options can be given with --athenaopts=\'sutbstep1:--opt1 --opt2[=foo] ...\' \'substep2:--opt3\''
'Without substep specified, options will be used for all substeps.')
parser.add_argument('--command', '-c', group = 'Athena', type=argFactory(trfArgClasses.argString, runarg=False), metavar='COMMAND',
help='Run %(metavar)s before all else')
parser.add_argument('--athena', group = 'Athena', type=argFactory(trfArgClasses.argString, runarg=False), metavar='ATHENA',
help='Use %(metavar)s as the athena executable')
parser.add_argument('--preExec', group = 'Athena', type=argFactory(trfArgClasses.argSubstepList), nargs='+',
metavar='substep:PREEXEC',
help='Python code to execute before main job options are included (can be optionally limited to a single substep)')
parser.add_argument('--preInclude', group = 'Athena', type=argFactory(trfArgClasses.argSubstepList, splitter=','), nargs='+',
metavar='substep:PREINCLUDE',
help='Python configuration fragment to include before main job options (can be optionally limited to a single substep). Will split on commas: frag1.py,frag2.py is understood.')
parser.add_argument('--postExec', group = 'Athena', type=argFactory(trfArgClasses.argSubstepList), nargs='+',
metavar='substep:POSTEXEC',
help='Python code to execute after main job options are included (can be optionally limited to a single substep)')
parser.add_argument('--postInclude', group = 'Athena', type=argFactory(trfArgClasses.argSubstepList, splitter=','), nargs='+',
metavar='substep:POSTINCLUDE',
help='Python configuration fragment to include after main job options (can be optionally limited '
'to a single substep). Will split on commas: frag1.py,frag2.py is understood.')
parser.add_argument('--maxEvents', group='Athena', type=argFactory(trfArgClasses.argSubstepInt, defaultSubstep=maxEventsDefaultSubstep),
nargs='+', metavar='substep:maxEvents',
help='Set maximum events for each processing step (default substep is "{0}")'.format(maxEventsDefaultSubstep))
parser.add_argument('--skipEvents', group='Athena', nargs='+', type=argFactory(trfArgClasses.argSubstepInt, defaultSubstep='first'),
help='Number of events to skip over in the first processing step (skipping substep can be overridden)')
parser.add_argument('--asetup', group='Athena', type=argFactory(trfArgClasses.argSubstep, runarg=False), nargs='+', metavar='substep:ASETUP',
help='asetup command string to be run before this substep is executed')
parser.add_argument('--eventAcceptanceEfficiency', type=trfArgClasses.argFactory(trfArgClasses.argSubstepFloat, min=0.0, max=1.0, runarg=False),
help='Allowed "efficiency" for processing events - used to ensure output file has enough events (default 1.0)')
parser.add_argument('--athenaMPMergeTargetSize', '--mts', type=trfArgClasses.argFactory(trfArgClasses.argKeyFloatValueList, runarg=False),
metavar='dataType:targetSizeInMegaBytes', nargs='+', group='Athena',
help='Set the target merge size for an AthenaMP output file type (give size in MB). '
'Note that the special value 0 means do not merge this output file; negative values mean '
'always merge to a single file. Globbing is supported, e.g. "DESD_*:500" is understood. '
'Special datatype "ALL" can be used as a default for all datatypes not explicitly '
'given their own value or glob matched.')
parser.add_argument('--athenaMPStrategy', type=trfArgClasses.argFactory(trfArgClasses.argSubstep, runarg=False),
nargs='+', metavar='substep:Strategy', group='Athena',
help='Set the AthenaMP scheduling strategy for a particular substep. Default is unset, '
'except when n_inputFiles = n_workers, when it is "FileScheduling" (useful for '
'ephemeral outputs).')
parser.add_argument('--athenaMPUseEventOrders', type=trfArgClasses.argFactory(trfArgClasses.argBool, runarg=False),
metavar='BOOL', group='Athena',
help='Change AthenaMP setup to read event numbers from event orders files')
parser.add_argument('--athenaMPEventsBeforeFork', type=trfArgClasses.argFactory(trfArgClasses.argInt, runarg=False),
metavar='N', group='Athena',
help='Set AthenaMP to fork after processing N events (default is to fork immediately after '
'initialisation')
parser.add_argument('--sharedWriter', type=trfArgClasses.argFactory(trfArgClasses.argBool, runarg=False),
metavar='BOOL', group='Athena',
help='SharedWriter mode active')
parser.add_argument('--eventService', type=trfArgClasses.argFactory(trfArgClasses.argBool, runarg=True),
metavar='BOOL', group='Athena',
help='Switch AthenaMP to the Event Service configuration')
if addValgrind:
addValgrindArguments(parser)
## @brief Add Valgrind options
def addValgrindArguments(parser):
parser.defineArgGroup('Valgrind', 'General Valgrind Options')
parser.add_argument(
'--valgrind',
group = 'Valgrind',
type = argFactory(
trfArgClasses.argBool,
runarg = False
),
metavar = "substep:BOOL",
help = 'Enable Valgrind'
)
parser.add_argument(
'--valgrindDefaultOpts',
group = 'Valgrind',
type = argFactory(
trfArgClasses.argBool,
runarg = False
),
metavar = "substep:BOOL",
help = 'Enable default Valgrind options'
)
parser.add_argument(
'--valgrindExtraOpts',
group = 'Valgrind',
type = argFactory(
trfArgClasses.argList,
splitter = ',',
runarg = False
),
metavar = 'OPT1,OPT2,OPT3',
help = 'Extra options passed to Valgrind when running Athena. ' +
'Options starting with "-" must be given as ' +
'--valgrindopts=\'--opt1=foo,--opt2=bar,...\''
)
## @brief Options related to the setup of the ATLAS detector (used in simulation and digitisation
# as well as reconstruction)
# @param parser trfArgParser object
def addDetectorArguments(parser):
parser.defineArgGroup('Detector', 'General detector configuration options, for simulation and reconstruction')
parser.add_argument('--DBRelease', group = 'Detector', type=argFactory(trfArgClasses.argSubstep, runarg=False), metavar='substep:DBRelease', nargs='+',
help='Use DBRelease instead of ORACLE. Give either a DBRelease tarball file (e.g., DBRelease-21.7.1.tar.gz) or cvmfs DBRelease directory (e.g., 21.7.1 or current')
parser.add_argument('--conditionsTag', group='Detector', type=argFactory(trfArgClasses.argSubstepConditions), metavar='substep:CondTag', nargs='+',
help='Conditions tag to set')
parser.add_argument('--geometryVersion', group='Detector', type=argFactory(trfArgClasses.argSubstep), metavar='substep:GeoVersion', nargs='+',
help='ATLAS geometry version tag')
parser.add_argument('--beamType', group='Detector', type=argFactory(trfArgClasses.argString),
help='Manual beam type setting')
parser.add_argument('--runNumber', '--RunNumber', group='Detector', type=argFactory(trfArgClasses.argInt),
help='Manual run number setting')
## @brief Options for passing metadata into the transform
# @param parser trfArgParser object
def addMetadataArguments(parser):
parser.defineArgGroup('Metadata', 'Metadata arguments that will be passed into the transform')
parser.add_argument('--AMIConfig', '--AMI', type=argFactory(trfArgClasses.argString, runarg=False), help='Configure transform with AMI tag parameters', group="Metadata")
parser.add_argument('--AMITag', type=argFactory(trfArgClasses.argString), metavar='TAG', group="Metadata",
help='AMI tag from which this job was defined - this option simply writes the '
'relevant AMI tag value into the output metadata, it does not configure the job (use --AMIConfig for that)')
parser.add_argument('--taskid', type=argFactory(trfArgClasses.argString, runarg=False), help="Task identification number", group="Metadata")
parser.add_argument('--jobid', type=argFactory(trfArgClasses.argString, runarg=False), help="Job identification number", group="Metadata")
parser.add_argument('--attempt', type=argFactory(trfArgClasses.argString, runarg=False), help="Job attempt number", group="Metadata")
## @brief Add primary DPD arguments
# @detailed Get the list of current primary DPDs and add then to the parser
# optionally only some DPDs may be added, using the @c pick list. This function
# uses the @c silent decorator to supress useless messages from ROOT
# @param parser Argument parser object to add arguments to
# @param pick Optional list of DPD types to add (use short names, e.g., @c DESDM_MUON)
# @param transform Transform object. DPD data types will be added to the correct executor (by name or substep)
# @param multipleOK If the @c multipleOK flag should be set for this argument
# @param RAWtoALL Flag if DPDs should be made direct from bytestream, instead of 'classic' workflow
#@silent
def addPrimaryDPDArguments(parser, pick = None, transform = None, multipleOK=False, RAWtoALL=False):
parser.defineArgGroup('Primary DPDs', 'Primary DPD File Options')
# list* really gives just a list of DPD names
try:
from PrimaryDPDMaker.PrimaryDPDFlags import listRAWtoDPD,listESDtoDPD,listAODtoDPD
if RAWtoALL:
listRAWtoDPD.extend(listESDtoDPD)
matchedOutputList = [(['r2a'], listRAWtoDPD), (['a2d'], listAODtoDPD)]
else:
matchedOutputList = [(['r2e'], listRAWtoDPD), (['e2d'], listESDtoDPD), (['a2d'], listAODtoDPD)]
for substep, dpdList in matchedOutputList:
for dpdName in [ dpd.replace('Stream', '') for dpd in dpdList ]:
msg.debug('Handling {0}'.format(dpdName))
if pick == None or dpdName in pick:
# Need to decide which file type we actually have here
dpdType = dpdName.split('_')[0]
if 'RAW' in dpdType:
parser.add_argument('--output' + dpdName + 'File',
type=argFactory(trfArgClasses.argBSFile, multipleOK=multipleOK, type='RAW'),
group = 'Primary DPDs', metavar=dpdName.upper(),
help='DPD {0} output {1} file'.format(dpdType, dpdName))
elif 'AOD' in dpdType:
parser.add_argument('--output' + dpdName + 'File',
type=argFactory(trfArgClasses.argPOOLFile, multipleOK=multipleOK, type='AOD'),
group = 'Primary DPDs', metavar=dpdName.upper(),
help='DPD {0} output {1} file'.format(dpdType, dpdName))
elif 'ESD' in dpdType:
parser.add_argument('--output' + dpdName + 'File',
type=argFactory(trfArgClasses.argPOOLFile, multipleOK=multipleOK, type='ESD'),
group = 'Primary DPDs', metavar=dpdName.upper(),
help='DPD {0} output {1} file'.format(dpdType, dpdName))
else:
msg.warning('Unrecognised primary DPD type: {0}'.format(dpdName))
# Automatically add DPD as output data arguments of their relevant executors
if transform:
for executor in transform.executors:
if hasattr(executor, 'substep') and executor.substep in substep:
executor.outDataUpdate([dpdName])
if executor.name in substep:
executor.outDataUpdate([dpdName])
except ImportError:
msg.warning('PrimaryDPDFlags not available - cannot add primary DPD arguments')
## @brief Add top DAOD arguments
# @detailed Get the list of current top ADODs and add then to the parser
# optionally only some DPDs may be added, using the @c pick list.
# @param @c parser Argument parser object to add arguments to
# @param @c pick Optional list of DPD types to add (use short names, e.g., @c D2AODM_TOPJET)
def addTopPhysDAODArguments(parser, pick = None):
parser.defineArgGroup('Top DAODs', 'Top Physics DAOD File Options')
# TopPhysAllDAODs is a list of JobProperty type objects
try:
from TopPhysD2PDMaker.TopPhysD2PDFlags import TopPhysAllDAODs
for dpdWriter in TopPhysAllDAODs:
dpdName = dpdWriter.StreamName.replace('Stream', '')
if pick == None or dpdName in pick:
parser.add_argument('--output' + dpdName + 'File',
type=argFactory(trfArgClasses.argFile, substep=['a2d']), group='Top DAODs',
metavar=dpdName.upper(), help='Top ADOD output %s file (substep [a2d])' % (dpdName,))
except ImportError:
msg.warning('TopPhysD2PDFlags not available - cannot add D2PD arguments')
## @brief Add D3PD arguments
# @detailed Get the list of current D3PDs and add then to the parser
# optionally only some DPDs may be added, using the @c pick list.
# @param parser Argument parser object to add arguments to
# @param pick Optional list of DPD types to add (use short names, e.g., @c NTUP_EGAMMA)
# @param transform Transform object. DPD data types will be added to the correct executor (by name or substep)
# @param multipleOK If the @c multipleOK flag should be set for this argument
# @param addD3PDMRGtypes Instead of normal output types for D3PDs, add @em input NTUPs and
# @em output merge NTUPs
def addD3PDArguments(parser, pick = None, transform = None, multipleOK=False, addD3PDMRGtypes = False):
parser.defineArgGroup('D3PD NTUPs', 'D3PD File Options')
# listAllKnownD3PD is a list of D3PD JobProperty type objects
try:
from D3PDMakerConfig.D3PDProdFlags import listAllKnownD3PD
for dpdWriter in listAllKnownD3PD:
dpdName = dpdWriter.StreamName.replace('Stream', '')
if pick == None or dpdName in pick:
if addD3PDMRGtypes:
parser.add_argument('--input' + dpdName + 'File',
type=argFactory(trfArgClasses.argNTUPFile, treeNames=dpdWriter.TreeNames, io='input'),
group='D3PD NTUPs',
metavar=dpdName.upper(), help='D3PD input {0} file )'.format(dpdName), nargs='+')
parser.add_argument('--output' + dpdName + '_MRGFile',
type=argFactory(trfArgClasses.argNTUPFile, treeNames=dpdWriter.TreeNames),
group='D3PD NTUPs',
metavar=dpdName.upper(), help='D3PD merged output {0} file )'.format(dpdName))
else:
parser.add_argument('--output' + dpdName + 'File',
type=argFactory(trfArgClasses.argNTUPFile, treeNames=dpdWriter.TreeNames, multipleOK=multipleOK),
group='D3PD NTUPs', metavar=dpdName.upper(),
help='D3PD output {0} file (can be made in substeps {1})'.format(dpdName, ','.join(dpdWriter.SubSteps)))
# Automatically add D3PDs as data arguments of their relevant executors
if transform:
for executor in transform.executors:
if hasattr(executor, 'substep') and executor.substep in dpdWriter.SubSteps:
executor.outDataUpdate([dpdName])
if executor.name in dpdWriter.SubSteps:
executor.outDataUpdate([dpdName])
except ImportError:
msg.warning('D3PDProdFlags not available - cannot add D3PD arguments')
## @brief Add reduction framework output file argument
# @detailed This is the base name for the NTUP output streams. It will get appended
# to it the names of the specific reduced types.
# @param parser Argument parser object to add arguments to
# @param transform Transform object, to add reduced object to (maybe don't need that here?)
def addReductionArguments(parser, transform = None):
parser.defineArgGroup('Reduction', 'Reduced Filetype Options')
parser.add_argument('--inputNTUP_COMMONFile',
type=argFactory(trfArgClasses.argNTUPFile, io='input', treeNames=['physics']),
group='Reduction', help='NTUP common input file', nargs='+')
parser.add_argument('--outputDNTUPFile',
type=argFactory(trfArgClasses.argNTUPFile, treeNames=None),
group='Reduction', help='Reduced NTUP output filename base')
parser.add_argument('--outputDAODFile',
type=argFactory(trfArgClasses.argPOOLFile, io='output', type='aod'),
help='Output reduced AOD filename base', group='Reduction')
parser.add_argument('--reductionConf',
type=argFactory(trfArgClasses.argList), nargs='+',
help='Configuration of reduced stream outputs', group='Reduction')
parser.add_argument('--passThrough', type=argFactory(trfArgClasses.argBool), metavar="True/False",
help='Run the derivation framework in a pass-through mode, needed for some MC samples. Needs to be implemented in derivation JOs')
## @brief Simple class to store information about extra DPD filetypes
# @detailed Implement this type of information as a class allowing for
# extensions to be easily added and for some convenient heuristics
# in the constructor
class dpdType(object):
## @brief Class constructor for dpdType
# @param name The name of this datatype (e.g., @c DRAW_ZEE, @c NTUP_SCT)
# @param type The argFile.type (should be the major datatype, e.g. @c BS, @c ESD, @c AOD, etc.)
# @param substeps The substeps or executor names where this data can be made
# @param argclass The argument class to be used for this data
# @param treeNames For DPD types only, the tree(s) used for event counting (if @c None then
# no event counting can be done.
# @param help Help string to generate for this argument
def __init__(self, name, type = None, substeps = [], argclass = None, treeNames = None, help = None):
self._name = name
## @note Not very clear how useful this actually is, but we
# implement some heuristics here to avoid having to set
# the argFile.type always by hand
if type is None:
if 'RAW' in name:
self._type = 'bs'
elif 'ESD' in name:
self._type = 'esd'
elif 'AOD' in name:
self._type = 'aod'
elif 'NTUP' in name:
self._type = 'ntup'
else:
self._type = type
## @note If not given explictly apply some heuristics, watch out for this
# if your data is made in a non-standard step
if substeps == []:
if 'RAW' in name:
self._substeps = ['RAWtoESD']
elif 'ESD' in name:
self._substeps = ['RAWtoESD']
elif 'AOD' in name:
self._substeps = ['ESDtoAOD']
elif 'NTUP' in name:
self._substeps = ['ESDtoDPD', 'AODtoDPD']
else:
self._substeps = substeps
## @note Similarly if no explcit class is given we guess, YMMV
if argclass is None:
if 'RAW' in name:
self._argclass = trfArgClasses.argBSFile
elif 'ESD' in name:
self._argclass = trfArgClasses.argPOOLFile
elif 'AOD' in name:
self._argclass = trfArgClasses.argPOOLFile
elif 'NTUP' in name:
self._argclass = trfArgClasses.argNTUPFile
else:
self._argclass = argclass
self._help = help
self._treeNames = treeNames
@property
def name(self):
return self._name
@property
def type(self):
return self._type
@property
def substeps(self):
return self._substeps
@property
def argclass(self):
return self._argclass
@property
def help(self):
return self._help
@property
def treeNames(self):
return self._treeNames
def getExtraDPDList(NTUPOnly = False):
extraDPDs = []
extraDPDs.append(dpdType('NTUP_SCT', substeps=['r2e']))
extraDPDs.append(dpdType('NTUP_MUONCALIB', substeps=['r2e','r2a'], treeNames=['PatternNtupleMaker/Segments']))
extraDPDs.append(dpdType('NTUP_TRKVALID', substeps=['r2e']))
extraDPDs.append(dpdType('NTUP_FASTMON', substeps=['a2t','a2d','e2a']))
extraDPDs.append(dpdType('NTUP_LARNOISE', substeps=['e2d'], treeNames=['CollectionTree']))
extraDPDs.append(dpdType('NTUP_WZ', substeps=['e2d'], treeNames=['physics']))
extraDPDs.append(dpdType('NTUP_TRT', substeps=['e2d'], treeNames=['MyCollectionTree']))
extraDPDs.append(dpdType('NTUP_HECNOISE', substeps=['e2d'], treeNames=['HECNoise']))
extraDPDs.append(dpdType('NTUP_ENHBIAS', substeps=['e2d','e2a'], treeNames=['vertices']))
extraDPDs.append(dpdType('NTUP_TRUTH', substeps=['a2d'], treeNames=['truth']))
extraDPDs.append(dpdType('NTUP_SUSYTRUTH', substeps=['a2d'], treeNames=['truth']))
extraDPDs.append(dpdType('NTUP_HIGHMULT', substeps=['e2a'], treeNames=['MinBiasTree']))
extraDPDs.append(dpdType('NTUP_PROMPTPHOT', substeps=['e2d', 'a2d'], treeNames=["PAUReco","HggUserData"]))
extraDPDs.append(dpdType('NTUP_MCPTP', substeps=['a2d'], help="Ntuple file for MCP Tag and Probe"))
extraDPDs.append(dpdType('NTUP_MCPScale', substeps=['a2d'], help="Ntuple file for MCP scale calibration"))
extraDPDs.append(dpdType('NTUP_FastCaloSim', substeps=['e2d']))
extraDPDs.append(dpdType('NTUP_PILEUP', substeps=['a2da']))
# Trigger NTUPs (for merging only!)
if NTUPOnly:
extraDPDs.append(dpdType('NTUP_TRIGCOST', treeNames=['trig_cost']))
extraDPDs.append(dpdType('NTUP_TRIGRATE', treeNames=['trig_cost']))
extraDPDs.append(dpdType('NTUP_TRIGEBWGHT', treeNames=['trig_cost']))
else:
extraDPDs.append(dpdType('DAOD_HSG2'))
extraDPDs.append(dpdType('DESDM_ZMUMU'))
return extraDPDs
## @brief Add additional DPD arguments
# @detailed Manually add DPDs that, for some reason, are not in any of the automated
# lists parsed by the companion functions above.
# @param parser Argument parser object to add arguments to
# @param pick Optional list of DPD types to add (use short names, e.g., @c NTUP_EGAMMA)
# @param transform Transform object. DPD data types will be added to the correct executor (by name or substep)
# @param multipleOK If the @c multipleOK flag should be set for this argument
# @param NTUPMergerArgs If @c True, add NTUP arguments as input/output types, suitable for NTUPMerge_tf
def addExtraDPDTypes(parser, pick=None, transform=None, multipleOK=False, NTUPMergerArgs = False):
parser.defineArgGroup('Additional DPDs', 'Extra DPD file types')
extraDPDs = getExtraDPDList(NTUPOnly=NTUPMergerArgs)
if NTUPMergerArgs:
for dpd in extraDPDs:
if pick == None or dpd.name in pick:
if dpd.name.startswith('NTUP'):
parser.add_argument('--input' + dpd.name + 'File',
type=argFactory(dpd.argclass, multipleOK=True, io='input', type=dpd.type, treeNames=dpd.treeNames),
group = 'Additional DPDs', metavar=dpd.name.upper(), nargs='+',
help=dpd.help if dpd.help else 'DPD input {0} file'.format(dpd.name))
parser.add_argument('--output' + dpd.name + '_MRGFile',
type=argFactory(dpd.argclass, multipleOK=multipleOK, type=dpd.type, treeNames=dpd.treeNames),
group = 'Additional DPDs', metavar=dpd.name.upper(),
help=dpd.help if dpd.help else 'DPD output merged {0} file'.format(dpd.name))
pass
else:
for dpd in extraDPDs:
if pick == None or dpd.name in pick:
msg.debug('Adding DPD {0} ({1}, {2}, {3}, {4})'.format(dpd.name, dpd.type, dpd.substeps, dpd.treeNames, dpd.argclass))
# NTUPs are a bit special as they can take a treeName to count events
if issubclass(dpd.argclass, trfArgClasses.argNTUPFile):
parser.add_argument('--output' + dpd.name + 'File',
type=argFactory(dpd.argclass, name=dpd.name.upper(), multipleOK=multipleOK, type=dpd.type, treeNames=dpd.treeNames),
group = 'Additional DPDs', metavar=dpd.name.upper(),
help=dpd.help if dpd.help else 'DPD output {0} file'.format(dpd.name))
else:
parser.add_argument('--output' + dpd.name + 'File',
type=argFactory(dpd.argclass, multipleOK=multipleOK, type=dpd.type),
group = 'Additional DPDs', metavar=dpd.name.upper(),
help=dpd.help if dpd.help else 'DPD output {0} file'.format(dpd.name))
if transform:
for executor in transform.executors:
if hasattr(executor, 'substep') and executor.substep in dpd.substeps:
executor.outDataUpdate([dpd.name])
if executor.name in dpd.substeps:
executor.outDataUpdate([dpd.name])
def addFileValidationArguments(parser):
parser.defineArgGroup('File Validation', 'Standard file validation switches')
parser.add_argument('--fileValidation', type = argFactory(trfArgClasses.argBool), metavar='BOOL',
group='File Validation', help='If FALSE skip both input and output file validation (default TRUE; warning - do not use this option in production jobs!)')
parser.add_argument('--inputFileValidation', type = argFactory(trfArgClasses.argBool), metavar='BOOL',
group='File Validation', help='If FALSE skip input file validation (default TRUE; warning - do not use this option in production jobs!)')
parser.add_argument('--outputFileValidation', type = argFactory(trfArgClasses.argBool), metavar='BOOL',
group='File Validation', help='If FALSE skip output file validation (default TRUE; warning - do not use this option in production jobs!)')
parser.add_argument('--parallelFileValidation', type = argFactory(trfArgClasses.argBool), metavar='BOOL',
group='File Validation', help='Parallelise file validation if True')
def addParallelJobProcessorArguments(parser):
parser.defineArgGroup('Parallel Job Processor', 'Parallel Job Processor arguments')
parser.add_argument('----parallelProcessPool', group='pool', type=argFactory(trfArgClasses.argInt, runarg=False), help='Number of processes in pool requested (int)')
def addValidationArguments(parser):
parser.defineArgGroup('Validation', 'Standard job validation switches')
parser.add_argument('--ignoreFiles', '--ignoreFilters', group='Validation', type=argFactory(trfArgClasses.argList, splitter=',', runarg=False),
help='Files containing error patterns to be ignored during logfile scans (will split on commas; use "None" to disable the standard "atlas_error_mask.db")', nargs='+')
parser.add_argument('--ignorePatterns', group='Validation', type=argFactory(trfArgClasses.argList, splitter=',', runarg=False),
help='Regexp error patterns to be ignored during logfile scans (will be applied as a search against the whole logfile line)', nargs='+')
parser.add_argument('--ignoreErrors', type=argFactory(trfArgClasses.argBool, runarg=False), metavar="BOOL", group='Validation',
help='Ignore ERROR lines in logfiles (use with care this can mask serious problems; --ignorePatterns is prefered)')
parser.add_argument('--checkEventCount', type=trfArgClasses.argFactory(trfArgClasses.argSubstepBool, defaultSubstep = 'all', runarg=False),
help='Enable check of output events against input events (default: True)', group='Validation',
metavar="BOOL")
## @brief Add trigger related arguments
def addTriggerArguments(parser, addTrigFilter=True):
parser.defineArgGroup('Trigger', 'Trigger Related Options')
parser.add_argument('--triggerConfig',
type=argFactory(trfArgClasses.argSubstep, defaultSubstep="RDOtoRDOTrigger", separator='='),
metavar='substep=triggerConf',
help='Trigger configuration string (substep aware argument - default is to run trigger in RDOtoRDOTrigger step, '
'use syntax SUBSTEP=TRIGCONF if you want to run trigger somewhere else). '
'N.B. This argument uses EQUALS (=) to separate the substep name from the value.',
group='Trigger', nargs='+')
if addTrigFilter:
parser.add_argument('--trigFilterList',
type=argFactory(trfArgClasses.argList), nargs="+",
help='Trigger filter list (multiple values can be given separately or split on commas; only understood in RAWtoESD)',
group='Trigger')
## Tea for two and two for tea... these arguments are used for testing
def addTeaArguments(parser):
parser.defineArgGroup('Tea', 'Tea Making Options (for testing)')
parser.add_argument('--cupsOfTea', group='Tea', type=argFactory(trfArgClasses.argInt), help='Number of cups of tea requested (int)')
parser.add_argument('--teaType', group='Tea', type=argFactory(trfArgClasses.argString), help='Requested flavour of tea (string)')
parser.add_argument('--mugVolume', group='Tea', type=argFactory(trfArgClasses.argFloat), help='How large a cup to use (float)')
parser.add_argument('--drinkers', group='Tea', nargs='+', type=argFactory(trfArgClasses.argList), help='Who is drinking tea (list)')
## @brief This method adds the current valid list of D3PDs to two lists
def listKnownD3PDs():
inputD3PDList = []
outputD3PDList = []
from D3PDMakerConfig.D3PDProdFlags import listAllKnownD3PD
for dpdWriter in listAllKnownD3PD:
dpdName = dpdWriter.StreamName.replace('Stream', '')
inputD3PDList.append(dpdName)
outputD3PDList.append(dpdName+'_MRG')
return inputD3PDList, outputD3PDList