9 from datetime
import date, datetime, timedelta
11 import psycopg2.extras
14 BASE_DIR = os.getcwd()
15 filename =
'MCenterSpills.root' 19 DB_QUERY_TIME = timedelta(0)
26 print "python MCenterSpills.py -s YYYY-mm-dd -e YYYY-mm-dd -n #" 29 print "-s : start date" 31 print "-n : number of days" 33 print "You can specify any 2 of the above 3 options. The third will be calculated for you." 34 print "There is no default, you must supply options" 36 print "Creates root file with date, first and last run, number of recorded spills, and recorded POT [counts] for each day." 40 """ Parse the command line options 42 t1 (datetime) : First day to report 43 t2 (datetime) : Last day to report 44 n (int) : Number of days to report 53 (opts, args) = getopt.getopt(sys.argv[1:],\
59 except getopt.GetoptError
as err:
63 if opt
in (
"-h",
"--help"):
67 elif opt
in (
"-s",
"--start"):
69 elif opt
in (
"-e",
"--end"):
71 elif opt
in (
"-n",
"--ndays"):
74 assert False,
"unknown option" 77 if (date_start!=
None):
78 t0 = datetime.strptime(date_start,
'%Y-%m-%d')
80 t1 = datetime.strptime(date_end,
'%Y-%m-%d')
83 if ((date_start==
None)&(date_end!=
None)&(ndays!=
None)):
85 t0 -= timedelta(days=(ndays-1))
88 if ((date_start!=
None)&(date_end==
None)&(ndays!=
None)):
90 t1 += timedelta(days=ndays)
93 if ((date_start!=
None)&(date_end!=
None)&(ndays==
None)):
94 n = (t1-t0)+timedelta(days=1)
97 if ((date_start!=
None)&(date_end!=
None)&(ndays!=
None)):
101 d = (t1-t0)+timedelta(days=1)
104 print 'Inconsistent time range' 112 """ Get a complete list of run numbers for a specified day 114 Any run that starts or stops on the specified date is contaned in 118 day0: A datetime object for the requested day 121 An list of SQL results for run,tstart,tstop ordered by start time 123 day1 = day0+timedelta(days=1)
129 """ Get all runs that start or stop within a particular date range 132 day0 : A datetime object for first day 133 day1 : A datetime object for the last day 135 sql0 =
"select run,tstart,tstop from "+DETECTOR+
".runs";
136 cut1 =
" where partition=1";
137 cut2 =
" tstop is not null" 138 cut3 =
"tstart >= '{}'".
format(day0.strftime(
"%Y-%m-%dT%H:%M:%S"))
139 cut4 =
"tstart < '{}'".
format(day1.strftime(
"%Y-%m-%dT%H:%M:%S"))
141 cut5 =
"tstop >= '{}'".
format(day0.strftime(
"%Y-%m-%dT%H:%M:%S"))
142 cut6 =
"tstop < '{}'".
format(day1.strftime(
"%Y-%m-%dT%H:%M:%S"))
144 sql1 =
"order by tstart asc" 150 "((" + cut3+
" and "+cut4+
") or ("+cut5+
" and "+cut6+
")) " + \
154 DB_CURSOR.execute(SQL);
155 runs = DB_CURSOR.fetchall();
162 """ Find the highest and lowest run number in a list 165 runs: A list of SQL results (run,tstart,tstop) 168 (runlo,runhi), the lowest and highest run numbers in the list 170 runmin = runs[0][
'run']
171 runmax = runs[0][
'run']
173 if (r[
'run']<runmin):
175 if (r[
'run']>runmax):
177 return (runmin,runmax)
183 Return spill information (unix time and POT) for a datetime range 186 t1 (datetime): Start time 187 t2 (datetime): End time 190 List of (time,pot) tuples 198 webaddress =
'http://ifb-data.fnal.gov:8099'\
199 '/ifbeam/data/data?'\
200 'v=F:MC7SC1&e=e,36&t0={}&t1={}&&f=csv'.\
207 t0 = datetime.utcnow()
209 dd = urllib2.urlopen(webaddress,
None,600)
212 dd = urllib2.urlopen(webaddress,
None,600)
215 dd = urllib2.urlopen(webaddress,
None,600)
218 t1 = datetime.utcnow()
220 DB_QUERY_TIME += (t1-t0)
225 csvdata = csv.reader(dd)
228 if (row.count(
'F:MC7SC1')>0):
230 spills.append( (
float(row[2])/1000.,
float(row[4])) )
237 """ Tally the protons on target delivered and recorded in a day 240 day : datetime of day of interest 241 runs (sql) : SQL set of runs (run, tstart, tend) 242 spills (list[(time,pot)]) : Complete list of spills for time period 245 (pot_recorded,pot_delivered) (float,float) 248 dayend = day + timedelta(days=1)
250 pot_delivered =
pot_between(daystart,dayend,spills)
270 return (pot_recorded,pot_delivered,spills_recorded)
275 """ Compute the POT recorded between two time stamps. 278 t1 (datetime) : Start time 279 t2 (datetime) : End time 280 spills ( list[(time,pot)]) : Complete list of spills for time period 283 pot (float) : Scintillator counts 291 if (t>=tf1)&(t<=tf2):
299 """ Compute the POT recorded between two time stamps. 302 t1 (datetime) : Start time 303 t2 (datetime) : End time 304 spills ( list[(time,pot)]) : Complete list of spills for time period 307 pot (float) : scintillator counts 315 if (t>=tf1)&(t<=tf2):
323 """ Convert a datetime to UNIX time 326 input: A datetime object 329 A floating points number of seconds since Jan. 1, 1970 (UNIX standard) 332 start = datetime(year=1970,month=1,day=1,hour=0,minute=0,second=0)
334 return diff.total_seconds()
347 from ROOT
import TFile, TTree
348 from ROOT
import gROOT, AddressOf
350 file = TFile(BASE_DIR+
"/"+filename,
'RECREATE')
352 gROOT.ProcessLine(
"struct BeamStruct {Double_t Date; Int_t spills_rec; Double_t pot_rec; Int_t run_low; Int_t run_high;};")
353 from ROOT
import BeamStruct
354 beamStruct = BeamStruct()
355 tree = TTree(
'BeamMetrics',
'POTtree')
356 tree.Branch(
'Date',AddressOf(beamStruct,
'Date'),
'Date/D')
357 tree.Branch(
'spills_rec',AddressOf(beamStruct,
'spills_rec'),
'spills_rec/I')
358 tree.Branch(
'pot_rec', AddressOf(beamStruct,
'pot_rec'),
'pot_rec/D')
359 tree.Branch(
'run_low',AddressOf(beamStruct,
'run_low'),
'run_low/I')
360 tree.Branch(
'run_high',AddressOf(beamStruct,
'run_high'),
'run_high/I')
364 DB_NAME = os.environ[
'NOVADBNAME']
365 DB_HOST = os.environ[
'NOVADBHOST']
366 DB_USER = os.environ[
'NOVADBUSER']
367 DB_PASS =
open(os.environ[
'NOVADBPWDFILE'],
'r').readlines()[0].strip() 368 DB_PORT = os.environ['NOVANEARDAQDBPORT']
371 conn = psycopg2.connect(\
372 "dbname=%s host=%s user=%s password=%s port=%s" % \
373 (DB_NAME, DB_HOST, DB_USER, DB_PASS, DB_PORT))
375 print "I am unable to connect to the database" 378 DB_CURSOR = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
381 date0 =
date( year=t0.year, month=t0.month, day=t0.day)
382 datetime0 = datetime(year=t0.year, month=t0.month, day=t0.day)
386 for i
in range(0,ndays):
387 datei = date0 + timedelta(days=i)
388 datetimei = datetime0 + timedelta(days=i)
389 datetimef = datetimei + timedelta(days=1)
391 unixi = (datetimei - datetime(1970,1,1)).total_seconds()+1
410 (pot_rec,pot_del,num_spill_rec) =
compute_pot(datetimei, runs, spills)
422 beamStruct.Date = unixi
423 beamStruct.spills_rec = num_spill_rec
424 beamStruct.pot_rec = pot_rec
425 beamStruct.run_low = r1
426 beamStruct.run_high = r2
434 if __name__ ==
"__main__":
def pot_between(t1, t2, spills)
::xsd::cxx::tree::date< char, simple_type > date
def compute_pot(day, runs, spills)
def runs_for_period(day0, day1)
def mc7_spills_between(t1, t2)
def spills_between(t1, t2, spills)
std::string format(const int32_t &value, const int &ndigits=8)
procfile open("FD_BRL_v0.txt")