ATLAS Offline Software
Loading...
Searching...
No Matches
calibdata.py
Go to the documentation of this file.
1#!/bin/env python
2
3
4from CalibDataClass import *
5import readline
6import sys
7import traceback
8import os
9import fnmatch
10import getopt
11import re
12import fileinput
13import time
14
15# initializing some things, do not edit
16usedb = CalibDbInfo.calibdb
17noask = False
18force = False
19debug = False
20quiet = False
21nobatch = False
22upload = False
23createid = False
24showlist = False
25modifyhead = False
26copy = False
27copydata = []
28head_id = None
29tube_id = None
30tube = None
31chamber = None
32lowrun = None
33uprun = None
34lowtime = None
35uptime = None
36copysrc = None
37syncdb = False
38constant_type = None
39constant_arg = None
40insert_time = None
41sitename = None
42implementation = None
43status_flag = "NULL"
44valid = []
45delete = []
46upload_args = []
47rootfile = None
48luminosity = None
49newidfile = None
50cd = None
51autoimpl = False
52synclimit = 1
53
54datatypes = ['t0','rt','adc','id']
55
56def 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
116def 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
129def pout(output,newline=True):
130 if newline:
131 output += "\n"
132 if quiet == False:
133 print (output)
134
135def 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
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
153def checktypes(arg):
154 if len(list(set(arg) & set(datatypes))) == 0:
155 return False
156 else:
157 return True
158
159def 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
181def 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
190try:
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=" ])
192except 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
198if 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
205for 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
331try:
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
812except (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
829try:
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)
839except 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
void print(char *figname, TCanvas *c1)
STL class.
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177
summary(cd)
Definition calibdata.py:181
perr(error, exc=None, exit=False)
Definition calibdata.py:116
check_path(path)
Definition calibdata.py:135
checktypes(arg)
Definition calibdata.py:153
check_algo_type(type)
Definition calibdata.py:143
parse_date_dir(upload_arg)
Definition calibdata.py:159
pout(output, newline=True)
Definition calibdata.py:129