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