nova_uptime.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 """
3 Compute operations statistics (uptime, POT recorded, delivered, etc.)
4 for NOvA.
5 
6 Based on original work of Jon Paley.
7 
8 messier@indiana.edu
9 """
10 import sys, os
11 import getopt
12 import shlex, subprocess
13 import re, urllib2, csv
14 from datetime import date, datetime, timedelta
15 import psycopg2
16 import psycopg2.extras
17 
18 #.......................................................................
19 DETECTOR = 'fardet'
20 
21 #.......................................................................
22 #
23 # Do we want the downtime report? Uptime report?
24 #
25 DO_DOWNTIME_REPORT = False
26 DO_UPTIME_REPORT = True
27 #
28 # The shortest downtime worth reporting
29 #
30 DOWNTIME_MIN = timedelta(minutes=1)
31 
32 #.......................................................................
33 #
34 # If we are asked for just one run summary, set this to the value of
35 # the run number
36 #
37 DO_RUN_POT_SUMMARY = 0
38 
39 #.......................................................................
40 #
41 # Real spills will have more than this number (time 1e12) POT recorded
42 #
43 GOOD_SPILL_POT = 0.05
44 
45 #.......................................................................
46 #
47 # Some database variables
48 #
49 DB_CURSOR = None
50 DB_QUERY_TIME = timedelta(0)
51 
53  """ Establish connection to runs database
54  JMP 2015-04-06: This function seems to not be used for anything.
55  Might want to remove it. But just in case, changed dB connection info
56  to use streaming replica of FarDet DAQ dB. Use port 5434 for the
57  NearDet, otherwise this is for FarDet
58  """
59  DB_NAME = os.environ['NOVADBNAME'] # 'nova_prod'
60  DB_HOST = os.environ['NOVADBHOST'] # 'ifdbrep.fnal.gov'
61  DB_USER = os.environ['NOVADBUSER'] # 'nova_reader'
62  DB_PASS = open(os.environ['NOVADBPWDFILE'], 'r').readlines()[0].strip()
63  DB_FAR_PORT = os.environ['NOVAFARDAQDBPORT'] # '5436'
64 
65  try:
66  conn = psycopg2.connect(\
67  "dbname=%s host=%s user=%s password=%s port=%s" % \
68  (DB_NAME, DB_HOST, DB_USER, DB_PASS, DB_FAR_PORT))
69  global DB_CURSOR
70  DB_CURSOR = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
71  except:
72  print "I am unable to connect to the database"
73 
74 #.......................................................................
75 
76 def in_unix(input):
77  """ Convert a datetime to UNIX time
78 
79  Args:
80  input: A datetime object
81 
82  Returns:
83  A floating points number of seconds since Jan. 1, 1970 (UNIX standard)
84 
85  """
86  start = datetime(year=1970,month=1,day=1,hour=0,minute=0,second=0)
87  diff = input - start
88  return diff.total_seconds()
89 
90 #.......................................................................
91 
92 def nactive_chans(run):
93  """ Return how many active channels there we at start of run
94 
95  Args:
96  run: Run number
97 
98  Returns:
99  Number of active channels (APD pixels)
100  """
101  if (run==0):
102  return 0
103  sql = "select nactivechan from "+DETECTOR+".runs where run="+str(run)
104  DB_CURSOR.execute(sql)
105  n = DB_CURSOR.fetchall()
106  return n[0]['nactivechan']
107 
108 #.......................................................................
109 
110 def run_at(day):
111  """ Find the run that was going at time "day"
112 
113  Args:
114  day : A datetime object
115  """
116  sql0 = "select run,tstart,tstop from "+DETECTOR+".runs";
117  cut1 = " where partition=1";
118  cut2 = " tstop is not null"
119  cut3 = "'{}' >= tstart".format(day.strftime("%Y-%m-%dT%H:%M:%S"))
120  cut4 = "'{}' <= tstop".format(day.strftime("%Y-%m-%dT%H:%M:%S"))
121 
122  sql1 = "order by tstart asc"
123 
124  SQL = \
125  sql0 + \
126  cut1 + " and " + \
127  cut2 + " and " + \
128  cut3 + " and " + \
129  cut4 + " " + \
130  sql1
131 
132  DB_CURSOR.execute(SQL);
133  runs = DB_CURSOR.fetchall();
134 
135  return runs
136 
137 
138 #.......................................................................
139 
140 def runs_for_period(day0, day1):
141  """ Get all runs that start or stop within a particular date range
142 
143  Args:
144  day0 : A datetime object for first day
145  day1 : A datetime object for the last day
146  """
147  sql0 = "select run,tstart,tstop from "+DETECTOR+".runs";
148  cut1 = " where partition=1";
149  cut2 = " tstop is not null"
150  cut3 = "tstart >= '{}'".format(day0.strftime("%Y-%m-%dT%H:%M:%S"))
151  cut4 = "tstart < '{}'".format(day1.strftime("%Y-%m-%dT%H:%M:%S"))
152 
153  cut5 = "tstop >= '{}'".format(day0.strftime("%Y-%m-%dT%H:%M:%S"))
154  cut6 = "tstop < '{}'".format(day1.strftime("%Y-%m-%dT%H:%M%:S"))
155 
156  sql1 = "order by tstart asc"
157 
158  SQL = \
159  sql0 + \
160  cut1 + " and " + \
161  cut2 + " and " + \
162  "((" + cut3+" and "+cut4+") or ("+cut5+" and "+cut6+")) " + \
163  sql1
164 
165  DB_CURSOR.execute(SQL);
166  runs = DB_CURSOR.fetchall();
167 
168  return runs
169 
170 #.......................................................................
171 
172 def runs_by_day(day0):
173  """ Get a complete list of run numbers for a specified day
174 
175  Any run that starts or stops on the specified date is contaned in
176  the list
177 
178  Args:
179  day0: A datetime object for the requested day
180 
181  Returns:
182  An list of SQL results for run,tstart,tstop ordered by start time
183  """
184  day1 = day0+timedelta(days=1)
185  return runs_for_period(day0, day1)
186 
187 #.......................................................................
188 
189 def run_minmax(runs):
190  """ Find the highest and lowest run number in a list
191 
192  Args:
193  runs: A list of SQL results (run,tstart,tstop)
194 
195  Returns:
196  (runlo,runhi), the lowest and highest run numbers in the list
197  """
198  runmin = runs[0]['run']
199  runmax = runs[0]['run']
200  for r in runs:
201  if (r['run']<runmin):
202  runmin = r['run']
203  if (r['run']>runmax):
204  runmax = r['run']
205  return (runmin,runmax)
206 
207 #.......................................................................
208 
209 def compute_uptime(day,runs):
210  """ Compute the number of live hours in a particular day.
211 
212  Also computes the fractional up time (by live seconds) for the day
213 
214  Args:
215  day (datetime): The date in question
216  runs (list,int): List of runs selected to be on that day
217 
218  Returns:
219  (livetime, fraction): The uptime in hours (timedelta) and the
220  fractional livetime
221  """
222 
223  daystart = day
224  dayend = day + timedelta(days=1)
225  sum = timedelta(0)
226 
227  for r in runs:
228  t1 = r['tstart']
229  t2 = r['tstop']
230  #
231  # Handle end points. Runs that carried into this day and runs
232  # that extedned beyond the end of this day should be pinnedto
233  # the start and end of the day.
234  #
235  if (t1<daystart):
236  t1 = daystart
237  if (t2>dayend):
238  t2 = dayend
239 
240  sum += (t2-t1)
241  #
242  # An unfortunate hack - when the live time is 100% the timedelta
243  # reports as "1 day and 0 seconds" which is not parsed well in
244  # spreadsheets. So, convert back to something that is just 1
245  # second shy of a day.
246  #
247  if (sum>=timedelta(days=1)):
248  sum = timedelta(days=0,seconds=24*60*60-1)
249  #
250  # Return the total number of hours of livetime and the fractional
251  # livetime for the day
252  #
253  return (sum,sum.seconds/(24.0*60.0*60.0))
254 
255 #.......................................................................
256 
257 def spills_between(t1, t2):
258  """
259  Return spill information (unix time and POT) for a datetime range
260 
261  Args:
262  t1 (datetime): Start time
263  t2 (datetime): End time
264 
265  Returns:
266  List of (time,pot) tuples
267  """
268  global DB_QUERY_TIME
269 
270  spills = [];
271 
272  tf1 = in_unix(t1)
273  tf2 = in_unix(t2)
274  webaddress = 'http://ifb-data.fnal.gov:8099'\
275  '/ifbeam/data/data?'\
276  'v=E:TRTGTD&e=e,a9&t0={}&t1={}&&f=csv'.\
277  format(tf1,tf2)
278 
279  dd = None
280  #
281  # Make three tries and then bail...
282  #
283  t0 = datetime.utcnow()
284  try:
285  dd = urllib2.urlopen(webaddress,None,600)
286  except:
287  try:
288  dd = urllib2.urlopen(webaddress,None,600)
289  except:
290  try:
291  dd = urllib2.urlopen(webaddress,None,600)
292  except:
293  return spills
294  t1 = datetime.utcnow()
295 
296  DB_QUERY_TIME += (t1-t0)
297 
298  if (dd==None):
299  return spills
300 
301  csvdata = csv.reader(dd)
302 
303  for row in csvdata:
304  if (row.count('E:TRTGTD')>0):
305  if (row[4]!='null'):
306  spills.append( (float(row[2])/1000., float(row[4])) )
307 
308  return spills
309 
310 #.......................................................................
311 
312 def mc7_spills_between(t1, t2):
313  """
314  Return spill information (unix time and POT) for a datetime range
315 
316  Args:
317  t1 (datetime): Start time
318  t2 (datetime): End time
319 
320  Returns:
321  List of (time,pot) tuples
322  """
323  global DB_QUERY_TIME
324 
325  spills = [];
326 
327  tf1 = in_unix(t1)
328  tf2 = in_unix(t2)
329  webaddress = 'http://ifb-data.fnal.gov:8099'\
330  '/ifbeam/data/data?'\
331  'v=F:MC7SC1&e=e,36&t0={}&t1={}&&f=csv'.\
332  format(tf1,tf2)
333 
334  dd = None
335  #
336  # Make three tries and then bail...
337  #
338  t0 = datetime.utcnow()
339  try:
340  dd = urllib2.urlopen(webaddress,None,600)
341  except:
342  try:
343  dd = urllib2.urlopen(webaddress,None,600)
344  except:
345  try:
346  dd = urllib2.urlopen(webaddress,None,600)
347  except:
348  return spills
349  t1 = datetime.utcnow()
350 
351  DB_QUERY_TIME += (t1-t0)
352 
353  if (dd==None):
354  return spills
355 
356  csvdata = csv.reader(dd)
357 
358  for row in csvdata:
359  if (row.count('F:MC7SC1')>0):
360  if (row[4]!='null'):
361  spills.append( (float(row[2])/1000., float(row[4])) )
362 
363  return spills
364 
365 #.......................................................................
366 
367 def pot_between(t1,t2,spills):
368  """ Compute the POT recorded between two time stamps.
369 
370  Args:
371  t1 (datetime) : Start time
372  t2 (datetime) : End time
373  spills ( list[(time,pot)]) : Complete list of spills for time period
374 
375  Returns:
376  pot (float) : Protons in units of 1e18 POT
377  """
378 
379  tf1 = in_unix(t1)
380  tf2 = in_unix(t2)
381 
382  sum = 0.0
383  for (t,q) in spills:
384  if ((t>=tf1)&(t<=tf2)&(q>GOOD_SPILL_POT)):
385  sum += q
386  #
387  # Database is in units of 1e12, I want 1e18.
388  #
389  return sum*(1.0E12/1.0E18)
390 
391 def nspills_between(t1,t2,spills):
392  """ Count the number of good spills between t1 and t2
393 
394  Args:
395  t1 (datetime) : Start time
396  t2 (datetime) : End time
397  spills ( list[(time,pot)]) : Complete list of spills for time period
398 
399  Returns:
400  nt (int) : Number of spills between t1 and t2
401  """
402 
403  tf1 = in_unix(t1)
404  tf2 = in_unix(t2)
405 
406  sum = 0.0
407  for (t,q) in spills:
408  if ((t>=tf1)&(t<=tf2)&(q>GOOD_SPILL_POT)):
409  sum += 1
410 
411  return sum
412 
413 #.......................................................................
414 
415 def compute_pot(day,runs,spills):
416  """ Tally the protons on target delivered and recorded in a day
417 
418  Args:
419  day : datetime of day of interest
420  runs (sql) : SQL set of runs (run, tstart, tend)
421  spills (list[(time,pot)]) : Complete list of spills for time period
422 
423  Returns:
424  (pot_recorded,pot_delivered) (float,float)
425  """
426  daystart = day
427  dayend = day + timedelta(days=1)
428 
429  pot_delivered = pot_between(daystart,dayend,spills)
430 
431  pot_recorded = 0.0
432  for r in runs:
433  t1 = r['tstart']
434  t2 = r['tstop']
435  #
436  # Handle end points. Runs that carried into this day and runs
437  # that extedned beyond the end of this day should be pinned to
438  # the start and end of the day.
439  #
440  if (t1<daystart):
441  t1 = daystart
442  if (t2>dayend):
443  t2 = dayend
444 
445  pot_recorded += pot_between(t1,t2,spills)
446 
447  return (pot_recorded,pot_delivered)
448 
449 #.......................................................................
450 
452  """ Print a single line summary of a particular run number
453  """
454  #
455  # Querry runs database to find start and end time of run
456  #
457  sql0 = "select tstart,tstop from "+DETECTOR+".runs";
458  cut1 = " where partition=1";
459  cut2 = " tstop is not null"
460  cut3 = " run=%d"%run
461 
462  SQL = \
463  sql0 + \
464  cut1 + " and " + \
465  cut2 + " and " + \
466  cut3;
467 
468  DB_CURSOR.execute(SQL);
469  run_data = DB_CURSOR.fetchall();
470 
471  #
472  # Collect the POT inside the time interval
473  #
474  t1 = run_data[0]['tstart']
475  t2 = run_data[0]['tstop']
476  spills = spills_between(t1,t2)
477  npot = pot_between(t1,t2,spills)
478 
479  print run,t1,t2,(t2-t1),npot
480 
481 
482 #.......................................................................
483 
484 
485 def downtime_report(day,runs,spills):
486  """
487  """
488  daystart = day
489  dayend = day + timedelta(days=1)
490 
491  lastrun = 0
492  tstop = daystart
493  for r in runs:
494  #
495  # Compute the time difference between the last run stop and
496  # the current run start
497  #
498  run = r['run']
499  tstart = r['tstart']
500  dt = (tstart-tstop)
501 
502  if (dt>DOWNTIME_MIN):
503  pot = pot_between(tstop,tstart,spills)
504  print lastrun,'\t',run,'\t',tstop,'\t',tstart,'\t',dt,'\t',pot
505  #
506  # Save the stop time of this run
507  #
508  lastrun = run
509  tstop = r['tstop']
510  #
511  # Check for any downtime between last run and midnight
512  #
513  run = 0
514  tstart = dayend
515  dt = (tstart-tstop)
516  if (dt>DOWNTIME_MIN):
517  pot = pot_between(tstop,tstart,spills)
518  print lastrun,'\t',run,'\t',tstop,'\t',tstart,'\t',dt,'\t',pot
519 
520 #.......................................................................
521 
522 def usage():
523  """ Print how to use the program
524  """
525  print "Usage:";
526  print "% python nova-uptime.py -e mm/dd/YY -s /mm/dd/YY -n [#]"
527  print "Where:"
528  print "--neardet : Make summary for neardet (default is fardet)"
529  print "--testbeam : Make summary for testbeam (default is fardet)"
530  print "-d : Do the downtime report instead of uptime report"
531  print "-e : Last date to report"
532  print "-s : First date to report"
533  print "-n : Number of days to report"
534  print "-m : Minimum number of minutes to report in downtime mode"
535  print "-r : Make a report for specified run number"
536  print ""
537  print "Any combinated of s, e, and n may be used:"
538  print " -e 9/7/2013 -n 7 : Seven days ending on Sept. 7th, 2013"
539  print " -s 10/1/2013 -n 10 : Ten days starting on Oct. 1st, 2013"
540  print " -s 12/1/2013 -e 12/31/2013 : The entire month of December"
541  print ""
542  print " 'yesterday' and 'today' are a valid dates"
543  print ""
544  print "With nothing specified, default report is previous 7 days from yesterday."
545  print "";
546  print "In 'uptime' mode the data reported are:"
547  print " date,day,run start,run end,uptime in hrs,uptime frac.,1e12 POT recorded,1e12 POT delivered,POT frac."
548  print "";
549  print "In 'downtime' mode the data reported are:"
550  print " run last,run next,start of downtime,end of downtime,duration,1e12 POT lost"
551 
552 #.......................................................................
553 
554 def options():
555  """ Parse the command line options
556  Returns:
557  t1 (datetime) : First day to report
558  t2 (datetime) : Last day to report
559  n (int) : Number of days to report
560  """
561  global DO_DOWNTIME_REPORT
562  global DO_UPTIME_REPORT
563  global DO_RUN_POT_SUMMARY
564  global DOWNTIME_MIN
565  global DETECTOR
566 
567  date_start = None
568  date_end = None
569  ndays = None
570  try:
571  (opts, args) = getopt.getopt(sys.argv[1:],\
572  "hds:e:n:m:r:a:t",\
573  ["help",\
574  "downtime",\
575  "start=",\
576  "end=",\
577  "ndays=",\
578  "downtime_min",
579  "run=",
580  "neardet",
581  "testbeam"])
582  except getopt.GetoptError as err:
583  print str(err)
584  sys.exit(2)
585  for opt, arg in opts:
586  if opt in ("-h", "--help"):
587  usage()
588  exit(0)
589  elif opt in ("-d", "--downtime"):
590  DO_DOWNTIME_REPORT = True
591  DO_UPTIME_REPORT = False
592  elif opt in ("-s", "--start"):
593  date_start = arg
594  elif opt in ("-e", "--end"):
595  date_end = arg
596  elif opt in ("-n", "--ndays"):
597  ndays = int(arg)
598  elif opt in ("-r", "--run"):
599  DO_RUN_POT_SUMMARY = int(arg)
600  return (0,0,0)
601  elif opt in ("-m", "--downtime_min"):
602  DOWNTIME_MIN = timedelta(minutes=int(arg))
603  elif opt in ("-a", "--neardet"):
604  DETECTOR = 'neardet'
605  elif opt in ("-t", "--testbeam"):
606  DETECTOR = 'testbeam'
607  else:
608  assert False, "unknown option"
609  #
610  # If no options are given, default to most recent 7 days ending on
611  #"yesterday"
612  #
613  if ((date_start==None) & (date_end==None) & (ndays==None)):
614  ndays = 7
615  t0 = datetime.utcnow()
616  t0 -= timedelta(days=ndays)
617  t0 = t0.replace(hour=0, minute=0, second=0, microsecond=0)
618  t1 = t0
619  t1 += timedelta(days=ndays)
620  return (t0, t1, ndays)
621  #
622  # Convert start and end date text to datetime object
623  #
624  if (date_start!=None):
625  if (date_start=='yesterday'):
626  t0 = datetime.utcnow()
627  t0 -= timedelta(days=1)
628  t0 = t0.replace(hour=0, minute=0, second=0, microsecond=0)
629  elif (date_start=='today'):
630  t0 = datetime.utcnow()
631  t0 = t0.replace(hour=0, minute=0, second=0, microsecond=0)
632  else:
633  t0 = datetime.strptime(date_start,'%m/%d/%Y')
634  if (date_end!=None):
635  if (date_end=='yesterday'):
636  t1 = datetime.utcnow()
637  t1 -= timedelta(days=1)
638  t1 = t1.replace(hour=0, minute=0, second=0, microsecond=0)
639  elif (date_end=='today'):
640  t1 = datetime.utcnow()
641  t1 = t1.replace(hour=0, minute=0, second=0, microsecond=0)
642  else:
643  t1 = datetime.strptime(date_end,'%m/%d/%Y')
644 
645  #...................................................................
646  #
647  # Check the information I have, fill in blanks or check for
648  # internal consistency
649  #
650  if ((date_start==None)&(date_end!=None)&(ndays!=None)):
651  #
652  # Need to supply a start time
653  #
654  t0 = t1
655  t0 -= timedelta(days=(ndays-1))
656  if ((date_start==None)&(date_end!=None)&(ndays==None)):
657  #
658  # Need to supply a start time and a number of days
659  #
660  ndays = 7
661  t0 = t1
662  t0 -= timedelta(days=(ndays-1))
663  if ((date_start!=None)&(date_end==None)&(ndays!=None)):
664  #
665  # Need to supply an end time
666  #
667  t1 = t0
668  t1 += timedelta(days=ndays)
669  if ((date_start!=None)&(date_end!=None)&(ndays==None)):
670  #
671  # Need to supply a number of days
672  #
673  n = (t1-t0)+timedelta(days=1)
674  ndays = int(n.days)
675  if ((date_start!=None)&(date_end!=None)&(ndays!=None)):
676  #
677  # Have everything we need, but are they consistent?
678  #
679  d = (t1-t0)+timedelta(days=1)
680  n = int(d.days)
681  if (ndays != n):
682  print 'Inconsistent time range'
683  exit(2)
684 
685  return (t0, t1, ndays)
686 
687 #.......................................................................
688 #
689 # "Main" function
690 #
691 def main():
692  (t0, t1, ndays) = options()
693 
694  DB_NAME = os.environ['NOVADBNAME'] # 'nova_prod'
695  DB_HOST = os.environ['NOVADBHOST'] # 'ifdbrep.fnal.gov'
696  DB_USER = os.environ['NOVADBUSER'] # 'nova_reader'
697  DB_PASS = open(os.environ['NOVADBPWDFILE'], 'r').readlines()[0].strip()
698  DB_FAR_PORT = os.environ['NOVAFARDAQDBPORT'] # '5436'
699  DB_NEAR_PORT = os.environ['NOVANEARDAQDBPORT'] # '5434'
700 
701  if (DETECTOR=='fardet'):
702  try:
703  conn = psycopg2.connect(\
704  "dbname=%s host=%s user=%s password=%s port=%s" % \
705  (DB_NAME, DB_HOST, DB_USER, DB_PASS, DB_FAR_PORT))
706  except:
707  print "I am unable to connect to the database"
708  else:
709  try:
710  conn = psycopg2.connect(\
711  "dbname=%s host=%s user=%s password=%s port=%s" % \
712  (DB_NAME, DB_HOST, DB_USER, DB_PASS, DB_NEAR_PORT))
713  except:
714  print "I am unable to connect to the database"
715 
716  global DB_CURSOR
717  DB_CURSOR = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
718 
719  if (DO_RUN_POT_SUMMARY!=0):
720  run_pot_summary(DO_RUN_POT_SUMMARY)
721  return
722 
723  date0 = date( year=t0.year, month=t0.month, day=t0.day)
724  datetime0 = datetime(year=t0.year, month=t0.month, day=t0.day)
725 
726  weekdays = ['Mo','Tu','We','Th','Fr','Sa','Su']
727 
728  for i in range(0,ndays):
729  datei = date0 + timedelta(days=i)
730  datetimei = datetime0 + timedelta(days=i)
731  datetimef = datetimei + timedelta(days=1)
732 
733  #
734  # Get the complete list of runs for the day
735  #
736  runs = runs_by_day(datei)
737 
738  #
739  # Get the complete list of spills for the day
740  #
741  if (DETECTOR=='testbeam'):
742  spills = mc7_spills_between(datetimei, datetimef)
743  else:
744  spills = spills_between(datetimei, datetimef)
745 
746  #
747  # Compute the fraction of the day a run was going
748  #
749  r1 = 0
750  r2 = 0
751  uptime = 0
752  upfrac = 0
753  if (runs):
754  (r1,r2) = run_minmax(runs);
755  (uptime,upfrac) = compute_uptime(datetimei, runs)
756  #
757  # Compute how many protons were delivered and recorded
758  #
759  (pot_rec,pot_del) = compute_pot(datetimei, runs, spills)
760 
761  if (DO_DOWNTIME_REPORT):
762  downtime_report(datetimei, runs, spills)
763  #
764  # Compute the fraction of POT recorded. In cases where the POT
765  # delivered is zero, record the fraction recorded as the up time
766  # computed above.
767  #
768  pot_frac = 0.0
769  if (pot_del==0.0):
770  pot_frac = upfrac
771  else:
772  pot_frac = pot_rec/pot_del
773 
774  if (DO_UPTIME_REPORT):
775  print datei,",",\
776  weekdays[datei.weekday()],",",\
777  r1,",",\
778  r2,",",\
779  uptime,",",\
780  upfrac,",",\
781  pot_rec,",",\
782  pot_del,",",\
783  pot_frac;
784  print 'Completed summary for',DETECTOR
785  print 'Total time in IFBEAMs queries:',DB_QUERY_TIME
786 #.......................................................................
787 
788 if __name__ == "__main__":
789  main()
790 ########################################################################
791 
def nspills_between(t1, t2, spills)
Definition: nova_uptime.py:391
::xsd::cxx::tree::date< char, simple_type > date
Definition: Database.h:186
def options()
Definition: nova_uptime.py:554
def pot_between(t1, t2, spills)
Definition: nova_uptime.py:367
def spills_between(t1, t2)
Definition: nova_uptime.py:257
def runs_for_period(day0, day1)
Definition: nova_uptime.py:140
def in_unix(input)
Definition: nova_uptime.py:76
def nactive_chans(run)
Definition: nova_uptime.py:92
def compute_pot(day, runs, spills)
Definition: nova_uptime.py:415
def connect_to_database()
Definition: nova_uptime.py:52
std::string format(const int32_t &value, const int &ndigits=8)
Definition: HexUtils.cpp:14
procfile open("FD_BRL_v0.txt")
def run_minmax(runs)
Definition: nova_uptime.py:189
def run_at(day)
Definition: nova_uptime.py:110
def run_pot_summary(run)
Definition: nova_uptime.py:451
exit(0)
def mc7_spills_between(t1, t2)
Definition: nova_uptime.py:312
def runs_by_day(day0)
Definition: nova_uptime.py:172
def compute_uptime(day, runs)
Definition: nova_uptime.py:209
def downtime_report(day, runs, spills)
Definition: nova_uptime.py:485