ATLAS Offline Software
AtlRunQueryParser.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 # Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
4 #
5 # ----------------------------------------------------------------
6 # Script : AtlRunQueryParser.py
7 # Project: AtlRunQuery
8 # Purpose: Utility to translate a parser language (to be used in
9 # a web browser) into AtlRunQuery arguments
10 # Authors: Andreas Hoecker (CERN), Joerg Stelzer (DESY)
11 # Created: Nov 13, 2008
12 # ----------------------------------------------------------------
13 #
14 from __future__ import print_function
15 from functools import reduce
16 import sys,re
17 
18 from CoolRunQuery.utils.AtlRunQueryLookup import InitDetectorMaskDecoder, DecodeDetectorMask, DQChannels
19 
20 from DQDefects import DefectsDB
21 
23  dqFolderList = [ 'SHIFTOFL', 'DQCALCOFL', 'DQMFOFL', 'DQMFOFLH', 'DCSOFL', 'TISUMM', 'LBSUMM', 'MUONCALIB',
24  'DQMFONL', 'DQMFONLLB', 'SHIFTONL' ] # these are online folders
25 
26  def __init__ ( self ):
27  self.const_arg = ""
28  self.default_find = ""
29  self.isMCDB = False
30  self.default_show = ["run","events","time"]
31 
32  # allowed 'query' arguments
33  # tuple format: ( "short name", "long-name", "interpret function", "show function", "example", "default value" )
34  self.sortedKeys = [ "run", "time", "duration", "events", "allevents", "projectTag", "partition", "readyforphysics",
35  "trigkeys", "trigger", "release",
36  "ami", "magnets", "larcond", "db", "ctag", "lhc", "lumi", "dq",
37  "streams", "detector", "datasets", "all", "summary", "dqeff", "cosmics", "heavyions" ]
38 
39  self.queryArgs = { "run": ("r(uns)", "run", self.InterpretPeriods, self.ShowVariable,
40  'r(uns) [format: "run 91000", "runs 91000-92000", "runs 91000-(+)" (this run and all before (after))]', ""),
41  "all": ("all", "all", self.InterpretString, self.ShowVariable,
42  'all [format: only available as "show" option]', ""),
43  "summary": ("summary", "summary", self.InterpretString, self.ShowVariable,
44  'summary [format: only available as "show" option]', ""),
45  "dqsummary": ("dqsum(mary)", "dqsummary", self.InterpretString, self.ShowVariable,
46  'dqsum(mary) [format: only available as "show" option]', ""),
47  "dqplots": ("dqpl(ots)", "dqplots", self.InterpretString, self.ShowVariable,
48  'dqpl(ots) [format: only available as "show" option]', ""),
49  "dqeff": ("dqeff", "dqeff", self.InterpretString, self.ShowVariable,
50  'dqeff [format: only available as "show" option]', ""),
51  "events": ("ev(ents)", "events", self.InterpretRange, self.ShowVariable,
52  'ev(ents) [format: "events 10000+", ... (same as for run number)]', ""),
53  "allevents": ("alle(vents)", "allevents", self.InterpretRange, self.ShowVariable,
54  'alle(vents) [format: only available as "show" option]', ""),
55  "time": ("t(ime)", "time", self.InterpretRange, self.ShowVariable,
56  't(ime) [format: "time 10.9.2008-30.9.2008", "time 15.10.2008-(+)" (this date and all before (after))]', ""),
57  "duration": ("dur(ation)", "duration", self.InterpretDuration, self.ShowVariable,
58  'dur(ation) [format: "dur 10d/h/m/s+/-", "2000s+" (run duration more than 2000 sec), "dur 3h-" (less than 3 hours)]', ""),
59  "magnets": ("m(agnet)", "bfield", self.InterpretMagnets, self.ShowVariable,
60  'm(agnet) [format: "magnet s(olenoid)", "magnet t(oroid)", "not magnet t(oroid)", ...]', ""),
61  "detector": ("det(ector)", "detmask", self.InterpretDetectorMask, self.ShowVariable,
62  'det(ector) [format: "detector Pixel B" (for Pixel Barrel), "detector Pixel" (for Pixel B & EC), "all" (for all detectors, detector mask = 72551459979255)', ""),
63  "smk": ("smk", "smk", self.InterpretRange, self.ShowVariable,
64  'smk [format: "smk 398", "smk 398,399 (super-master-key labelling trigger menu, format like for run ranges)]', ""),
65  "trigkeys": ("trigk(eys)", "trigkeys", self.InterpretRange, self.ShowVariable,
66  'trigk(eys) [format: "tkeys" (show all trigger keys of run: SMK, L1 and HLT prescale keys)]', ""),
67  "release": ("rel(ease)", "release", self.InterpretString, self.ShowWithArg,
68  'rel(ease) [format: "release 15.1.*" ',""),
69  "projectTag": ("ptag", "projecttag",self.InterpretString, self.ShowVariable,
70  'ptag [format: "ptag data08_cos,data08_cosmag,data09_cos", "ptag data08_cos*,data09_cos" (note: the projectTag in dataset name / denoted "filenamtTag" in COOL)]',"data0*,data1*,data2*"),
71  "partition": ("p(artition)", "partition", self.InterpretString, self.ShowVariable,
72  'p(artition) [format: "partition ATLAS"]', "ATLAS"),
73  "readyforphysics": ("ready(forphysics)", "readyforphysics", self.InterpretString, self.ShowVariable,
74  'ready(forphysics) [format: "readyforphysics T(rue)"]', ""),
75  "db": ("db", "db", self.InterpretString, self.ShowVariable,
76  'db [format: "db <DB>, where <DB> is either DATA, MC, COMP200, CONDBR2, or OFLP200',""),
77  "ctag": ("ctag", "ctag", self.InterpretString, self.ShowVariable,
78  'ctag [format: "ctag COMCOND-HLTC-001-00" ',""),
79  "streams": ("st(reams)", "streams", self.InterpretStreams, self.ShowWithArg,
80  'st(reams) [format: "stream RPCwBeam,TGCwBeam", "stream physics*" ',""),
81  "dq": ("dq", "dq", self.InterpretDQ, self.ShowDQ,
82  'dq [format: "dq <FLAG> <status>", where the data quality status is "g(reen)", "y(ellow)", "r(ed)", "u(known)", example: dq PIXB y+ (means yellow or green status)]', ""),
83  "trigger": ("tr(igger)", "trigger", self.InterpretString, self.ShowWithArg,
84  'tr(igger) [format: "trigger *Electron*" ',""),
85  "lumi": ("lu(minosity)","luminosity", self.InterpretWithTwoArgs, self.ShowWithArg,
86  'lu(minosity) [format: "lumi FOLDER", default: LBLESTOFL]" ',""),
87  "olc": ("olc", "olc", self.InterpretWithTwoArgs, self.ShowWithArg,
88  'olc [format: "olc" (OLC = Online Luminosity Calculator)]" ',""),
89  "bs": ("bs", "beamspot", self.InterpretString, self.ShowWithArg,
90  'bs [format: "bs"]" ',""),
91  "bpm": ("bpm", "bpm", self.InterpretString, self.ShowVariable,
92  'bpm [format: "show bpm"]" ',""),
93  "datasets": ("da(tasets)", "datasets", self.InterpretString, self.ShowWithArg,
94  'da(tasets) [format: show datasets *NTUP*"]" ',""),
95  "ami": ("ami", "ami", self.InterpretString, self.ShowVariable,
96  'ami [format: show ami"]" ',""),
97  "larcond": ("lar(cond)", "larcond", self.InterpretWithTwoArgs, self.ShowVariable,
98  'lar(cond) [format: larcond nsamples 7 / show larcond"]" ',""),
99  "lhc": ("lhc", "lhc", self.InterpretWithTwoArgs, self.ShowVariable,
100  'lhc [format: lhc fill 7 / show lhc"]" ',""),
101  "trigrates": ("trigr(ates)", "trigrates", self.InterpretString, self.ShowWithArg,
102  'trigr(ates) [format: sh trigrates L1_EM*"]" ',""),
103  "dqsumgrl": ("dqsumgrl", "dqsumgrl", self.InterpretString, self.ShowVariable,
104  'dqsumgrl [format: "dqsumgrl PHYS_StandardGRL_All_Good_25ns", Define tolerable/intolerable defects for DQ summary relative to GRL or other virtual defect, default is PHYS_StandardGRL_All_Good_25ns]', "PHYS_StandardGRL_All_Good_25ns"),
105  "cosmics": ("cos(mics)", "cosmics", self.InterpretString, self.ShowVariable,
106  'cos(mics) [format: only available as "show" option]', ""),
107  "heavyions": ("heavy(ions)", "heavyions", self.InterpretString, self.ShowVariable,
108  'heavy(ions) [format: only available as "show" option]', ""),
109  "logictag": ("logictag", "logictag", self.InterpretString, self.ShowVariable,
110  'logictag [format: "logictag "HEAD", Define logic tag for defect database used for DQ summary relative to GRL or other virtual defect, default is "HEAD"]', "HEAD"),
111  "defecttag": ("defecttag", "defecttag", self.InterpretString, self.ShowVariable,
112  'defecttag [format: "defecttag "HEAD", Define defect tag for defect database used for DQ summary relative to GRL or other virtual defect, default is "HEAD"]', "HEAD") }
113  # allowed 'show' arguments
114 
115  # init detector mask
116  (self.dName, self.NotInAll, self.vetoedbits) = InitDetectorMaskDecoder(lhcRun=3) # needs to be fixed (made run-dependent) - move into Det Selector
117 
118  def ParserUsage( self ):
119  print (' ')
120  print ('Parser usage: python %s <string_argument>' % sys.argv[0])
121  print (' ')
122  print ('A query starts with the keyword "f(ind)", several queries can be combined with "and", "(and) not"')
123  print ('The requested response information is given through the keyword "sh(ow)" (the query must be terminated by a "/")')
124  print (' ')
125  print ('Query words:')
126  for key in self.queryArgs:
127  print (" %s " % self.queryArgs[key][4])
128  print (' ' )
129  print ('Parts of a keyword written in paranthesis are optional')
130  print (' ' )
131  print ('Examples: ')
132  print (' ' )
133  print (' find run 90272 and runs 90275-91900 and magnet toroid and magnet solenoid / show run and events')
134  print (' f r 90272 and r 90275-91900 and m t and m s / sh r and ev [same as above in short-hand version]')
135  print (' find runs 90275-91900 and not run 90280 and not dq EMEC r and show run and dq EMEC' )
136  print (' ')
137 
138  def replaceNumbers( self, n ):
139  return n.replace('k','000').replace('m','000000')
140 
141  def getPtagAndPeriod( self, name ):
142  ptag = 'data11_7TeV'
143  if '.' in name:
144  ptag, period = name.split('.')
145  else:
146  period = name
147  letter = period[period.find('period')+6:][0]
148  return ptag.strip(), period.strip(), letter
149 
150  def InterpretPeriods( self, atlqarg, arg, neg ):
151  """
152  atlqarg: 'run'
153  arg: 'run data10_7TeV.periodA' or 'run periodA' (where 'data11_7TeV' is assumed)
154  # or 'data10_7TeV.periodA-periodC' or 'data10_7TeV.periodA,data10_7TeV.periodB,...'
155  # This is case sensitive !!
156  """
157  arg = arg.split(None,1)[1] # remove keyword 'run'
158 
159  from CoolRunQuery.AtlRunQueryInterpretDataPeriods import GetRuns
160 
161  list_of_runs = GetRuns(arg)
162 
163  if len(list_of_runs)==0:
164  print ("No runs matching pattern")
165  sys.exit(0)
166 
167  return "--run " + ','.join([str(r) for r in list_of_runs])
168 
169 
170 
171  def InterpretRange( self, atlqarg, arg, neg ):
172  # special possibility to give run ranges
173  rge = self.replaceNumbers(arg.split(None,1)[1])
174  rge = rge.replace('last ','l ').replace('las ','l ').replace('la ','l ').replace('l ','last ')
175  return "--" + atlqarg.strip() + ' "' + rge.strip().replace(' ','') + '"'
176 
177  # range interpretation utilities
178  def InterpretRangeNew( self, atlqarg, arg, neg ):
179  # special possibility to give run ranges
180  rge = self.replaceNumbers(arg.split(None,1)[1])
181  rge = rge.replace('last ','l ').replace('las ','l ').replace('la ','l ').replace('l ','last ')
182  return "--" + atlqarg.strip() + ' "' + rge.strip().replace(' ','') + '"'
183 
184  def InterpretString( self, atlqarg, arg, neg ):
185  # '%' is translated into '*' wildcard
186  arg = arg.partition(' ')[2]
187  arg = arg.replace('%','*')
188  arg = arg.strip().replace(' ','')
189 
190  atlqarg = atlqarg.strip()
191  if atlqarg=='db' and (arg=='MC' or arg=='OFLP'):
192  self.isMCDB = True
193 
194  # default for ReadyForPhysics flag
195  if atlqarg == 'readyforphysics' and not arg:
196  arg = '1'
197 
198  # default for DQSumGRL flag
199  if atlqarg == 'dqsumgrl' and not arg:
200  arg = 'PHYS_StandardGRL_All_Good_25ns'
201 
202  # default for dbbtag flag
203  if atlqarg == 'logictag' and not arg:
204  arg = 'HEAD'
205  if atlqarg == 'defecttag' and not arg:
206  arg = 'HEAD'
207 
208  return '--%s "%s"' % (atlqarg, arg)
209 
210  def InterpretWithTwoArgs( self, atlqarg, arg, neg ):
211  # '%' is translated into '*' wildcard
212  cmd,sep,arg = arg.partition(' ')
213  arg = arg.replace('%','*')
214  arg = arg.strip()
215 
216  # special case for olc lumi
217  if cmd.lower() == 'olc' and 'lumi' in arg.lower():
218  atlqarg = 'olclumi'
219  a = arg.split()
220  if len(a) == 2:
221  arg = a[1].strip()
222  else:
223  print ('ERROR in argument of command "olc lumi": no argument given' )
224  sys.exit()
225 
226  # make equal to 'lumi' (for backward compatibility)
227  if cmd.lower() == 'lumi':
228  atlqarg = 'olclumi'
229  if not arg:
230  print ('ERROR in argument of command "olc lumi": no argument given' )
231  sys.exit()
232 
233  # special case for 'lhc'
234  if cmd.lower() == 'lhc':
235  if 'stablebeams' in arg.lower():
236  arg,sep,val = arg.partition(' ')
237  val = val.strip().upper()
238  if val == '1' or val == 'T':
239  val = 'TRUE'
240  elif val == '0' or val == 'F':
241  val = 'FALSE'
242  elif val != 'TRUE' and val != 'FALSE':
243  print ('ERROR in argument of command "lhc": "%s". Value must be boolean (true/false or 1/0)' % val)
244  sys.exit()
245  arg += ' ' + val
246 
247  atlqarg = atlqarg.strip()
248  if atlqarg=='db' and (arg=='MC' or arg=='OFLP'):
249  self.isMCDB = True
250 
251  return '--%s "%s"' % (atlqarg, arg)
252 
253  def InterpretStreams( self, atlqarg, arg, neg ):
254  # '%' is translated into '*' wildcard
255  arg = arg.split()[1:]
256  retstr = "--" + atlqarg.strip() + ' "' + arg[0].replace('%','*')
257  if len(arg)>1:
258  return retstr + " " + self.replaceNumbers(arg[1]) + '"'
259  else:
260  return retstr + '"'
261 
262  def InterpretDuration( self, atlqarg, arg, neg ):
263  # sanity check
264  key, sep, arg = arg.partition(' ')
265  units = {'sec': 1, 's': 1, 'm': 60, 'h': 3600, 'd': 86400 }
266  found = False
267  for u, fac in units.items():
268  if u in arg:
269  arg = arg.replace(u,'')
270  if '-' in arg:
271  sign = '-'
272  else:
273  sign = '+'
274  arg = "%i%s" % (int(arg.replace(sign,'').strip())*fac,sign)
275  found = True
276  if not found:
277  self.ParseError( "Unit missing in duration tag: '%s' - should be 's', 'm', 'h', or 'd'" % arg )
278 
279  return self.InterpretRange( atlqarg, key + ' ' + arg, neg )
280 
281  def InterpretMagnets( self, atlqarg, arg, neg ):
282  key, s, arg = arg.partition(' ')
283 
284  # if 'arg' is empty, intepret directly
285  if arg.strip() == '':
286  self.ParseError( 'Keyword "mag(net)" requires argument' )
287 
288  # check if 'not' given
289  arg = arg.strip()[0]
290 
291  # now interpret
292  if arg == "":
293  newarg = "off"
294  else:
295  if arg == 's':
296  newarg = "solenoid"
297  elif arg == 't':
298  newarg = "toroid"
299  else:
300  self.ParseError( "cannot interpret of magnetic field: '%s'" % arg )
301  if neg:
302  newarg += "off"
303  else:
304  newarg += "on"
305 
306  return "--" + atlqarg.strip() + ' "' + newarg.strip().replace(' ','') + '"'
307 
308  @classmethod
309  def DQGetFolder( cls, args, allowWildCards=False ):
310 
311  #Get logictag and defecttag from sys.argv <--not nice but see no better way
312  arglist = sys.argv[1].split(" ")
313  logictag = "HEAD"
314  defecttag = "HEAD"
315  for idx, item in enumerate(arglist):
316  if item == "logictag":
317  logictag = arglist[idx+1]
318  if item == "defecttag":
319  defecttag = arglist[idx+1]
320  #Create dbb dummy with HEAD tag
321  ddb = DefectsDB()
322  #check if defect tag is defined in defect database
323  if defecttag not in ['HEAD'] + ddb.defects_tags:
324  print('WARNING (DQGetFolder): The defined defect tag "%s" is not defined in defect database. Will use "HEAD" tag instead!' %(defecttag))
325  defecttag = "HEAD"
326  #check if defect and logic tag is defined in defect database
327  if logictag not in ['HEAD'] + ddb.logics_tags:
328  print('WARNING (DQGetFolder): The defined logic tag "%s" is not defined in defect database. Will use "HEAD" tag instead!' %(logictag))
329  logictag = "HEAD"
330  #Now set tags
331  ddb = DefectsDB(tag=(defecttag, logictag))
332  #Create hierarchical tag
333  htag = ""
334  if logictag != "HEAD" and defecttag != "HEAD":
335  logic_revision = int(logictag.split("-")[-1])
336  defect_part = "-".join(defecttag.split("-")[1:])
337  htag = "DetStatus-v%02i-%s" % (logic_revision, defect_part)
338  #htag = ddb.new_hierarchical_tag(defecttag, logictag)
339 
340  """interpret dq show command
341  * args are all arguments after dq codeword
342 
343  possible formats for 'dq args':
344  1) dq
345  2) dq D
346  3) dq F
347  4) dq F#
348  5) dq D F
349  6) dq #T
350  7) dq D #T
351  8) dq F#T
352  9) dq D F#T
353 
354  where
355  D is a komma-separated list of defects or DQ-flags or *, each optionally proceeded by a ! or followed by a (defect,defect,defect,...)
356  F an folder name [default DEFECTS]
357  T a cool tag [default HEAD]
358 
359  If no folder is specified the new defects folder is used
360  """
361 
362  d = { 'flag': '', 'folder': '', 'tag': ''}
363  if '#' in args:
364  if allowWildCards:
365  m = re.match(r'(?P<flag>[!.*\w,\-\$\\\]*?)\s*?(?P<folder>\w*)#(?P<tag>[\w-]*)', args)
366  else:
367  m = re.match(r'(?P<flag>[!\w,\-\$\\\]*?)\s*?(?P<folder>\w*)#(?P<tag>[\w-]*)', args)
368  else:
369  m = re.match(r'(?P<flag>[!\w,\-\$\\\]*)\s*(?P<folder>[\w-]*)', args)
370 
371  if m:
372  d.update(m.groupdict())
373 
374  flag = d['flag'].lower()
375  folder = d['folder'].upper()
376  tag = d['tag']
377 
378  if flag.upper() in cls.dqFolderList:
379  folder = flag.upper()
380  flag = ''
381 
382  if folder == '':
383  folder = 'DEFECTS'
384  if flag == '':
385  flag = '*'
386 
387  #Overwrite tag if htag defined
388  if htag != '':
389  tag = htag
390  if tag != '':
391  tag = '#' + tag
392  folder = folder + tag
393 
394  return flag, folder, tag
395 
396 
397  def ShowDQ( self, atlqarg, short, arg ):
398 
399  # check if 'arg' has additional arguments (eg, dq PIXB, ...)
400  args = arg.partition(' ')[2]
401 
402  # check/insert COOL folder
403  flags, folder, tag = self.DQGetFolder( args, allowWildCards = True )
404 
405  newarg = ""
406 
407  if folder.startswith('DEFECTS'):
408  # defects DB
409  if flags == "*": # no additional arguments given --> show all flags
410  return '--show "dq DEFECTS%s" ' % tag
411  else:
412  # assume some defects are given, split by ","
413  return ' '.join(['--show "dq %s DEFECTS%s"' % (fl.upper(), tag) for fl in flags.split(',')])
414 
415  # replace 'lar' by appropriate choices
416  flags = flags.replace( 'lar','emba,embc,emeca,emecc,heca,hecc,fcala,fcalc' )
417 
418  # replace 'tile' by appropriate choices
419  flags = flags.replace( 'tile','tigb,tilba,tilbc,tieba,tiebc' )
420 
421  # replace 'trig' by appropriate choices
422  flags = flags.replace( 'trig','l1cal,l1mub,l1mue,l1ctp,trcal,trbjt,trbph,trcos,trele,trgam,trjet,trmet,trmbi,trmuo,trtau,tridt' )
423 
424  dqitems = DQChannels()
425  if flags == "*": # no additional arguments given --> show all flags
426  # query over all DQ channels and add to show
427  for key, dqchan in dqitems:
428  newarg += '--show "dq %s %s" ' % (dqchan, folder)
429  else:
430  # assume some DQ channels are given, split by "," or " "
431  argList = flags.split(',')
432  for a in argList:
433  a = a.strip().lower()
434  if self.isVirtualFlag(a):
435  newarg += '--show "dq %s %s" ' % (a.upper(), folder)
436  else:
437  for key, dqchan in dqitems:
438  dc = dqchan.lower()
439  if a[0:3]==('trg'): # all trigger dq (tr but not trt)
440  if dc[0:2]=="tr" and dc[2]!='t':
441  newarg += '--show "dq %s %s" ' % (dqchan, folder)
442  else:
443  if a in dc:
444  newarg += '--show "dq %s %s" ' % (dqchan, folder)
445 
446  return newarg
447 
448 
449 
450  def InterpretDQ( self, atlqarg, args, neg ):
451  # the following formats for dq need to work
452  # dq [any] sys1[,sys2] value[+|-] // note: a system must be given, if you want all the specify '*' e.g. 'dq * g'
453 
454  # split, and remove first word ('dq'), be reminded that a split automatically removes _all_ whitespaces
455  args = args.split()[1:]
456 
457  hasColor = len(args)>0 and re.match('(n.a.|u|r|y|g|b)[+-]{0,1}$',args[-1].lower())
458  if hasColor:
459  # last argument must be dq value
460  dqflagVal = args[-1]
461  args = args[:-1]
462  else:
463  dqflagVal = 'x'
464 
465 
466  # check for the 'any' identifier (any --> OR, otherwise AND)
467  useAny = len(args)>0 and (args[0] == 'any')
468  if useAny:
469  args = args[1:]
470 
471  # get the cool folders
472  flags, folder, tag = self.DQGetFolder( ' '.join(args) )
473 
474  newarg = ""
475 
476  if folder.startswith('DEFECTS'):
477  if flags == "*":
478  newarg = "--dq !ANY " + folder
479  else:
480  # assume some DQ channels are given, split by "," or " "
481  dqchans = flags.upper().split(',')
482  if useAny:
483  newarg += self.InterpretSingleDQ( atlqarg, (','.join(dqchans), dqflagVal, folder) ) + ' '
484  else:
485  for dqchan in dqchans:
486  newarg += self.InterpretSingleDQ( atlqarg, (dqchan, dqflagVal, folder) ) + ' '
487 
488  else:
489  if not hasColor:
490  self.ParseError( 'DQ flags need to be assigned a value ("n.a.", "u", "g", "y", "r"), eg, "dq PIXB,TIL yellow+" or "dq g"' )
491 
492  # treat some old aliases
493  flags = flags.replace( 'lar','emba,embc,emeca,emecc,heca,hecc,fcala,fcalc' )
494  flags = flags.replace( 'tile','tigb,tilba,tilbc,tieba,tiebc' )
495  flags = flags.replace( 'trig','l1cal,l1mub,l1mue,l1ctp,trcal,trbjt,trbph,trcos,trele,trgam,trjet,trmet,trmbi,trmuo,trtau,tridt' )
496 
497  # loop over DQ channels
498  dqitems = DQChannels()
499  if flags == "*": # no additional arguments given --> select on all flags
500  # query over all DQ channels and add to show
501  dqchans = [y for (x,y) in dqitems]
502  if useAny:
503  newarg += self.InterpretSingleDQ( atlqarg, (','.join(dqchans), dqflagVal, folder) ) + ' '
504  else:
505  for dqchan in dqchans:
506  newarg += self.InterpretSingleDQ( atlqarg, (dqchan, dqflagVal, folder) ) + ' '
507 
508  else:
509  # assume some DQ channels are given, split by "," or " "
510  dqchans = []
511  for a in flags.upper().split(','):
512  if self.isVirtualFlag(a):
513  tmpdqchans = [a]
514  else:
515  # wildcard -- DANGEROUS --
516  tmpdqchans = [dqchan for (k,dqchan) in dqitems if a in dqchan]
517  if 'LUMI' == a and 'LUMIONL' in tmpdqchans:
518  tmpdqchans.remove('LUMIONL')
519  if 'IDVX' == a and 'MMUIDVX' in tmpdqchans:
520  tmpdqchans.remove('MMUIDVX')
521  if len(tmpdqchans)==0:
522  self.ParseError( 'Unknown DQ channel: "%s"' % a )
523  dqchans += tmpdqchans
524 
525  if useAny:
526  newarg += self.InterpretSingleDQ( atlqarg, (','.join(dqchans), dqflagVal, folder) ) + ' '
527  else:
528  for dqchan in dqchans:
529  newarg += self.InterpretSingleDQ( atlqarg, (dqchan, dqflagVal, folder) ) + ' '
530 
531 
532  return newarg
533 
534  def isVirtualFlag(self, flag):
535  return '_' in flag
536 
537  def InterpretSingleDQ( self, atlqarg, args ):
538  # expand colours
539  if len(args) != 3:
540  self.ParseError( 'ERROR in DQ argument: "%s" --> need <Flag> AND <Status> (len is: %i)' % (atlqarg, len(args)) )
541  flag, col, folder = args
542 
543  flag = flag.upper() # upper case status flags
544 
545  col = col.lower() # lower case color status only
546  trcol = ''
547  if not folder.startswith('DEFECTS'):
548  if col[0] == 'n':
549  trcol = 'n.a.'
550  elif col[0] == 'u':
551  trcol = 'unknown'
552  elif col[0] == 'g':
553  trcol = 'green'
554  elif col[0] == 'y':
555  trcol = 'yellow'
556  elif col[0] == 'r':
557  trcol = 'red'
558  elif col[0] == 'b':
559  trcol = 'black'
560  else:
561  self.ParseError( 'ERROR in DQ argument: "%s" --> uknown status: %s' % (args, col) )
562  if '+' in col:
563  trcol+= '+'
564  if '-' in col:
565  trcol+= '-'
566  else:
567  if col[0] == 'n':
568  trcol = 'red'
569  elif col[0] == 'u':
570  trcol = 'red'
571  elif col[0] == 'g':
572  trcol = 'green'
573  elif col[0] == 'y':
574  trcol = 'red'
575  elif col[0] == 'r':
576  trcol = 'red'
577  elif col[0] == 'b':
578  trcol = 'red'
579  elif col[0] == 'x':
580  trcol = 'none'
581  else:
582  self.ParseError( 'ERROR in DQ argument: "%s" --> uknown status: %s' % (atlqarg, col) )
583 
584 
585  return "--" + atlqarg.strip() + ' "' + flag + ' ' + trcol + ' ' + folder + '"'
586 
587  def InterpretDetectorMask( self, atlqarg, arg, neg ):
588  arg = (arg.partition(' ')[2]).lower().strip()
589  anyflag = ''
590  if 'any' in arg:
591  arg = arg.replace('any','').strip()
592  if not neg:
593  anyflag = 'A'
594 
595  # check who's in
596  mask = 0
597  for sarg in arg.split(","):
598  for i in range(0,len(self.dName)):
599  # is vetoed ?
600  if i in self.vetoedbits:
601  continue
602 
603  # sanity
604  d = self.dName[i].lower() + self.NotInAll[i]
605  if not ('unknown' in d or 'removed' in d):
606  # the actual query
607  if (sarg == 'all' and 'NotInAll' not in d) or sarg in d:
608  mask |= 1 << i
609 
610  # sanity check
611  if mask == 0:
612  print ('ERROR: could not find detector: "%s" in detector list' % arg)
613  print (self.dName)
614  print ('Note: search is case INSENSITIVE')
615  self.ParseError( '' )
616 
617  # decide whether detectors are required IN or OUT of partition
618  atlqarg.strip()
619  if neg:
620  atlqarg += 'out'
621  else:
622  atlqarg += 'in'
623 
624  return "--" + atlqarg + ' "%i%s' % (mask,anyflag) + '"'
625 
626  def ParseError( self, errtext, pos = -1 ):
627  print (' ')
628  print ('ERROR in argument: "%s"' % self.const_arg)
629  print ("%s" % errtext)
630  print (' ')
631  sys.exit(1)
632 
633  def MatchingQueryArg(self, arg):
634  arg = arg.split()[0] # first word of arg 'r' in 'r 9000-23100'
635  for key in self.queryArgs:
636  short = self.queryArgs[key][0] # e.g. 'r(uns)'
637  shortNoPar = short.replace('(','').replace(')','') # e.g. 'runs'
638  if '(' in short:
639  short = short[:short.find('(')] # e.g. 'r'
640  matchesArg = shortNoPar.startswith(arg.lower()) and arg.lower().startswith(short)
641  if matchesArg:
642  return key
643  return None
644 
645  def RetrieveQuery( self, findarg ):
646  # check that find part starts with f and remove the f(ind)
647  firstword, findarg = findarg.split(None,1)
648  if not 'find'.startswith(firstword):
649  self.ParseError( "Argument must begin with 'f(ind)'", 0 )
650 
651  argList = [x.strip() for x in findarg.split(" and ")]
652 
653  newarg = ""
654  for arg in argList:
655 
656  # check if negation
657  negation = False
658  if 'not' in arg:
659  arg = arg.replace("not","").strip()
660  negation = True
661 
662  key = self.MatchingQueryArg(arg)
663  if not key:
664  self.ParseError( "Could not find predefined keyword for arg: '%s' in 'find' block" % (arg) )
665  else:
666  short, atlqarg, function = self.queryArgs[key][0:3]
667  newarg += function( atlqarg, arg, negation ) + ' '
668 
669  return newarg
670 
671  def RetrieveShow( self, showarg ):
672 
673  #self.default_show = ["run","events","time"]
674  arglist = self.default_show + [a.strip() for a in showarg.split(' and ') if a.strip()!=''] # split at 'and'
675 
676  # show all
677  if 'all' in arglist:
678  idx = arglist.index('all')
679  arglist[idx:idx+1] = ['ready', 'lhc', 'trigk', 'rel', 'streams', 'det'] # slice it out
680  # show summary
681  if 'summary' in arglist:
682  arglist += ['dur', 'allev', 'str', 'dq']
683  # show lhc ...
684  if any([arg.startswith('lhc') for arg in arglist]):
685  arglist += ['olc']
686  # show dqsum & dqplots
687  tmpArgList = [arg.startswith('dqsum') or arg.startswith('dqpl') for arg in arglist]
688  if any(tmpArgList):
689  idx = tmpArgList.index(True)
690  arglist[idx+1:idx+1] = [ 'ready','lumi', 'lhc stablebeams', 'dq', 'ptag', 'trigrates L1_EM30', 'trigrates L1_EM5', 'trigrates L1_EM12']
691 
692  # interpret argument list
693  newarg = ""
694  for arg in arglist:
695  key = self.MatchingQueryArg(arg) # check argument validity
696  if key is None:
697  self.ParseError( "Could not find predefined keyword for arg: '%s' in 'show' block" % (arg) )
698 
699  # interpret argument and append to string
700  (short, atlqarg, dummy, function) = self.queryArgs[key][0:4]
701  newarg += function( atlqarg, short, arg )
702 
703  return newarg
704 
705 
706  def ShowVariable( self, atlqarg, short, arg ):
707  return '--show ' + atlqarg + ' '
708 
709  def ShowWithArg( self, atlqarg, short, arg ):
710  if len(arg.split())==1:
711  if atlqarg == 'olc':
712  return '--show olclumi --show olclbdata --show olcfillparams '
713  elif atlqarg == 'luminosity':
714  return '--show "lhc min" --show "%s 0" ' % (atlqarg)
715  else:
716  return '--show %s ' % atlqarg
717  else:
718  if atlqarg == 'olc':
719  return '--show "olclumi %s" --show olcfillparams --show olclbdata ' % arg.partition(' ')[2]
720  elif atlqarg == 'luminosity':
721  return '--show "lhc min" --show "%s %s" ' % (atlqarg, arg.partition(' ')[2])
722  else:
723  return '--show "%s %s" ' % (atlqarg, arg.partition(' ')[2])
724 
725  def PostProcessShowArgs( self, showargs ):
726 
727  # remove special duplicate
728  if len(showargs.split('lhc')) >= 3:
729  showargs = showargs.replace('--show "lhc min"','')
730 
731  # remove duplicates in show block
732  duples = ['--show %s' % d.strip() for d in showargs.split('--show') if d.strip()!='']
733  uniques = reduce(lambda first, second: (second not in first and first.append(second)) or first, duples, [])
734  showargs = ' '.join(uniques)
735 
736  return showargs
737 
738 
739  def ParseArgument( self, const_arg ):
740  self.const_arg = const_arg
741 
742 
743  # first separate the three parts ('/' is separator) and strip the spaces around each
744  findarg, showarg, otherarg = [x.strip() for x in (self.const_arg.split('/')+['',''])[0:3]]
745 
746  # check that show part starts with sh and remove the sh(ow)
747  if showarg!='':
748  if showarg[0:2] != 'sh':
749  self.ParseError( "Show block must begin with 'sh(ow)'", 0 )
750  showarg = showarg[showarg.index(' ')+1:] # remove first word 'sh(ow)'
751  else:
752  if ' sh ' in findarg or ' sho ' in findarg or ' show ' in findarg:
753  self.ParseError( "Show block must be separated by '/' from find condition'", 0 )
754 
755  # retrieve the query and show arguments (and check for input errors)
756  queryarg = self.RetrieveQuery( findarg.strip() )
757  shwarg = self.RetrieveShow ( showarg.strip() )
758 
759  # add 'lhc' to show if 'olclumi' query
760  # necessary because of stable beams information
761  if '--olclumi' in queryarg and 'stablebeams' not in queryarg:
762  queryarg += '--lhc "stablebeams TRUE" '
763 
764  shwarg = self.PostProcessShowArgs( shwarg )
765 
766  # interpret other arguments
767  nodef_flag = False
768  oargs = otherarg.split()
769  # always verbose for the time being...
770  extraargs = {'verbose' : '--verbose'}
771  idx = 0
772  while idx < len(oargs):
773  oa = oargs[idx]
774  if oa == 'v':
775  extraargs['verbose'] = '--verbose'
776  elif oa == 'noroot':
777  extraargs['noroot'] = '--noroot'
778  elif oa == 'root':
779  extraargs['root'] = '--root'
780  elif oa == 'nohtml':
781  extraargs['nohtml'] = '--nohtml'
782  elif oa == 'html':
783  extraargs['html'] = '--html'
784  elif oa == 'utc':
785  extraargs['utc'] = '--utc'
786  elif oa == 'nogrl':
787  extraargs['nogrl'] = '--nogrl'
788  elif oa == 'grl' or oa == 'xmlfile':
789  extraargs['xmlfile'] = '--xmlfile MyLBCollection.xml:MyLBCollection'
790  elif oa == 'nodef' :
791  nodef_flag = True
792  elif idx>0 and (oargs[idx-1]=='grl' or oargs[idx-1]=='xmlfile'):
793  extraargs['xmlfile'] = '--xmlfile %s' % oa
794  else:
795  print ("Extra argument '%s' unknown. Exiting." % oa)
796  sys.exit(1)
797  idx+=1
798 
799  if 'verbose' in extraargs:
800  print ("Parser: '%s'" % self.const_arg)
801  print (' find argument: "%s"' % findarg.strip())
802  print (' show argument: "%s"' % showarg.strip())
803  print (' extra argument: "%s"' % otherarg.strip())
804 
805  # no defaults for MC
806  if self.isMCDB:
807  nodef_flag = True
808 
809  # add default arguments
810  if not nodef_flag:
811  for key, argument, defaultvalue in [ (x[0],x[1][1],x[1][5]) for x in self.queryArgs.items()]:
812  if argument not in queryarg and defaultvalue != "":
813  queryarg += " --" + argument + ' "' + defaultvalue + '"'
814 
815  extraarg = ' '.join(extraargs.values())
816 
817  fullarg = '%s %s %s' % (queryarg, shwarg, extraarg)
818 
819  return fullarg
820 
821 
822 # command line driver for convenience
823 if __name__=='__main__':
824 
825  #from CoolRunQuery.AtlRunQueryParser import ArgumentParser
827 
828  if len(sys.argv) <= 1:
829  print ('No query argument given')
830  sys.exit(1)
831 
832  if sys.argv[1].lower() == 'detmask':
833  print ('Detector mask %s correspond to:\n%s' % (sys.argv[2], DecodeDetectorMask( int(sys.argv[2] ))))
834  sys.exit()
835 
836  if sys.argv[1].lower() == 'help':
837  ap.ParserUsage()
838  sys.exit(1)
839 
840  atlqueryarg = ap.ParseArgument( ' '.join(sys.argv[1:]) )
841  print ("\nAtlRunQuery.py %s\n" % atlqueryarg)
842 
replace
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition: hcg.cxx:307
python.AtlRunQueryParser.ArgumentParser.InterpretDetectorMask
def InterpretDetectorMask(self, atlqarg, arg, neg)
Definition: AtlRunQueryParser.py:587
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
python.AtlRunQueryParser.ArgumentParser.InterpretRangeNew
def InterpretRangeNew(self, atlqarg, arg, neg)
Definition: AtlRunQueryParser.py:178
python.AtlRunQueryParser.ArgumentParser.RetrieveQuery
def RetrieveQuery(self, findarg)
Definition: AtlRunQueryParser.py:645
python.AtlRunQueryParser.ArgumentParser.InterpretDQ
def InterpretDQ(self, atlqarg, args, neg)
Definition: AtlRunQueryParser.py:450
python.AtlRunQueryParser.ArgumentParser.sortedKeys
sortedKeys
Definition: AtlRunQueryParser.py:34
python.AtlRunQueryParser.ArgumentParser.InterpretRange
def InterpretRange(self, atlqarg, arg, neg)
Definition: AtlRunQueryParser.py:171
python.AtlRunQueryParser.ArgumentParser.isMCDB
isMCDB
Definition: AtlRunQueryParser.py:29
upper
int upper(int c)
Definition: LArBadChannelParser.cxx:49
python.AtlRunQueryParser.ArgumentParser.InterpretStreams
def InterpretStreams(self, atlqarg, arg, neg)
Definition: AtlRunQueryParser.py:253
python.AtlRunQueryParser.ArgumentParser.ShowDQ
def ShowDQ(self, atlqarg, short, arg)
Definition: AtlRunQueryParser.py:397
python.AtlRunQueryParser.ArgumentParser.default_find
default_find
Definition: AtlRunQueryParser.py:28
python.AtlRunQueryParser.ArgumentParser.replaceNumbers
def replaceNumbers(self, n)
Definition: AtlRunQueryParser.py:138
python.AtlRunQueryParser.ArgumentParser.const_arg
const_arg
Definition: AtlRunQueryParser.py:27
reduce
void reduce(HepMC::GenEvent *ge, std::vector< HepMC::GenParticlePtr > toremove)
Remove unwanted particles from the event, collapsing the graph structure consistently.
Definition: FixHepMC.cxx:81
python.AtlRunQueryParser.ArgumentParser.ShowWithArg
def ShowWithArg(self, atlqarg, short, arg)
Definition: AtlRunQueryParser.py:709
python.AtlRunQueryParser.ArgumentParser.getPtagAndPeriod
def getPtagAndPeriod(self, name)
Definition: AtlRunQueryParser.py:141
python.utils.AtlRunQueryLookup.DecodeDetectorMask
def DecodeDetectorMask(mask, lhcRun=3, smart=False)
Definition: AtlRunQueryLookup.py:420
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
python.AtlRunQueryParser.ArgumentParser.ParseError
def ParseError(self, errtext, pos=-1)
Definition: AtlRunQueryParser.py:626
python.AtlRunQueryParser.ArgumentParser.InterpretString
def InterpretString(self, atlqarg, arg, neg)
Definition: AtlRunQueryParser.py:184
python.AtlRunQueryParser.ArgumentParser.ParserUsage
def ParserUsage(self)
Definition: AtlRunQueryParser.py:118
python.AtlRunQueryParser.ArgumentParser.InterpretDuration
def InterpretDuration(self, atlqarg, arg, neg)
Definition: AtlRunQueryParser.py:262
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
python.utils.AtlRunQueryLookup.DQChannels
def DQChannels()
Definition: AtlRunQueryLookup.py:119
python.AtlRunQueryParser.ArgumentParser.dqFolderList
list dqFolderList
Definition: AtlRunQueryParser.py:23
python.AtlRunQueryParser.ArgumentParser.DQGetFolder
def DQGetFolder(cls, args, allowWildCards=False)
Definition: AtlRunQueryParser.py:309
TrigJetMonitorAlgorithm.items
items
Definition: TrigJetMonitorAlgorithm.py:79
python.AtlRunQueryParser.ArgumentParser.InterpretMagnets
def InterpretMagnets(self, atlqarg, arg, neg)
Definition: AtlRunQueryParser.py:281
python.AtlRunQueryParser.ArgumentParser.InterpretPeriods
def InterpretPeriods(self, atlqarg, arg, neg)
Definition: AtlRunQueryParser.py:150
python.AtlRunQueryParser.ArgumentParser.RetrieveShow
def RetrieveShow(self, showarg)
Definition: AtlRunQueryParser.py:671
python.AtlRunQueryInterpretDataPeriods.GetRuns
def GetRuns(arg)
Definition: AtlRunQueryInterpretDataPeriods.py:124
python.AtlRunQueryParser.ArgumentParser
Definition: AtlRunQueryParser.py:22
python.AtlRunQueryParser.ArgumentParser.ParseArgument
def ParseArgument(self, const_arg)
Definition: AtlRunQueryParser.py:739
python.utils.AtlRunQueryLookup.InitDetectorMaskDecoder
def InitDetectorMaskDecoder(lhcRun)
Definition: AtlRunQueryLookup.py:171
python.AtlRunQueryParser.ArgumentParser.ShowVariable
def ShowVariable(self, atlqarg, short, arg)
Definition: AtlRunQueryParser.py:706
python.AtlRunQueryParser.ArgumentParser.default_show
default_show
Definition: AtlRunQueryParser.py:30
python.AtlRunQueryParser.ArgumentParser.__init__
def __init__(self)
Definition: AtlRunQueryParser.py:26
python.AtlRunQueryParser.ArgumentParser.InterpretWithTwoArgs
def InterpretWithTwoArgs(self, atlqarg, arg, neg)
Definition: AtlRunQueryParser.py:210
python.AtlRunQueryParser.ArgumentParser.isVirtualFlag
def isVirtualFlag(self, flag)
Definition: AtlRunQueryParser.py:534
str
Definition: BTagTrackIpAccessor.cxx:11
dbg::print
void print(std::FILE *stream, std::format_string< Args... > fmt, Args &&... args)
Definition: SGImplSvc.cxx:70
python.AtlRunQueryParser.ArgumentParser.queryArgs
queryArgs
Definition: AtlRunQueryParser.py:39
python.AtlRunQueryParser.ArgumentParser.InterpretSingleDQ
def InterpretSingleDQ(self, atlqarg, args)
Definition: AtlRunQueryParser.py:537
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
python.AtlRunQueryParser.ArgumentParser.MatchingQueryArg
def MatchingQueryArg(self, arg)
Definition: AtlRunQueryParser.py:633
python.AtlRunQueryParser.ArgumentParser.PostProcessShowArgs
def PostProcessShowArgs(self, showargs)
Definition: AtlRunQueryParser.py:725