ATLAS Offline Software
UploadDQAMITag.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 # Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
4 
5 # 10-Sep-2010, Peter Onyisi <ponyisi@cern.ch>
6 #
7 # Script for uploading a new DQ configuration to AMI "h" tag
8 # ASSUMPTION: the binary DQ configurations have the following
9 # directory structure:
10 # $BASEDIR / cosmics_minutes10.hcfg
11 # / cosmics_minutes30.hcfg
12 # / cosmics_run.hcfg
13 # / collisions_*.hcfg
14 # / heavyions_*.hcfg
15 
16 from __future__ import print_function
17 
18 import os
19 
20 AMI_TAG_PREFIX='h'
21 
22 def get_current_config(amiclient):
23 
24  #amicommand = ['ListElement', '-entity=h_config', '-processingStep=Atlas_Production', '-project=Atlas_Production', '-select=tag']
25  amicommand = ['SearchQuery', '''-sql="SELECT V_AMITags.tagType, V_AMITags.tagNumber FROM V_AMITags WHERE V_AMITags.tagType = 'h' ORDER BY V_AMITags.tagNumber DESC"'''
26  '-project="AMITags"', '-processingStep=production']
27 
28  print (amicommand)
29 
30  result = amiclient.execute(amicommand, format='dict_object')
31  resultlist = result.get_rows('Element_Info')
32  latestTag = 'h' + resultlist[0]['tagNumber']
33  #try:
34  # latestTag = 'h' + `max(int(_['tag'][1:]) for _ in resultlist)`
35  #except:
36  # latestTag = 'h0'
37 
38  nextTag = latestTag[0] + str(int(latestTag[1:])+1)
39 
40  print ('Latest AMI tag is', latestTag)
41  print ('Will create AMI tag', nextTag)
42  #latestTag='h7'
43 
44  amicommand = ['AMIGetAMITagInfo', '-amiTag='+latestTag]
45 
46  result = amiclient.execute(amicommand, format='dict_object')
47  print ('----------')
48  #print (result)
49  #print (result.get_rowset_types())
50  #print (result.get_rows('amiTagInfo'))
51  rv = result.get_rows('amiTagInfo')[0]
52 
53  print ()
54  print ('-------------------------------------')
55  print ('Info of current AMI tag ...')
56  for key, val in rv.items():
57  print (' %s:' % key, val)
58  rv1 = {}
59  for k, v in rv.items():
60  rv1[k] = v.__str__()
61 
62  #del rv1['readStatus']
63  #del rv1['writeStatus']
64  for k in ('tag', 'createdBy', 'modifiedBy', 'tagStatus', 'tagNumber', 'tagType',
65  'locked', 'updates', 'created', 'lastModified', 'processingStep',
66  'transformationName', 'baseRelease', 'modified', 'phconfig'):
67  try:
68  del rv1[k]
69  except KeyError:
70  pass
71  for k in ('inputs','outputs', 'moreInfo', 'trfsetupcmd',
72  'description'):
73  rv1[k] = '"%s"' % str(rv1[k].__str__())
74 
75  #rv1['phconfig'] = str(rv1['phconfig'].__str__())
76  return rv1, latestTag
77 
78 def get_next_tag(latestTag):
79  nextTag = latestTag[0] + str(int(latestTag[1:])+1)
80  #nextTag='h8'
81  return nextTag
82 
83 #if reading from afs, use the old system, looking for the most current hcfg files and setting the symlink as phconfig
84 def update_dict_for_configs_afs(updict, indir):
85 
86  basedir = os.path.abspath(indir)
87 
88  print ('Looking for configurations in subdirectories of', indir)
89 
90  types = ['minutes10', 'minutes30', 'run']
91  searchparams = [('Cosmics', 'cosmics'), ('Collisions', 'collisions'),
92  ('HeavyIons', 'heavyions')]
93 
94  filepathdict = {}
95  filelist = []
96 
97  for dir1, fn in searchparams:
98  print (dir1)
99  filepathdict[dir1] = {}
100  for t in types:
101  print (' ', t, '...',)
102  fname = os.path.join(basedir, dir1,
103  '%s_%s.current.hcfg' % (fn, t))
104  if os.access(fname, os.R_OK):
105  print ('found,',)
106  if os.path.islink(fname) and os.path.isfile(fname):
107  realname = os.readlink(fname)
108  if not os.path.isabs(realname):
109  realname = os.path.join(os.path.dirname(fname), realname)
110  print ('is symlink to', realname)
111  filepathdict[dir1][t] = realname
112  filelist.append(realname)
113  else:
114  print ('but is not valid symlink')
115  else:
116  print ('not found')
117  if filepathdict[dir1] == {}:
118  del filepathdict[dir1]
119 
120  commonpart = os.path.dirname(os.path.commonprefix(filelist)) + os.sep
121 
122  filepathdict['basename'] = commonpart
123 
124  # clean up common part
125  for dir1, fn in searchparams:
126  for t in types:
127  try:
128  filepathdict[dir1][t] = filepathdict[dir1][t].replace(commonpart, '')
129  except KeyError:
130  pass
131 
132  print ()
133  print ('-------------------------------------')
134  print ('File path dictionary to upload:')
135  print (filepathdict)
136  print ('-------------------------------------')
137  print ()
138 
139  val = updict.get('phconfig', {})
140  if isinstance(val, str):
141  val = {}
142  val['filepaths'] = filepathdict
143  updict['phconfig'] = '"%s"' % val
144 
145 #if reading hcfgs from a cvmfs directory, only one set of files should be present. Use those for phconfig
146 def update_dict_for_configs_cvmfs(updict, indir):
147 
148  basedir = os.path.abspath(indir)
149 
150  print ('Looking for configurations in subdirectories of', indir)
151 
152  types = ['minutes10', 'run']
153  searchparams = [('Cosmics', 'cosmics'), ('Collisions', 'collisions'),
154  ('HeavyIons', 'heavyions')]
155 
156  filepathdict = {}
157  filelist = []
158 
159  for dir1, fn in searchparams:
160  print (dir1)
161  filepathdict[dir1] = {}
162  for t in types:
163  print (' ', t, '...',)
164  fname = os.path.join(basedir, '%s_%s.hcfg' % (fn, t))
165  if os.access(fname, os.R_OK):
166  print ('found %s' % (dir1))
167  if os.path.isfile(fname):
168  filepathdict[dir1][t] = fname
169  filelist.append(fname)
170  else:
171  print ('not found')
172  if filepathdict[dir1] == {}:
173  del filepathdict[dir1]
174 
175  commonpart = os.path.dirname(os.path.commonprefix(filelist)) + os.sep
176 
177  filepathdict['basename'] = commonpart
178 
179  # clean up common part
180  for dir1, fn in searchparams:
181  for t in types:
182  try:
183  filepathdict[dir1][t] = filepathdict[dir1][t].replace(commonpart, '')
184  except KeyError:
185  pass
186 
187  print ()
188  print ('-------------------------------------')
189  print ('File path dictionary to upload:')
190  print (filepathdict)
191  print ('-------------------------------------')
192  print ()
193 
194  val = updict.get('phconfig', {})
195  if isinstance(val, str):
196  val = {}
197  val['filepaths'] = filepathdict
198  updict['phconfig'] = '"%s"' % val
199 
200 def update_dict_for_release(updict, release):
201  # From UpdateAMITag.py
202  #Check if release exists
203  relSp=release.split("-")
204  if len(relSp)!=2:
205  s="ERROR: Expected parameter 'release' in the form Project-number, got "+release
206  raise RuntimeError(s)
207  relProj=relSp[0]
208  if ',' in relSp[1]:
209  relNbr, _=relSp[1].split(',', 1)
210  else:
211  relNbr, _=relSp[1], None
212 
213  baseRelNbr=".".join(relNbr.split(".")[:2])
214  relPath = "/cvmfs/atlas.cern.ch/repo/sw/software/%s/%s/%s" % (baseRelNbr, relProj, relNbr)
215  if not os.path.isdir(relPath):
216  s="ERROR Release directory " + relPath + " does not exist"
217  raise RuntimeError(s)
218  #Release exists if we reach this point
219 
220  extraSetup = " oracleCOOL"
221  if relProj == "AtlasProduction":
222  extraSetup += " AtlasProduction"
223  elif relProj == "Athena":
224  extraSetup += " Athena"
225  elif relProj == "AthDataQuality":
226  extraSetup += " AthDataQuality"
227  elif relProj != "AtlasOffline":
228  s="ERROR: The project specified (" + relProj +") is not Athena, AtlasOffline or AtlasProduction. Are you sure?"
229  raise RuntimeError(s)
230 
231  # update dictionary
232  tasktransinfo = {'trfpath': 'DQM_Tier0Wrapper_tf.py',
233  'trfsetupcmd': "/afs/cern.ch/atlas/tzero/software/setup/usetuptrf.sh " + relNbr + extraSetup}
234  updict['moreInfo'] = '"{\'tasktransinfo\': %s}"' % tasktransinfo.__str__()
235  updict['SWReleaseCache'] = release.replace('-', '_')
236  updict['groupName'] = relProj
237  updict['cacheName'] = relSp[1]
238  updict['description'] = "'Trf for combined DQM histogram merging and DQM webpage creation, to get periodic DQ monitoring updates. Using " + release +"'"
239  updict['trfsetupcmd'] = '"%s"' % tasktransinfo['trfsetupcmd']
240  #updict['tagNumber'] = nextTag[1:]
241  #del updict['trfsetupcmd']
242 
243 def upload_new_config(amiclient, nextTag, updict):
244 
245  amicommand = ['AddAMITag', 'tagType="h"', ]
246 
247  for key, val in updict.items():
248  amicommand.append('%s=%s' % (key, val))
249 
250  print ('-------------------------------------')
251  print ()
252  print ('Now uploading new AMI tag')
253  print ('AMI command:', amicommand)
254 
255  result = amiclient.execute(amicommand)
256  print (result)
257  print ()
258  print ('Success!')
259 
260 if __name__ == '__main__':
261  import optparse
262 
263  parser = optparse.OptionParser(usage='Usage: %prog [options] cmd arg\n'
264  ' cmd can be:\n'
265  ' configs: update only DQ configurations; args should be the config base directory\n'
266  ' release: update only the release; args should be the new release'
267  )
268 
269  parser.set_defaults(certificate=False)
270  parser.add_option('-u', '--user', dest='amiuser', help='Set AMI user; should set password at the same time.')
271  parser.add_option('-p', '--password', dest='amipass', help='Set AMI password; should set user at the same time.')
272  parser.add_option('-c', '--certificate', dest='certificate',
273  action='store_true',
274  help='Use grid certificate/VOMS proxy.')
275 
276  options, args = parser.parse_args()
277 
278  if len(args) < 2:
279  parser.error('Must provide type of operation and argument!')
280 
281  if args[0].lower() not in ('configs', 'release'):
282  parser.error('cmd must be "configs" or "release"')
283 
284 
285  #Get pyAMI client
286 # try:
287 # from pyAMI.client import Client
288 # except ImportError:
289 # print ("WARNING unable to import AMI from pyAMI with standard $PYTHONPATH.")
290 # print ("Will manually add ZSI and 4suite, then try again...")
291 # import sys
292 # sys.path.insert(0,'/afs/cern.ch/atlas/offline/external/ZSI/2.1-a1/lib/python')
293 # sys.path.insert(0,'/afs/cern.ch/sw/lcg/external/4suite/1.0.2_python2.5/slc4_ia32_gcc34/lib/python2.5/site-packages')
294 # from pyAMI.client import Client
295 #
296 # amiclient=Client('atlas', ignore_proxy = not options.certificate)
297 # if options.amiuser is not None and options.amipass is not None:
298 # amiclient.auth(options.amiuser, options.amipass)
299 
300  import pyAMI.client
301  import pyAMI.atlas.api as AtlasAPI
302  amiclient = pyAMI.client.Client('atlas')
303  AtlasAPI.init()
304 
305  cfgdict, latestTag = get_current_config(amiclient)
306  nextTag = get_next_tag(latestTag)
307 
308  if args[0].lower() == 'configs':
309  if '/afs/cern.ch/user/a/atlasdqm/' in str(args[1]):
310  update_dict_for_configs_afs(cfgdict, args[1])
311  elif 'cvmfs' in str(args[1]):
312  update_dict_for_configs_cvmfs(cfgdict, args[1])
313  else:
314  s="Invalid directory given. hcfg files should exist in cvmfs or the atlasdqm afs space"
315  raise RuntimeError(s)
316  elif args[0].lower() == 'release':
317  update_dict_for_release(cfgdict, args[1])
318 
319  upload_new_config(amiclient, nextTag, cfgdict)
replace
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition: hcg.cxx:307
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
UploadDQAMITag.update_dict_for_release
def update_dict_for_release(updict, release)
Definition: UploadDQAMITag.py:200
UploadDQAMITag.update_dict_for_configs_afs
def update_dict_for_configs_afs(updict, indir)
Definition: UploadDQAMITag.py:84
UploadDQAMITag.upload_new_config
def upload_new_config(amiclient, nextTag, updict)
Definition: UploadDQAMITag.py:243
UploadDQAMITag.update_dict_for_configs_cvmfs
def update_dict_for_configs_cvmfs(updict, indir)
Definition: UploadDQAMITag.py:146
UploadDQAMITag.get_current_config
def get_current_config(amiclient)
Definition: UploadDQAMITag.py:22
UploadDQAMITag.get_next_tag
def get_next_tag(latestTag)
Definition: UploadDQAMITag.py:78
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
str
Definition: BTagTrackIpAccessor.cxx:11
Trk::split
@ split
Definition: LayerMaterialProperties.h:38