ATLAS Offline Software
Classes | Functions | Variables
python.trfAMI Namespace Reference

Classes

class  TagInfo
 Stores the information about a given tag. More...
 
class  TrfConfig
 Stores the configuration of a transform. More...
 

Functions

def _parseExecDict (substep, value)
 Back convert a pre/postExec dictionary into a set of command line compatible strings. More...
 
def _parseIncludeDict (substep, value, joinWithChar=",")
 Back convert a pre/postInclude dictionary into a set of command line compatible strings By default use a comma for joining up the list values. More...
 
def isNewAMITag (tag)
 
def getAMIClient (endpoints=['atlas-replica', 'atlas'])
 Get an AMI client. More...
 
def getProdSysTagsCharacters ()
 Get list of characters of ProdSys tags. More...
 
def getPANDAClient ()
 Get PANDA client. More...
 
def ReadablePANDA (s)
 Un-escape information from PANDA. More...
 
def getTrfConfigFromPANDA (tag)
 Get information about a ProdSys tag from PANDA. More...
 
def get_ami_tag (client, tag, suppressNonJobOptions=True)
 
def remove_enclosing_quotes (s)
 
def getTrfConfigFromAMI (tag, suppressNonJobOptions=True)
 Get information about a T0 tag from AMI. More...
 
def deserialiseFromAMIString (amistring)
 Convert from a string to a python object. More...
 

Variables

 msg
 
 AMIerrorCode
 

Function Documentation

◆ _parseExecDict()

def python.trfAMI._parseExecDict (   substep,
  value 
)
private

Back convert a pre/postExec dictionary into a set of command line compatible strings.

Definition at line 117 of file trfAMI.py.

117 def _parseExecDict(substep, value):
118  string = ""
119  for bit in value:
120  string += " '" + substep + ":" + str(bit).replace("'", "\\'")+"'"
121  return string
122 

◆ _parseIncludeDict()

def python.trfAMI._parseIncludeDict (   substep,
  value,
  joinWithChar = "," 
)
private

Back convert a pre/postInclude dictionary into a set of command line compatible strings By default use a comma for joining up the list values.

Definition at line 126 of file trfAMI.py.

126 def _parseIncludeDict(substep, value, joinWithChar = ","):
127  string = "'"
128  string += substep + ":" + joinWithChar.join(value).replace("'", "\\'")+"'"
129  return string
130 

◆ deserialiseFromAMIString()

def python.trfAMI.deserialiseFromAMIString (   amistring)

Convert from a string to a python object.

As we don't know how the string is encoded we try JSON then a safe eval. This is a bit ugly :-(

Definition at line 534 of file trfAMI.py.

534 def deserialiseFromAMIString(amistring):
535  try:
536  result = json.loads(amistring)
537  except ValueError as e_json:
538  msg.debug("Failed to decode {0} as JSON: {1}".format(amistring, e_json))
539  try:
540  result = ast.literal_eval(amistring)
541  except SyntaxError:
542  errMsg = "Failed to deserialise AMI string '{0}' using JSON or eval".format(amistring)
543  msg.error(errMsg)
544  raise TransformAMIException(AMIerrorCode, errMsg)
545  return result

◆ get_ami_tag()

def python.trfAMI.get_ami_tag (   client,
  tag,
  suppressNonJobOptions = True 
)
Get AMI-tag information.

Args:
    :client: the pyAMI client [ pyAMI.client.Client ]
    :tag: the AMI-tag [ str ]

Returns:
    an array of python dictionnaries.

Definition at line 381 of file trfAMI.py.

381 def get_ami_tag(client, tag, suppressNonJobOptions = True):
382  '''Get AMI-tag information.
383 
384  Args:
385  :client: the pyAMI client [ pyAMI.client.Client ]
386  :tag: the AMI-tag [ str ]
387 
388  Returns:
389  an array of python dictionnaries.
390  '''
391 
392  command = [
393  'AMIGetAMITagInfo',
394  '-amiTag="%s"' % tag,
395  '-cached',
396  ]
397 
398  if suppressNonJobOptions:
399  command += ['-suppressNonJobOptions']
400 
401  msg.debug(command)
402 
403  return client.execute(command, format = 'dict_object').get_rows('amiTagInfo')
404 

◆ getAMIClient()

def python.trfAMI.getAMIClient (   endpoints = ['atlas-replica','atlas'])

Get an AMI client.

Note
Always return a client to the primary replica. The caller is allowed to update the replica via the config.endpoints value.
Returns
pyAMI.client.Client instance

Definition at line 222 of file trfAMI.py.

222 def getAMIClient(endpoints = ['atlas-replica','atlas']):
223  msg.debug('Getting AMI client...')
224 
225  try:
226  from pyAMI.client import Client
227  except ImportError:
228  raise TransformAMIException(AMIerrorCode, 'Import of pyAMI modules failed.')
229 
230  msg.debug("Attempting to get AMI client for endpoints {0}".format(endpoints))
231  amiclient = Client(endpoints, ignore_proxy = True)
232  return amiclient
233 

◆ getPANDAClient()

def python.trfAMI.getPANDAClient ( )

Get PANDA client.

Returns
cx_Oracle cursor instance

Definition at line 248 of file trfAMI.py.

248 def getPANDAClient():
249  msg.debug('Getting PANDA client...')
250  try:
251  import cx_Oracle
252  except ImportError:
253  raise TransformAMIException(AMIerrorCode, 'Import of cx_Oracle failed (is Oracle setup on this machine?).')
254 
255  try:
256  cur = cx_Oracle.connect('atlas_grisli_r/panda_c10@adcr_panda').cursor()
257  except Exception:
258  msg.debug('An exception occurred while connecting to PANDA database: %s', traceback.format_exc())
259  raise TransformAMIException(AMIerrorCode, 'Failed to get PANDA client connection (N.B. this does not work from outside CERN).')
260 
261  return cur
262 

◆ getProdSysTagsCharacters()

def python.trfAMI.getProdSysTagsCharacters ( )

Get list of characters of ProdSys tags.

Returns
list of characters

Definition at line 236 of file trfAMI.py.

237  # Due to move to uniform tag definition in AMI this list is now frozen
238  # So just hard code it
239  msg.debug('Getting list of ProdSys tag characters...')
240 
241  defaultList=['z', 'p', 'e', 's', 'd', 'r', 't', 'a', 'b', 'w']
242 
243  return defaultList
244 
245 

◆ getTrfConfigFromAMI()

def python.trfAMI.getTrfConfigFromAMI (   tag,
  suppressNonJobOptions = True 
)

Get information about a T0 tag from AMI.

Parameters
tagTag for which information is requested
Returns
list of PyJoCbTransforms.trfAMI.TRFConfig instances

Definition at line 416 of file trfAMI.py.

416 def getTrfConfigFromAMI(tag, suppressNonJobOptions = True):
417  msg.debug('Using AMI to get info about tag %s', tag)
418 
419  try:
420 # import pyAMI.atlas.api
421  import pyAMI.exception
422  except ImportError as e:
423  raise TransformAMIException(AMIerrorCode, 'Import of pyAMI modules failed ({0})'.format(e))
424 
425  try:
426  amiclient=getAMIClient()
427 # result = pyAMI.atlas.api.get_ami_tag(amiclient, tag)
428  result = get_ami_tag(amiclient, tag, suppressNonJobOptions)
429  except pyAMI.exception.Error as e:
430  msg.warning('An exception occured when connecting to primary AMI: {0}'.format(e))
431  msg.debug('Exception: {0}'.format(e))
432  if 'please login' in e.message or 'certificate expired' in e.message:
433  raise TransformAMIException(AMIerrorCode, 'Getting tag info from AMI failed with credential problem. '
434  'Please check your AMI account status.')
435  if 'Invalid amiTag' in e.message:
436  raise TransformAMIException(AMIerrorCode, 'Invalid AMI tag ({0}).'.format(tag))
437 
438  msg.debug("Error may not be fatal - will try AMI replica catalog")
439 
440  try:
441  trf = TrfConfig()
442  trf.name = result[0]['transformation']
443  trf.inputs=result[0].get('inputs', {})
444  trf.outputs=result[0].get('outputs', {})
445  trf.release = result[0]['SWReleaseCache'].replace('_', ',')
446 
447  if 'phconfig' in result[0]:
448  trf.physics=deserialiseFromAMIString(result[0]['phconfig'])
449  else:
450  physics = {}
451  for k, v in result[0].items():
452  if 'Exec' in k:
453  execStrList = [execStr for execStr in convertToStr(v).replace('" "', '"" ""').split('" "')]
454  physics[convertToStr(k)] = [remove_enclosing_quotes(execStr).replace('\\"', '"') for execStr in execStrList]
455  elif '" "' in v:
456  msg.info('found a quoted space (" ") in parameter value for %s, converting to list', k)
457  subStrList = [subStr for subStr in convertToStr(v).replace('" "', '"" ""').split('" "')]
458  physics[convertToStr(k)] = [remove_enclosing_quotes(subStr).replace('\\"', '"') for subStr in subStrList]
459  else:
461 
462  msg.debug('Result from AMI after string cleaning:')
463  msg.debug('%s', dumps(physics, indent = 4))
464 
465  if suppressNonJobOptions:
466  for k in list(physics):
467  if k in ['inputs', 'outputs', 'productionStep', 'transformation', 'SWReleaseCache']:
468  physics.pop(k)
469 
470  for k, v in physics.items():
471  if 'triggerConfig' in k or 'triggerConfigByRun' in k:
472  if ' ' in v:
473  physics[k] = v.replace(' ', ',')
474  msg.warning('Attempted to correct illegal trigger configuration string: {0} -> {1}'.format(v, physics[k]))
475 
476  msg.debug("Checking for pseudo-argument internal to ProdSys...")
477  if 'extraParameter' in physics:
478  val = physics.pop('extraParameter')
479  msg.debug("Removed extraParamater=%s from arguments.", val)
480 
481  msg.debug("Checking for input/output file arguments...")
482  for arg in list(physics):
483  if arg.lstrip('-').startswith('input') and arg.endswith('File'):
484  value = physics.pop(arg)
485  msg.debug("Found input file argument %s=%s.", arg, value)
486  trf.inFiles[arg] = value
487  elif arg.lstrip('-').startswith('output') and arg.endswith('File'):
488  value = physics.pop(arg)
489  msg.debug("Found output file argument %s=%s.", arg, value)
490  trf.outFiles[arg] = value
491 
492  msg.debug("Checking for not set arguments...")
493  for arg, value in physics.items():
494  if value == "NONE" or value == "none" or value == ["NONE"]:
495  val = physics.pop(arg)
496  msg.debug("Removed %s=%s from arguments.", arg, val)
497 
498  trf.physics = physics
499 
500  if not isinstance(trf.physics, dict):
501  raise TransformAMIException(AMIerrorCode, "Bad result for tag's phconfig: {0}".format(trf.physics))
502 
503  if trf.inFiles == {}:
504  if 'inputs' in result[0]:
505  trf.inFiles=deserialiseFromAMIString(result[0]['inputs'])
506  for inFileType, inFileName in trf.inFiles.items():
507  # Not all AMI tags actually have a working filename, so fallback to trfDefaultFiles
508  # if necessary
509  if inFileName == '' or inFileName =={} or inFileName == [] or inFileName == '{}':
510  trf.inFiles[inFileType] = getInputFileName(inFileType, tag)
511 
512  if 'outputs' in result[0]:
513  outputs=deserialiseFromAMIString(result[0]['outputs'])
514  trf.outFiles=dict( (k, getOutputFileName(k.removeprefix('output').removesuffix('File')) ) for k in outputs )
515  trf.outfmts=[ outputs[k]['dstype'] for k in outputs ]
516  except KeyError as e:
517  raise TransformAMIException(AMIerrorCode, "Missing key in AMI data: {0}".format(e))
518  except Exception as e:
519  raise TransformAMIException(AMIerrorCode, "Got a very unexpected exception while parsing AMI outputs!"
520  " Please report.\nParsing:\n{0}\nRaised:\n{1}".format(result, e))
521 
522  # Now fix up for command line in the case of a new transform:
523  if '_tf.py' in trf.name:
524  trf.newTransform=True
525  else:
526  trf.newTransform=False
527 
528  return [ trf ]
529 
530 

◆ getTrfConfigFromPANDA()

def python.trfAMI.getTrfConfigFromPANDA (   tag)

Get information about a ProdSys tag from PANDA.

Parameters
tagTag for which information is requested
Returns
list of PyJoCbTransforms.trfAMI.TRFConfig instances

Definition at line 272 of file trfAMI.py.

272 def getTrfConfigFromPANDA(tag):
273 
274  msg.debug('Using PANDA to get info about tag %s', tag)
275 
276  try:
277  pandaclient=getPANDAClient()
278  pandaclient.execute("select trf,trfv,lparams,vparams,formats,cache from t_trf_config where tag='%s' and cid=%d" %(tag[:1],int(tag[1:]) ) )
279  result=pandaclient.fetchone()
280  except Exception:
281  msg.info('An exception occurred: %s', traceback.format_exc())
282  raise TransformAMIException(AMIerrorCode, 'Getting tag info from PANDA failed.')
283 
284  if result is None:
285  raise TransformAMIException(AMIerrorCode, 'Tag %s not found in PANDA database' % tag)
286 
287  msg.debug('Raw data returned from panda DB is:' + os.linesep + str(result))
288 
289  trfn=result[0].split(',')
290  msg.debug('List of transforms: %s', trfn)
291  trfv=result[1].split(',')
292  msg.debug('List of releases: %s', trfv)
293  lparams=result[2].split(';')
294  msg.debug('List of arguments: %s', lparams)
295  vparams=result[3].split(';')
296  msg.debug('List of argument values: %s', vparams)
297  formats=result[4].split('.')
298  msg.debug('List of formats: %s', formats)
299  cache=result[5].split(',')
300  msg.debug('List of caches: %s', formats)
301 
302 
303  if not ( len(trfn) == len(trfv) == len(lparams) == len(vparams) ):
304  raise TransformAMIException(AMIerrorCode, 'Inconsistency in number of trfs.')
305 
306  # Cache can be a single value, in which case it needs replicated for other
307  # transform steps, or it can be multivalued - great schema design guys :-(
308  if len(cache) != len(trfv):
309  if len(cache) == 1:
310  cache = cache * len(trfv)
311  else:
312  raise TransformAMIException(AMIerrorCode, 'Inconsistency in number of caches entries vs. release numbers ({0}; {1}).'.format(cache, trfv))
313 
314  listOfTrfs=[]
315 
316  for iTrf in range(len(trfn)):
317 
318  trf = TrfConfig()
319  trf.name =trfn[iTrf]
320  if '_tf.py' in trf.name:
321  trf.newTransform=True
322  else:
323  trf.newTransform=False
324  trf.release=trfv[iTrf] + "," + cache[iTrf]
325 
326  keys=lparams[iTrf].split(',')
327  values=vparams[iTrf].split(',')
328 
329  if ( len(keys) != len(values) ):
330  raise TransformAMIException(AMIerrorCode, 'Inconsistency in number of arguments.')
331 
332  physics = dict( (k, ReadablePANDA(v) ) for (k,v) in zip(keys, values))
333  # Hack to correct trigger keys being stored with spaces in panda
334  for k, v in physics.items():
335  if 'triggerConfig' in k or 'triggerConfigByRun' in k:
336  if ' ' in v:
337  physics[k] = v.replace(' ', ',')
338  msg.warning('Attempted to correct illegal trigger configuration string: {0} -> {1}'.format(v, physics[k]))
339  if 'Exec' in k:
340  # Mash up to a list, where %8C is used as the quote delimitation character
341  physics[k] = [ execElement.replace("%8C", "") for execElement in v.split("%8C %8C") ]
342 
343  msg.debug("Checking for pseudo-argument internal to ProdSys...")
344  if 'extraParameter' in physics:
345  val=physics.pop('extraParameter')
346  msg.debug("Removed extraParamater=%s from arguments.", val)
347 
348  msg.debug("Checking for input/output file arguments...")
349  for arg in list(physics):
350  if arg.lstrip('-').startswith('input') and arg.endswith('File'):
351  value=physics.pop(arg)
352  msg.debug("Found input file argument %s=%s.", arg, value )
353  trf.inFiles[arg]=value
354  elif arg.lstrip('-').startswith('output') and arg.endswith('File'):
355  value=physics.pop(arg)
356  msg.debug("Found output file argument %s=%s.", arg, value )
357  trf.outFiles[arg]=value
358 
359  msg.debug("Checking for not set arguments...")
360  for arg,value in physics.items():
361  if value=="NONE" or value=="none" or value==["NONE"]:
362  val=physics.pop(arg)
363  msg.debug("Removed %s=%s from arguments.", arg, val )
364 
365  trf.physics=physics
366 
367  listOfTrfs.append(trf)
368 
369 
370 
371  listOfTrfs[0].inDS=None # not yet implemented
372  listOfTrfs[-1].outfmts=formats
373 
374  return listOfTrfs
375 
376 
377 '''
378 directly copied from pyAMI.atlas 5 API
379 should be removed once suppressNonJobOptions is in official release
380 '''

◆ isNewAMITag()

def python.trfAMI.isNewAMITag (   tag)

Definition at line 131 of file trfAMI.py.

131 def isNewAMITag(tag):
132  newTagDict = {
133  'a' : 764,
134  'b' : 545,
135  'c' : 864,
136  'd' : 1351,
137  'e' : 3764,
138  'f' : 557,
139  'g' : 46,
140  'h' : 32,
141  'j' : 46,
142  'k' : 34,
143  'm' : 1377,
144  'o' : 4741,
145  'p' : 2295,
146  'q' : 430,
147  'r' : 6382,
148  's' : 2559,
149  't' : 597,
150  'u' : 51,
151  'v' : 139,
152  'w' : 501,
153  'x' : 302,
154  }
155 
156  if tag[0] in newTagDict:
157  if int(tag[1:]) > newTagDict[tag[0]]:
158  msg.debug('it is a new tag')
159  return True
160 
161  msg.debug('it is NOT a new tag')
162  return False
163 
164 

◆ ReadablePANDA()

def python.trfAMI.ReadablePANDA (   s)

Un-escape information from PANDA.

Provided by Pavel.

Definition at line 265 of file trfAMI.py.

265 def ReadablePANDA(s):
266  return s.replace('%0B',' ').replace('%9B','; ').replace('%8B','"').replace('%3B',';').replace('%2C',',').replace('%2B','+')
267 
268 

◆ remove_enclosing_quotes()

def python.trfAMI.remove_enclosing_quotes (   s)

Definition at line 405 of file trfAMI.py.

406  try:
407  if s[0] == s[-1] and s[0] in ('"', "'"):
408  s = s[1:-1]
409  except Exception:
410  pass
411  return s
412 

Variable Documentation

◆ AMIerrorCode

python.trfAMI.AMIerrorCode

Definition at line 24 of file trfAMI.py.

◆ msg

python.trfAMI.msg

Definition at line 17 of file trfAMI.py.

replace
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition: hcg.cxx:307
vtune_athena.format
format
Definition: vtune_athena.py:14
python.trfAMI._parseExecDict
def _parseExecDict(substep, value)
Back convert a pre/postExec dictionary into a set of command line compatible strings.
Definition: trfAMI.py:117
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
python.trfDefaultFiles.getInputFileName
def getInputFileName(arg, tag=None)
Definition: trfDefaultFiles.py:41
python.trfAMI.getTrfConfigFromPANDA
def getTrfConfigFromPANDA(tag)
Get information about a ProdSys tag from PANDA.
Definition: trfAMI.py:272
python.trfAMI.getAMIClient
def getAMIClient(endpoints=['atlas-replica', 'atlas'])
Get an AMI client.
Definition: trfAMI.py:222
FakeBkgTools::Client
Client
Definition: FakeBkgInternals.h:141
python.trfAMI.getPANDAClient
def getPANDAClient()
Get PANDA client.
Definition: trfAMI.py:248
python.trfAMI.getTrfConfigFromAMI
def getTrfConfigFromAMI(tag, suppressNonJobOptions=True)
Get information about a T0 tag from AMI.
Definition: trfAMI.py:416
python.trfAMI.ReadablePANDA
def ReadablePANDA(s)
Un-escape information from PANDA.
Definition: trfAMI.py:265
python.trfDefaultFiles.getOutputFileName
def getOutputFileName(fmt)
Definition: trfDefaultFiles.py:29
python.trfAMI.get_ami_tag
def get_ami_tag(client, tag, suppressNonJobOptions=True)
Definition: trfAMI.py:381
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
python.trfUtils.convertToStr
def convertToStr(in_string)
Recursively convert unicode to str, useful when we have just loaded something from json (TODO: make t...
Definition: trfUtils.py:636
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
python.trfAMI.getProdSysTagsCharacters
def getProdSysTagsCharacters()
Get list of characters of ProdSys tags.
Definition: trfAMI.py:236
python.trfAMI.remove_enclosing_quotes
def remove_enclosing_quotes(s)
Definition: trfAMI.py:405
TrigJetMonitorAlgorithm.items
items
Definition: TrigJetMonitorAlgorithm.py:79
query_example.cursor
cursor
Definition: query_example.py:21
get
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition: hcg.cxx:127
python.trfAMI._parseIncludeDict
def _parseIncludeDict(substep, value, joinWithChar=",")
Back convert a pre/postInclude dictionary into a set of command line compatible strings By default us...
Definition: trfAMI.py:126
python.trfAMI.deserialiseFromAMIString
def deserialiseFromAMIString(amistring)
Convert from a string to a python object.
Definition: trfAMI.py:534
str
Definition: BTagTrackIpAccessor.cxx:11
python.trfAMI.isNewAMITag
def isNewAMITag(tag)
Definition: trfAMI.py:131
Trk::split
@ split
Definition: LayerMaterialProperties.h:38