ATLAS Offline Software
calibdata.py
Go to the documentation of this file.
1 #!/bin/env python
2 
3 
4 from CalibDataClass import *
5 import readline
6 import sys
7 import traceback
8 import os
9 import fnmatch
10 import getopt
11 import re
12 import fileinput
13 import time
14 
15 # initializing some things, do not edit
16 usedb = CalibDbInfo.calibdb
17 noask = False
18 force = False
19 debug = False
20 quiet = False
21 nobatch = False
22 upload = False
23 createid = False
24 showlist = False
25 modifyhead = False
26 copy = False
27 copydata = []
28 head_id = None
29 tube_id = None
30 tube = None
31 chamber = None
32 lowrun = None
33 uprun = None
34 lowtime = None
35 uptime = None
36 copysrc = None
37 syncdb = False
38 constant_type = None
39 constant_arg = None
40 insert_time = None
41 sitename = None
42 implementation = None
43 status_flag = "NULL"
44 valid = []
45 delete = []
46 upload_args = []
47 rootfile = None
48 luminosity = None
49 newidfile = None
50 cd = None
51 autoimpl = False
52 synclimit = 1
53 
54 datatypes = ['t0','rt','adc','id']
55 
56 def usage():
57  print("\n --yes to avoid being asked for confirmation (-y)")
58  print("\n --quiet (-q) to run with no output. Will return 0 if no errors, 1 if any problem.")
59  print("\n --force (-F) to force delete of existing data attached to head id before upload or copy")
60  print("\n --list to list head id information from database (-l)")
61  print("\n --listdb to list available databases.")
62  print("\n--db=DATABASE to specify database to operate on (or to be used as destination in case of copy commands)")
63  print("\t If --db not specified actions will apply to default set by calibdb variable in CalibDbInfo.py")
64  print("\n --id=head id to apply actions to (-i headid). Not required by actions that \n\tmay create new head id (upload,copy,newid). If specified for upload or copy \n\tthen inserted data will be associated with that id. \n\t--force may be required to delete existing data for id")
65  print("\n --upload (-u) --path=/path/to/files [--path=/path/to/files] (-p)")
66  print("\tPath to 1 or more dir of files to upload named with chamber in filenames.\n\tIf directory is named YYYYMMDD will automatically use for lowtime/uptime. \n\tAssume 24HR period with end at midnight UTC of day in dir name.")
67  print("\tUpload can be a single filename. Filename doesn't have to contain chamber name if --chamber is specified.\n\tAny number of path arguments can be used though generally 2 would be used to upload RT and T0 together.\n")
68  print(" --implementation='implementation string'\n")
69  print("\tImplementation is ignored for RT as it is derived from type and path")
70  print("\n --type=[GTPM][T0BS][T0MT] (-t)")
71  print("\tArgument required if files do not have header. Ignored on per-file basis if standard header is provided in any file. Only one type can be specified (if uploading RT and T0 together at least one set must specify correct type in file headers). For RT upload type arguments are:")
72  print(" \tG = Gasmon RT")
73  print(" \tT = temperature-corrected")
74  print(" \tP = pressure-corrected")
75  print(" \tM = magnetic-field corrected")
76  print("\tFor T0 or ADC spectra types are:")
77  print(" \tT0BS = T0 Beam Splash")
78  print(" \tT0MT = T0 Mag,Temp corrected (also will accept T0CalibrationMT)")
79  print("\n --sync --from=database [--synclimit=<integer> (0 for no limit)] [--db=database]\n\tCompares head ids in source(--from) and destination db (--db), and synchronizes ids/data from\n\tsource if not found in destination (must be configured as 'replica').\n\tIf synclimit is not specified, will only sync highest head id. Otherwise sync until synclimit ids have been copied.\n\tIf both source and destination already contain same head ids then program will exit with no action.")
80  print("\n --copy=[t0,adc,rt] --from=ID[@DATABASE] (copy single id) or --from=database (for syncing to replicas) [--force] \n\tIf you do not provide existing --id to copy into then you may provide\n\timplementation, lowrun, uprun, lowtime, uptime to create new id with those parameters.\n\tTo modify some destination fields add --modifyhead and provide new values. \n\tFor convenience --implementation will be accepted without --modifyhead.\n\tIf target is specified as a replica in CalibDbInfo.py then you\n\tdo not need to specify destination ID or new id information - source meta information will be copied exactly.")
81  print("\tMultiple types may be copied at once, separate them with commas. t0 and adc are synonynms that copy the same tables (MDT_TUBE*)\n")
82  print("\tIn any case where a database is not provided for source (@DATABASE) or destination (--db)\n\tlocal database specified in config variable 'calibdb' is used")
83  print("\n --tube=tubeid (-b tubeid) \n\tNumeric ID (321937408) or tube name string (BIL1C01) to apply operations to")
84  print(" --chamber=chamberid (-c chamberid) \n\tChamber id or string to apply operations to.")
85  print("\n\tTube and chamber arguments can be applied to limit scope of any relevant operation.");
86  print("\tIf no tube or chamber is provided, operations effect all data for head id.")
87  print("\tMust provide --id with --tube or --chamber \n\tThey cannot be used to create new id with info for only one tube or chamber.")
88  print("\n --modifyhead --implementation='string' (only implementation,rootfile,statusflag supported). \n\tUse alone or in conjunction with 'copy' commands to modify existing head ids")
89  print("\n --newid to create a new headid from command line arguments (-n)")
90  print("\n --newidfile[=filename] -f [filename] \n\tUse to create a new headid from rows in file if provided \n\tor from info provided in command line args if no filename provided")
91  print("\tFile format is 5 columns ordered: \n\tIMPLEMENTATION LOWRUN UPRUN LOWTIME UPTIME\n\tFile can contain any number of rows to insert")
92  print("\n--lowrun (-L)")
93  print(" --uprun (-U)")
94  print("\tlowrun/uprun are required for new head ids")
95  print("\n --lowtime (-W) format: '20101231 23:59:00'")
96  print(" --uptime (-P) format '20101231 23:59:00'")
97  print("\tNote: lowtime/uptime are required for new head ids. \n\tIf first --path argument contains date in YYYYMMDD format then lowtime/uptime will be start and end of that day unless specified. ")
98  print("\n --luminosity (optional, defaults to 1.0)")
99  print("\n --rootfile (optional, defaults to 'none')")
100  print("\n --statusflag (optional, defaults to NULL")
101  print("\n --implementation (required for new head id)")
102  print("\tNOTE: Modifying other values is implemented internally but there is no option available to specify them - if needed please request.")
103  print("\n --delete [rt,t0,adc,id] (-e) to delete values for head id given by --id.\n\tIf id is in list, deletes that head id.\n\tDeleting id implies deleting values associated regardless of specification of adc,t0,rt in command.")
104  print("\n --setvalid [rt,t0,adc] (-z) sets data as valid for chamber or head id, requires --id and optionally --chamber args.\n")
105 
107  if noask == False and quiet == False:
108  confirm = raw_input("Enter 'y' or 'yes' if you wish to continue with operation: ")
109  else:
110  confirm = "y"
111  if confirm not in ("y","yes","Y","YES"):
112  return False
113  else:
114  return True
115 
116 def perr(error,exc=None,exit=False,):
117  if quiet == False:
118  output = error
119  if isinstance(exc,KeyboardInterrupt):
120  output += ": User Interrupt"
121  elif isinstance(exc,Exception):
122  if not isinstance(exc,SystemExit):
123  output += ": " + exc.__str__()
124  output += "\n"
125  print (output, file=sys.stderr)
126  if exit == True:
127  sys.exit(1)
128 
129 def pout(output,newline=True):
130  if newline:
131  output += "\n"
132  if quiet == False:
133  print (output)
134 
135 def check_path(path):
136  if os.path.isdir(path) or os.path.isfile(path):
137  return True
138  else:
139  perr("File/path argument to upload option does not exist", exit=True)
140  #sys.exit(1)
141 
142 # check --type argument
143 def check_algo_type(type):
144  if re.match(r'[GTPM]', type):
145  return True
146 
147  if type == 'T0CalibrationMT' or type == 'T0BS' or type == 'T0MT':
148  return True
149 
150  return False
151 
152 # check input data type in t0,adc,rt,id
153 def checktypes(arg):
154  if len(list(set(arg) & set(datatypes))) == 0:
155  return False
156  else:
157  return True
158 
159 def parse_date_dir(upload_arg):
160  global lowtime
161  global uptime
162  # try to parse a date from dirname and figure out IOV
163  check = re.compile(r'.*2[0-9][0-9][0-9][0-1][0-9][0-3][0-9]\/*')
164  find = re.compile(r'2[0-9][0-9][0-9][0-1][0-9][0-3][0-9]')
165  check_date = check.match(upload_arg)
166  if check_date != None and (lowtime == None and uptime == None):
167  upload_date = find.findall(upload_arg)
168  # calculate times for IOV from date found in upload_arg
169  lowtime = upload_date[0] + " 00:00:00"
170  uptime = upload_date[0] + " 23:59:59"
171  elif (lowtime != None and uptime != None):
172  upload_date = find.findall(uptime)
173  else:
174  pout("Upload directory name does not contain date in format: 20091021 and you did not specify lowtime/uptime in arguments. Today's date will be used.")
175  today = time.strftime('%Y%m%d')
176  lowtime = today + " 00:00:00"
177  uptime = today + " 23:59:59"
178  return [today]
179  return upload_date
180 
181 def summary(cd):
182  pout("Committed %s database operations this session in %s separate transactions. \nRolled back or failed %s write operations.\nTotal walltime %s and total CPU time %s seconds." % (cd.optotal, cd.transtotal, cd.opcount,cd.dbtime['wtime'],cd.dbtime['ptime']))
183 
184 # TODO: Rewrite all this to use argparse and
185 # consolidate some options into argument-optional
186 # versions (like --db to list db, --db= to set db, and then can remove --listdb)
187 # (getopt cannot handle optional arguments)
188 
189 # options
190 try:
191  opts, args = getopt.getopt(sys.argv[1:], "hup:d:t:b:c:m:i:nf:r:ylqDFL:U:W:P:", ["help", "upload","path=","delete=","type=","tube=","chamber=","implementation=","id=","newid","newidfile=","setvalid=","yes","list","quiet","debug","force","lowrun=","uprun=","lowtime=","uptime=","from=","copy=","modifyhead","luminosity=","rootfile=","statusflag=","listdb","db=","sync","synclimit=" ])
192 except getopt.GetoptError as err:
193  print ("A bad option was passed:", file=sys.stderr)
194  print (str(err), file=sys.stderr)
195  print ("Use option -h or --help for usage instructions", file=sys.stderr)
196  sys.exit(2)
197 
198 if len(opts) == 0:
199  print("This program requires an option: \n")
200  usage()
201  sys.exit(1)
202 
203 # option handling could probably be done better
204 # action prerequisite args here
205 for opt,arg in opts:
206  if opt in ["-y","--yes"]:
207  noask = True
208 
209  if opt in ["-h","--help"]:
210  usage()
211  sys.exit()
212 
213  if opt in ["--listdb"]:
214  print (CalibData.format_dblist())
215  sys.exit(0)
216 
217  if opt in ["--list", "-l"]:
218  showlist = True
219 
220  if opt in ["--db"]:
221  if arg in CalibDbInfo.databases:
222  usedb = arg
223  else:
224  perr("An unknown database was specified, valid databases are:");
225  print (CalibData.format_dblist())
226  sys.exit(1)
227 
228  if opt in ['--sync']:
229  syncdb = True
230 
231  if opt in ['--synclimit']:
232  if re.match(r"^\d+$", arg, flags=0):
233  synclimit = int(arg)
234  else:
235  perr("--synclimit must be integer",exit=True)
236 
237  if opt in ["-L","--lowrun"]:
238  lowrun = arg
239 
240  if opt in ["-U","--uprun"]:
241  uprun = arg
242 
243  if opt in ["-W","--lowtime"]:
244  lowtime = arg
245 
246  if opt in ["-P","--uptime"]:
247  uptime = arg
248 
249  if opt in ["--luminosity"]:
250  luminosity = arg
251 
252  if opt in ["--rootfile"]:
253  rootfile = arg
254 
255  if opt in ["--statusflag"]:
256  status_flag = arg
257 
258  if opt in ["-q", "--quiet"]:
259  quiet = True
260 
261  if opt in ["-D","--debug"]:
262  debug = True
263 
264  if opt in ["-i","--id"]:
265  head_id = arg
266 
267  if opt in ["-b","--tube"]:
268  tube = arg
269  nobatch = True
270 
271  if opt in ["-c","--chamber"]:
272  chamber = arg
273  nobatch = True
274 
275  if opt in ["-m","--implementation"]:
276  implementation = arg
277 
278  if opt in ["--copy"]:
279  copydata = arg.split(',')
280  copy = True
281  if not checktypes(copydata):
282  perr("Invalid copy types: %s" % arg)
283  upload_args.append('copyarg')
284 
285  if opt in ["--from"]:
286  copysrc = arg
287 
288  if opt in ["-z", "--setvalid"]:
289  valid = arg.split(',')
290  if not checktypes(valid):
291  perr("Invalid types for setting valid: %s" % arg)
292 
293  if opt in ["-e", "--delete"]:
294  delete = arg.split(',')
295  if not checktypes(delete):
296  perr("Invalid types for deletion: %s" % arg)
297 
298  if opt in ["--upload", "-u"]:
299  upload = True
300 
301  if opt in ["--modifyhead"]:
302  modifyhead = True
303 
304  if opt in ["-F","--force"]:
305  force = True
306 
307  if opt in ["-n", "--newid"]:
308  newidfile = None
309  createid = True
310  if upload == False:
311  upload_args = ['createid']
312 
313  if opt in ["-f","--newidfile"]:
314  implementation = 'fromfile'
315  newidfile = arg
316  createid = True
317  if upload == False:
318  upload_args = ['createid']
319 
320  if opt in ["-t","--type"]:
321  if check_algo_type(arg):
322  constant_arg = arg
323  else:
324  perr("Unknown algorithm type, not one of T0CalibrationMT, T0BS, T0MT or containing one of 'GTPM' for RT")
325  sys.exit(1)
326 
327  if opt in ["-p", "--path"]:
328  if check_path(arg):
329  upload_args.append(arg)
330 
331 try:
332 
333  if syncdb == True:
334  if copysrc not in CalibDbInfo.databases:
335  perr("\nMust specify a valid database key to --from argument",exit=True)
336  if usedb not in CalibDbInfo.databases:
337  perr("\nMust specify a valid destination database key to --db argument or in 'calibdb' setting in CalibDbInfo",exit=True)
338 
339  syncsrc = CalibData()
340  syncsrc.debug = debug
341  syncsrc.setdb(copysrc)
342  cd = CalibData()
343  cd.debug = debug
344  cd.setdb(usedb)
345 
346  srcdata = syncsrc.fetch_head_data()
347  dstdata = cd.fetch_head_data()
348  dst_ids = []
349  sync_ids = []
350 
351  for dst_head in dstdata:
352  dst_ids.append(dst_head[0])
353 
354  scount = 0
355  for src_head in srcdata:
356  if scount >= synclimit and synclimit != 0:
357  break
358  if src_head[0] not in dst_ids:
359  sync_ids.append(src_head[0])
360  scount += 1
361 
362  for copy_id in sync_ids:
363  print ("\nSyncing head id %s" % copy_id)
364  syncsrc = CalibData(copy_id)
365  syncsrc.setdb(copysrc)
366  syncsrc.debug = debug
367  syncsrc.get_head_info()
368  cd.copy_head(syncsrc)
369  cd.copy_tzero(syncsrc,ignore_missing=True)
370  cd.copy_rt(syncsrc,ignore_missing=True)
371 
372 
373  if upload == True or copy == True or createid == True:
374  # open file of head ids or set to 1 just to trigger 1 loop of head_id inserting from params
375  if newidfile != None and createid == True:
376  try:
377  idfile = open(newidfile, 'r')
378  except:
379  perr("Unable to open file of new head IDs: %s" % newidfile)
380  sys.exit(1)
381  else:
382  idfile = "1"
383 
384  # tally of how many files we read in the upcoming loop
385  count_files = 0
386  if upload == True:
387  pout("\nUploading from : %s" % (' '.join(upload_args)))
388  for upload_arg in upload_args:
389  if copy == True:
390  files = ["copyloop"]
391  elif upload_arg == 'createid':
392  files = ["idloop"]
393  else:
394  if os.path.isfile(upload_arg):
395  files = [upload_arg]
396  dirprep = ''
397  else:
398  files = os.listdir(upload_arg)
399  dirprep = upload_arg + "/"
400 
401  if head_id == None:
402  upload_date = parse_date_dir(upload_arg)
403 
404  for filename in files:
405  if not fnmatch.fnmatch(filename, '*.dat'):
406  continue
407  constant_type = constant_arg
408  # upload is initially false, becomes set to a string
409  if filename != 'copyloop' and filename != 'idloop':
410  f = open(dirprep + filename, 'r')
411  # read first line, determine what kind of upload this is. If RT with no header, we'll need to seek back to the first line.
412  f_start = f.tell()
413  rts = f.readline().split()
414  # T0 header is len 6, T0 is 19, ADC fit is 17.
415  if len(rts) == 6 or len(rts) == 19 or len(rts) == 17:
416  if len(rts) == 6:
417  ct = rts[3]
418  if constant_arg != None:
419  perr("Header found in input file, ignoring --type")
420  else:
421  ct = constant_type
422  f.seek(f_start)
423  if ct == "T0MT" or ct == "T0CalibrationMT":
424  upload = 't0'
425  constant_type = "T0MT"
426  fieldcount = 19
427  elif ct == "T0BS":
428  upload = 't0'
429  constant_type = ct
430  fieldcount = 19
431  elif ct == "ADCfit":
432  upload = 'adc'
433  constant_type = ct
434  fieldcount = 17
435  else:
436  raise Exception("Unrecognized algorithm type '%s' in T0 or ADC header in file %s" % (rts[3], filename))
437 
438  # if len == 3 it is RT with no header. If len == 12 it is RT with standard header
439  elif len(rts) == 3 or len(rts) == 12:
440  upload = 'rt'
441  fieldcount = 3
442  if len(rts) == 12:
443  # pull constant_type/algorithm from header. There isn't really a known standard for this so I'll use the one I invented for gas monitor RT uploads.
444  match_type = re.findall(r'[GPTM]+',rts[2])
445  if match_type:
446  constant_type = ''.join(match_type)
447  if constant_arg != None:
448  perr("Header found in input file, ignoring --type")
449  else:
450  raise Exception("Unable to find algorithm type from RT header field '%s' in file %s" % (rts[2],filename))
451  else:
452  f.seek(f_start)
453  if constant_type == None:
454  raise Exception("Unable to determine upload type from file contents: %s\nSpecifying a constant type with --type (aka ALGO_FLAG) is required for uploads if any files do not have a header." % filename)
455 
456  # only if no implementation argument on command line, set implementation from date defined by directory name of upload path
457  if implementation == None and head_id == None:
458  if upload == 'rt':
459  implementation = "RT_"
460  elif upload == 'adc' or upload == 't0':
461  implementation = "CALIB_"
462  implementation += constant_type + '_' + upload_date[0]
463  pout("No implementation specified, generating automatically: %s " % implementation)
464 
465  # end of specific to upload stuff......
466 
467  if cd == None:
468  for line in idfile:
469  if newidfile != None and createid == True:
470  idlines = line.split()
471  implementation = idlines[0]
472  lowrun = idlines[1]
473  uprun = idlines[2]
474  lowtime = idlines[3] + " " + idlines[4]
475  uptime = idlines[5] + " " + idlines[6]
476  try:
477  cd = CalibData(head_id,implementation,lowrun,uprun,lowtime,uptime,luminosity,rootfile,status_flag)
478  cd.debug = debug
479  cd.setdb(usedb)
480  if head_id != None:
481  cd.get_head_info()
482  if copy == True:
483  cdsource = CalibData(copysrc)
484  cdsource.debug = debug
485  cdsource.get_head_info()
486  pout("Source head id %s from database has information:" % cdsource.head_id)
487  pout(cdsource.format_headinfo())
488 
489  except QueryError as exc:
490  output = "\nCould not retrieve head id(s) from database: "
491  if "cdsource" not in locals() and head_id != None:
492  output += "ID %s" % head_id
493  if "cdsource" in locals():
494  output += " ID " + copysrc
495  perr(error=output,exception=exc)
496  sys.exit(1)
497 
498  if cd.head_id != None:
499  pout("Destination head id %s from database has information:" % cd.head_id)
500  pout(cd.format_headinfo())
501 
502  if implementation != None and copy == True:
503  pout("Setting/modifying destination implementation to '%s'" % implementation)
504  cdsource.implementation = implementation
505 
506  if (copy == True) and tube == None and chamber == None:
507  pout("If --id specified, copy will overwrite destination id with source values.\nIf implementation provided on command line it will be used for destination.\nIf no id is specified, a new one will be created with source data.\nIf destination is replica db an exact copy of source, including head id, will be created.")
508 
509  if cd.head_id == None:
510  try:
511  if copy == True:
512  cd.copy_head(cdsource)
513  else:
514  cd.write_headid()
515  pout("Successful commit will create new head ID: %s" % cd.head_id)
516  pout(cd.format_headinfo())
517  except HeadInsertError:
518  perr("Sorry, failed to setup head_id, quitting now")
519  raise
520 
521  if ask_confirm() == False:
522  sys.exit(0)
523 
524  if upload != False:
525  pout("\nFilename: %s" % filename, newline=False)
526  count_files += 1
527 
528  # this might seem redundant but we don't know what format we got from extract_tubestring
529  # the two methods below take whatever as an input and return a known format even if they might just return the input
530 
531  chamber_string = CalibData.extract_tubestring(filename)
532 
533  if (chamber_string):
534  chamber = CalibData.get_tube_string(chamber_string)
535  chamber_id = CalibData.get_tube_id(chamber_string)
536  elif (chamber):
537  chamber_id = CalibData.get_tube_id(chamber)
538  chamber = CalibData.get_tube_string(chamber)
539  else:
540  if filename != 'copyloop' and filename != 'idloop':
541  pout("Skipping %s, could not determine chamber from filename and none given on command line (may be fake bookkeeping chamber)" % filename)
542  continue
543 
544  pout("Chamber is: %s" % chamber, 0)
545  pout("Chamber id is: %s" % chamber_id, 0)
546 
547  if tube != None:
548  tube_id = CalibData.get_tube_id(tube)
549  tube = CalibData.get_tube_string(tube)
550  pout("Tube is: %s" % chamber, 0)
551  pout("Tube id is: %s" % chamber_id, 0)
552 
553  if upload != False:
554  cd.type = constant_type
555  if upload == 'rt':
556  try:
557  # insert RT into mdt_rt table, chamber_id was determined from file or arguments by this point
558  if force:
559  cd.delete_rt(chamber_id)
560  cd.insert_rt(chamber_id)
561 
562  except DataUniqueError:
563  perr("\nRT value exists for chamber.\nAdd --force to command to force delete before insert or delete rt with --delete='rt' option")
564  raise
565  except RTInsertError:
566  perr("Problem inserting RT for chamber: %s id: %s" % (chamber,chamber_id))
567  perr("Not deleting head id, reuse with --id flag or delete with --delete=id")
568  raise
569  except Exception:
570  perr("Error with RT insert operation")
571  raise
572 
573  # point_nr is just an informational count of datapoints in file (number of lines, start at 0 for first point)
574  point_nr = 0
575 
576  for line in f:
577  try:
578  rts = line.split()
579  if len(rts) != fieldcount:
580  perr("Invalid line in %s file %s, too many or too few fields" % (upload, filename))
581  if upload == 'rt':
582  cd.insert_rt_map(point_nr,rts[0],rts[1],rts[2])
583  elif upload == 't0' or upload == 'adc':
584  tube_id_string = rts[0] + "_" + rts[1] + "_" + rts[2] + "-" + rts[4] + "-" + rts[5] + "-" + rts[6]
585  tube_id = cd.get_tube_id(tube_id_string)
586  pout("Tube ID string: %s" % tube_id_string,0)
587  pout("Tube ID: %s" % tube_id)
588 
589  cd.t0_tube_grouping = "CHAMBER"
590  # hmm...not efficient if inserting a batch of them, but allows for not necessarily inserting/overwriting every t0.
591  # educate users to use --deletet0 for faster overwrites of existing t0 in batch uploads
592  if force == True:
593  cd.delete_tube(tube_id,chamber_id)
594  if upload == 't0':
595  cd.insert_t0(tube_id,chamber_id,rts[7],rts[8],rts[9],rts[10],rts[11],rts[12],rts[13],rts[14],rts[15],rts[16],rts[17],rts[18])
596  elif upload == 'adc':
597  cd.insert_adc(tube_id,chamber_id,rts[7],rts[8],rts[9],rts[10],rts[11],rts[12],rts[13],rts[14],rts[15],rts[16])
598  except (RTInsertError, T0InsertError, ADCInsertError):
599  perr("Error inserting values read at line %s in file %s" % (point_nr + 1, filename))
600  perr("Not deleting head id, reuse with --id flag or delete with --delete=id")
601  raise
602  except DataUniqueError:
603  perr("Values already exist for chamber %s (%s) tube %s (%s) at line %s in file %s. Use --force to delete existing t0 one-by-one before each insert. Use --delete=[t0,rt,adc] to delete values. \n" % (chamber, chamber_id, tube_id_string, tube_id, point_nr + 1, filename))
604  raise
605  except Exception:
606  perr("An error has occurred at line %s in file %s." % (point_nr + 1,filename))
607  raise
608  point_nr += 1
609 
610  if upload == 'rt' and point_nr != 100 and point_nr != 200:
611  raise Exception("Found %s data points in file %s. RT must have either 100 or 200 data points." % (point_nr,filename))
612  # reset all values or might validate values from this iteration on next one
613  chamber = None
614  chamber_id = None
615  tube = None
616  tube_id = None
617 
618  if count_files > 0:
619  pout("\nFound %d files in dir %s" % (count_files,upload_arg))
620  pout("\nInserting to head_id %s" % cd.head_id)
621 
622  if 't0' in copydata or 'adc' in copydata:
623  try:
624  if force == True:
625  cd.delete_tube(tube,chamber)
626  cd.copy_tzero(cdsource,chamber,tube)
627  #if implementation != None and head_id != None:
628  # cd.implementation = implementation
629  # cd.write_headid()
630  pout("T0/ADC copy complete")
631  except DataCopyError:
632  perr("Problem copying values from %s to %s@%s" % (copysrc, cd.head_id, cd.database))
633  raise
634  except DataUniqueError:
635  perr("Data for tube(s) or chamber(s) already exists. Use --force to overwrite.")
636  raise
637  except HeadInsertError:
638  perr("Error modifying head id %s" % cd.head_id)
639  raise
640  except Exception:
641  perr("Error copying T0/ADC")
642  raise
643 
644  if 'rt' in copydata:
645  try:
646  if force == True:
647  cd.delete_rt(chamber)
648  # should just require adding --modifyhead but for convenience in this one case...
649  cd.copy_rt(cdsource,chamber)
650  if implementation != None and head_id != None:
651  cd.implementation = implementation
652  cd.write_headid
653  pout("RT Copy complete")
654  except DataCopyError:
655  perr("Problem copying RT values from %s to %s@%s" % (copysrc, cd.head_id, cd.database))
656  raise
657  except DataUniqueError:
658  perr("Data for chamber(s) already exists. Use --force to overwrite.")
659  raise
660  except HeadInsertError:
661  perr("Error modifying head id %s" % cd.head_id)
662  raise
663  except Exception:
664  perr("Error copying RT")
665  raise
666  if (modifyhead):
667  if cd.head_id == None:
668  perr("Must provide --id with --modifyhead")
669  sys.exit(1)
670 
671  fields = { 'implementation':implementation, 'lowrun':lowrun, 'uprun':uprun, 'lowtime':lowtime, 'uptime':uptime,'luminosity':luminosity, 'rootfile':rootfile, 'sitename':sitename,'insert_time':insert_time, 'status_flag':status_flag }
672  modified = False
673  try:
674  for field,val in fields.items():
675  if val != None:
676  setattr(cd, field, val)
677  modified = True
678  if modified == False:
679  perr("No modification specified")
680  sys.exit(1)
681  cd.write_headid()
682  except HeadInsertError as exc:
683  perr("Error modifying head id" + cd.head_id, exc)
684  raise
685 
686  if showlist:
687  noask = True
688  try:
689  cd = CalibData()
690  cd.debug = debug
691  cd.setdb(usedb)
692  print (cd.format_head_data(cd.fetch_head_data()))
693  sys.exit(0)
694  except QueryError as exc:
695  perr("Error querying for head ids", exc)
696  sys.exit(1)
697 
698  if delete or valid:
699  if head_id == None:
700  perr("You did not give head id (--id=)")
701  sys.exit(1)
702 
703  if not isinstance(cd,CalibData):
704  cd = CalibData(head_id)
705  cd.setdb(usedb)
706  cd.debug = debug
707  try:
708  cd.get_head_info()
709  except QueryError as exc:
710  perr("Could not retrieve information for head id: %s" % head_id, exc)
711  sys.exit(1)
712 
713  if tube != None:
714  try:
715  tube_id = cd.get_tube_id(tube)
716  tube = cd.get_tube_string(tube)
717  except TubeIdError:
718  perr("Invalid tube string or numeric ID was input")
719  raise
720  except Exception:
721  perr("Unable to convert tube string or ID")
722  raise
723  else:
724  tube_id = None
725 
726  if chamber != None:
727  try:
728  chamber_id = cd.get_tube_id(chamber)
729  chamber = cd.get_tube_string(chamber)
730  except TubeIdError:
731  perr("Invalid tube string or numeric ID was input")
732  sys.exit(1)
733  except Exception:
734  perr("Invalid chamber string or ID was put in")
735  sys.exit(1)
736  else:
737  chamber_id = None
738 
739  if 'rt' in delete:
740  pout("Deleting RT for head id: %s, implementation name: %s " % (head_id,cd.implementation))
741  if chamber_id != None:
742  pout("Chamber: %s, chamber id: %s" % (chamber, chamber_id))
743  if ask_confirm() == False:
744  sys.exit(0)
745  try:
746  cd.delete_rt(chamber_id)
747  except DeleteError:
748  perr("Error deleting rt for head id %s \n" % head_id)
749  raise
750  except Exception:
751  raise
752 
753  if 't0' in delete:
754  pout("Deleting T0 for head id: %s, implementation name: %s " % (head_id,cd.implementation))
755  if chamber != None:
756  pout("Deleting t0 for chamber: %s, tube id: %s" % (chamber, chamber_id))
757  if tube_id != None:
758  pout("Deleting t0 for tube: %s, tube id: %s" % (tube, tube_id))
759  if ask_confirm() == False:
760  sys.exit(0)
761  try:
762  cd.delete_tube(tube_id,chamber_id)
763  except DeleteError:
764  perr("Error deleting t0 for head id %s" % head_id)
765  raise
766  except Exception:
767  raise
768 
769  # modify all this so any number of items can be set valid at once....
770  if 't0' in valid or 'adc' in valid:
771  try:
772  cd.set_t0_valid(tube_id)
773  except UpdateError:
774  print("Error setting t0 valid flag for head id %s \n" % head_id)
775  except Exception:
776  raise
777 
778  pout("Committing update of t0 valid flag for head id: %s, implementation name: %s " % (head_id,cd.implementation))
779  if tube_id != None:
780  pout("Tube: %s, tube id: %s" % (tube, tube_id))
781 
782  if 'rt' in valid:
783  try:
784  cd.set_rt_valid(tube_id)
785  except UpdateError:
786  perr("Error setting RT valid flag for head id %s \n" % head_id)
787  except Exception:
788  raise
789  pout("Committing update of rt valid flag for head id: %s, implementation name: %s " % (head_id,cd.implementation))
790  if tube_id != None:
791  pout("Tube: %s, tube id: %s" % (tube, tube_id))
792 
793  if 'id' in delete:
794  pout("*** Will delete associated RT ***")
795  pout("*** Will delete associated T0 ***")
796  pout("*** Will delete associated ADC ***")
797  pout ("*** Will delete all head id information ***")
798  pout(cd.format_headinfo())
799  if ask_confirm() == False:
800  sys.exit(0)
801  try:
802  cd.delete_head_id()
803  cd.delete_rt()
804  cd.delete_tube()
805  except DeleteError:
806  perr("Error deleting head id: %s" % head_id)
807  raise
808  except Exception:
809  raise
810 
811 # catch unhandled exceptions
812 except (Exception,KeyboardInterrupt) as exc:
813  # catch when we exit(0) by intent
814  if isinstance(exc,SystemExit):
815  if exc.code == 0:
816  sys.exit(0)
817  if debug == True:
818  traceback.print_exc()
819  perr("Error performing operation", exc)
820  if isinstance(cd,CalibData):
821  cd.rollback()
822  summary(cd)
823 
824  sys.exit(1)
825 
826 # safe and sound with no exceptions and time to commit whatever we did up there
827 # ...that is, time to commit anything that didn't get committed automatically when we exceeded 10000 operations for CalibData.opcount internally
828 
829 try:
830  pout("Committing data to database.")
831  commit = True
832  if debug:
833  commit = ask_confirm()
834  if commit == False:
835  cd.rollback()
836  if commit == True:
837  cd.commit(force=True)
838  summary(cd)
839 except Exception as exc:
840  perr("There was an error committing data", exc)
841  if cd:
842  cd.rollback()
843  summary(cd)
844  sys.exit(1)
845 
846 
847 
848 
calibdata.pout
def pout(output, newline=True)
Definition: calibdata.py:129
calibdata.perr
def perr(error, exc=None, exit=False)
Definition: calibdata.py:116
calibdata.check_algo_type
def check_algo_type(type)
Definition: calibdata.py:143
calibdata.parse_date_dir
def parse_date_dir(upload_arg)
Definition: calibdata.py:159
calibdata.check_path
def check_path(path)
Definition: calibdata.py:135
calibdata.summary
def summary(cd)
Definition: calibdata.py:181
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
calibdata.checktypes
def checktypes(arg)
Definition: calibdata.py:153
CxxUtils::set
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
Definition: bitmask.h:232
print
void print(char *figname, TCanvas *c1)
Definition: TRTCalib_StrawStatusPlots.cxx:25
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
Trk::open
@ open
Definition: BinningType.h:40
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
calibdata.usage
def usage()
Definition: calibdata.py:56
str
Definition: BTagTrackIpAccessor.cxx:11
CalibDataClass.CalibData
Definition: CalibDataClass.py:52
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
calibdata.ask_confirm
def ask_confirm()
Definition: calibdata.py:106