14 from __future__
import with_statement, print_function
15 from CoolRunQuery.utils.AtlRunQueryTimer
import timer
17 import sys, os, time, re, calendar
18 from math
import exp,sqrt,pi
30 h = http.client.HTTP(p[1])
31 h.putrequest(
'HEAD', p[2])
33 if h.getreply()[0] == 200:
39 from CoolRunQuery.AtlRunQueryCOMA
import ARQ_COMA
40 s =
",".
join( ARQ_COMA.get_periods_for_run(runno) )
45 for number, name
in enumerate(names.split()):
46 setattr(self, name, number)
49 hostname = os.getenv(
'HOSTNAME')
50 print (
"Execution on host: %r" % hostname )
54 onserver = ( re.match(
r'aiatlas.*\.cern\.ch',hostname)
is not None )
55 print (
"Execution on server: %r" % onserver)
60 cmdline_args = sys.argv
65 ROOT.gROOT.SetBatch(batch)
68 ROOT.gErrorIgnoreLevel = 2000
74 """Converts a float to a string with appropriately placed commas"""
76 s =
"%.*f" % (width, n)
82 threes =
int((dec-1)/3)
83 for i
in range(threes):
85 s = s[:loc] + delim + s[loc:]
89 lst = duration_string.split()
93 sec +=
int(entry.replace(
's',
''))
95 sec +=
int(entry.replace(
'm',
''))*60
97 sec +=
int(entry.replace(
'h',
''))*3600
99 sec +=
int(entry.replace(
'd',
''))*3600*24
101 sec +=
int(entry.replace(
'w',
''))*3600*24*7
103 sec +=
int(entry.replace(
'y',
''))*3600*24*365
105 print (
'Big troubles... in function "AtlRunQueryUtils::durationInSeconds": cannot decode string "%s"' % entry)
115 """for example schema=COOLONL_TRIGGER', db='CONDBR2"""
119 if schema==
"DEFECTS":
122 defdb = DQDefects.DefectsDB(
"COOLOFL_GLOBAL/CONDBR2",tag=db)
123 defdb.closeDatabase =
lambda:
None
127 from CoolConvUtilities.AtlCoolLib
import indirectOpen
131 traceback.print_exc()
136 if key
not in self.
pw:
137 from os
import environ
as env
143 auth =
XMLReader(env[
'CORAL_AUTH_PATH']+
"/authentication.xml")
144 for c
in auth.connectionlist.connections:
147 self.
pw[key] = dict([(p[
'name'],p[
'value'])
for p
in c.parameters])
149 if key
not in self.
pw:
150 print (
"Can not authenticate DB",key)
157 auth = self.
get_auth(
'oracle://ATLAS_COOLPROD/ATLAS_COOLOFL_TRIGGER')
158 self.
openConn[
'run'] = cx_Oracle.connect(
"%s/%s@ATLAS_COOLPROD" % (auth[
'user'],auth[
'password']))
163 auth = self.
get_auth(
'oracle://ATLAS_CONFIG/ATLAS_SFO_T0_R')
164 with timer(
"Opening Connection to ATLAS_SFO_T0_R @ ATLAS_CONFIG"):
165 self.
openConn[
'sfo'] = cx_Oracle.connect(
"%s/%s@ATLAS_CONFIG" % (auth[
'user'],auth[
'password']))
170 auth = self.
get_auth(
'oracle://ATLAS_T0/ATLAS_T0')
171 self.
openConn[
'tier0'] = cx_Oracle.connect(
"%s/%s@ATLAS_T0" % (auth[
'user'],auth[
'password']))
176 auth = self.
get_auth(
'oracle://ATLAS_PVSSPROD/ATLAS_PVSS_READER')
177 self.
openConn[
'pvss'] = cx_Oracle.connect(
"%s/%s@ATLAS_PVSSPROD" % (auth[
'user'],auth[
'password']))
182 if isinstance(dbconn,cx_Oracle.Connection):
185 dbconn.closeDatabase()
192 if not gr[0].isdigit():
195 gr[0:1]=[gr[0][:-3],gr[0][-3:]]
196 return ','.
join(gr[1:])
201 if no > 0x4000000000000:
202 return "%1.1f PB" % (no*1.0/0x4000000000000)
203 if no > 0x10000000000:
204 return "%1.1f TB" % (no*1.0/0x10000000000)
206 return "%1.1f GB" % (no*1.0/0x40000000)
208 return "%1.1f MB" % (no*1.0/0x100000)
210 return "%1.1f kB" % (no*1.0/0x400)
212 return "%i B" % no
220 for rr
in listOfRanges:
221 if len(newRR)==0
or rr[0]-1>newRR[-1][1]:
222 newRR.append(
copy(rr))
224 newRR[-1] = [newRR[-1][0],
max(rr[1],newRR[-1][1]) ]
232 for rr
in listOfRanges:
233 if len(newRR)==0
or rr[0]>newRR[-1][1]:
234 newRR.append(
copy(rr))
236 newRR[-1] = (newRR[-1][0],
max(rr[1],newRR[-1][1]) )
246 for i
in range(rows):
248 for j
in range(cols):
253 self.
matrix[col-1][row-1] = v
256 return self.
matrix[col-1][row-1]
261 outStr +=
'Row %s = %s\n' % (i+1, self.
matrix[i])
267 yield (self.
matrix, row, col)
270 if re.match(
r"^\d+$",s):
276 t =
int(1E9*calendar.timegm(time.strptime(s,
"%d.%m.%Y")))
282 """ convert string into seconds since epoch
284 string is meant to be UTC time (hence we need calendar.timegm
285 and not time.mktime to convert the tuple into seconds)
287 format can be '1.5.2010_14:23:10', '1.5.2010 14:23:10', or '1.5.2010'
290 t = time.strptime(t,
"%d.%m.%Y")
293 t = time.strptime(t,
"%d.%m.%Y %H:%M:%S")
295 t = time.strptime(t,
"%d.%m.%Y_%H:%M:%S")
297 return int(calendar.timegm(t))
300 """ convert string into seconds since epoch
302 string is meant to be in local time (hence we use time.mktime
303 and not calender.timegm to convert the tuple into seconds)
305 format can be '1.5.2010_14:23:10', '1.5.2010 14:23:10', or '1.5.2010'
308 t = time.strptime(t,
"%d.%m.%Y")
311 t = time.strptime(t,
"%d.%m.%Y %H:%M:%S")
313 t = time.strptime(t,
"%d.%m.%Y_%H:%M:%S")
315 return int(time.mktime(t))
319 return time.strftime(
"%d.%m.%Y %H:%M:%S",time.gmtime(s))
324 return time.strftime(
"%d.%m.%Y %H:%M:%S",time.localtime(s))
328 def GetRanges(rangestr, intRepFnc=stringToIntOrTime, maxval=1<<30):
329 if type(rangestr)==list:
332 if rangestr[:4]==
'STR:':
333 return [ [rangestr[4:], rangestr[4:]] ]
334 ranges = rangestr.split(
',')
338 listOfRanges += [[0,maxval]]
339 elif not (
'-' in r
or '+' in r):
342 listOfRanges += [[x,x]]
344 listOfRanges += [[intRepFnc(r[:-1]),maxval]]
346 listOfRanges += [[0,intRepFnc(r[:-1])]]
348 startend = r.split(
'-')
350 raise RuntimeError (
"Range format error '%s'" % r)
351 listOfRanges += [[intRepFnc(x)
for x
in startend]]
359 time.strptime(s,
"%d.%m.")
360 year=
str(time.gmtime().tm_year)
361 return s+year+
"_00:00:00" if startofday
else s+year+
"_23:59:59"
364 time.strptime(s,
"%d.%m.%Y")
365 return s+
"_00:00:00" if startofday
else s+
"_23:59:59"
369 def GetTimeRanges(timeranges, intRepFnc=timeStringToSecondsUTC, maxval=1<<30):
370 if type(timeranges)==list:
371 timeranges =
','.
join(timeranges)
373 timeranges = timeranges.split(
',')
381 listOfRangesHR += [[
'0',
'inf']]
382 elif not (
'-' in r
or '+' in r):
392 start,end = r.split(
'-')
394 raise RuntimeError (
"Time format '%s' wrong, should be 'from-until'" % r)
398 listOfRangesHR += [[start,end]]
399 start = 0
if start==0
else intRepFnc(start)
400 end = maxval
if end==
'inf' else intRepFnc(end)
401 listOfRanges += [[start,end]]
407 if len(runlist) == 0:
409 if isinstance(runlist[0], list):
412 rr = [[r.runNr,r.runNr]
for r
in runlist]
414 rr = [[runlist[0].runNr,runlist[-1].runNr]]
421 packopt=dict([[1,
'B'],[2,
'H'],[4,
'f'],[8,
'd']])
424 fmt =
'%d%s' % (nval, packopt[nbyte])
425 ival=struct.unpack(fmt, b[0:nval*nbyte])
427 print (
'bConvertList: Unrecognized pack option')
436 beam2 = a[nb1:nb1+nb2]
442 return beam1, beam2, coll
450 for i
in range(3564):
456 if (val & 0x03) == 0x03:
462 return beam1, beam2, coll
478 print(
"Calling compute pileup with")
479 print(
" lumi_mb :", lumi_mb)
480 print(
" sigma :", sigma)
481 print(
" # bunches:", nbunch)
482 print(
" # fOrbit :", fOrbit)
489 nint = lumi_mb * sigma / fOrbit / nbunch
498 if n > 20
and p[-1] < 1e40:
507 return '<font color="red">ERROR: need at least 3 arguments for pileup calculation: inst.-lumi cross-section-in-mb nbunch [nevents]</font>'
509 fstarg =
float(args[0])
513 sigtrans =
float(args[1])
516 sigma =
float(args[2])
517 nbunch =
float(args[3])
518 lumi = nprotons**2 * fOrbit * nbunch / (4.0 * pi * sigtrans**2)
521 nevents =
float(args[4])
524 lumi =
float(args[0])
525 sigma =
float(args[1])
526 nbunch =
int(args[2])
529 nevents =
int(args[3])
533 nint, plist =
ComputePileup( lumi_mb, sigma, nbunch, fOrbit )
536 print(
" plist ",plist)
537 referenceInfo =
'7TeV: 60.3±2.1 mb'
538 referenceInfo +=
' [<a href="https://arxiv.org/abs/1104.0326" target="_blank" title="Measurement of the Inelastic Proton-Proton Cross Section at &sqrt;s=7 TeV with the ATLAS Detector at the LHC">arXiv:1104.0326</a>], '
539 referenceInfo +=
'13TeV: 78.1±2.9mb'
540 referenceInfo +=
' [<a href="https://arxiv.org/abs/1606.02625" target="_blank" title="Measurement of the Inelastic Proton-Proton Cross Section at &sqrt;s=13 TeV with the ATLAS Detector at the LHC">arXiv:1606.02625</a>]'
543 s +=
'<table class="datasettable" style="font-size: 140%">'
544 s +=
'<tr><td>Instantaneous luminosity :</td><td> %g cm−2s−1 (= %g mb−1s−1)</td></tr>' % (lumi, lumi_mb)
545 s +=
'<tr><td>Inelastic cross section :</td><td> %g mb (%s)</td></tr>' % (sigma, referenceInfo)
546 s +=
'<tr><td>Number of colliding bunches :</td><td> %g</td></tr>' % nbunch
547 s +=
'<tr><td colspan="2"><hr style="width:100%; #999999; background-color: #999999; height:1px; margin-left:0px; border:0"></td></tr>'
548 s +=
'<tr><td>Inelastic interaction rate:</td><td>%g Hz</td></tr>' % (lumi_mb*sigma)
549 s +=
'<tr><td>Average number of interactions per crossing: </td><td> %g</td></tr>' % nint
551 s +=
'<hr style="width:100%; #999999; background-color: #999999; height:0px; border:0">\n<p>\n'
553 s +=
'Very large pileup probability (assume Gaussian distribution): %g +- %g' % (nint, sqrt(nint))
555 s +=
'<table class="pileuptable">'
556 s +=
'<tr><th>Num. of interactions per filled bunch crossing</th><th>Probability per filled bunch crossing</th><th>Probability per triggered minimum bias event*</th>'
558 s +=
'<th>Expected number of events in sample*</th>'
563 for i,p
in enumerate(plist):
565 s +=
'<tr><td>>= %i</td><td>%g</td><td>%g</td>' % (i,1.0-psum,(1.0-psum)/pref)
567 nevexp = (1.0-psum)/pref*nevents
568 s +=
'<td> %g</td>' % (nevexp)
573 s +=
'</table><p></p>'
574 s +=
'<font size=-2>*assuming 100% trigger efficiency for inelastic events</font><br>'
579 return '<font color="red">ERROR: only numerical arguments allowed</font>'
587 return (runs[0],runs[0])
588 return (runs[0],runs[-1])
591 lt = last.replace(
'last',
'').strip()
593 start = time.gmtime( time.mktime(time.gmtime()) - nsec )
594 return get_runs(time.strftime(
"%d.%m.%Y_%H:%M:%S",start))
597 """start and end are given in the format '1.5.2010_14:23:10', '1.5.2010 14:23:10', or '1.5.2010'"""
599 co = coolDbConn.GetAtlasRunDBConnection()
604 records =
'RUNNUMBER'
607 starttime = time.strftime(
"%Y%m%dT%H%M%S",t)
610 q =
"SELECT %s FROM ATLAS_RUN_NUMBER.RUNNUMBER WHERE STARTAT>'%s' ORDER BY RUNNUMBER desc" % (records,starttime)
613 endtime = time.strftime(
"%Y%m%dT%H%M%S",t)
614 q =
"SELECT %s FROM ATLAS_RUN_NUMBER.RUNNUMBER WHERE STARTAT>'%s' and STARTAT<'%s' ORDER BY RUNNUMBER" % (records,starttime,endtime)
620 return [r[0]
for r
in res]
625 find all runs between two timestamps
626 start and end are given in the format '1.5.2010_14:23:10', '1.5.2010 14:23:10', or '1.5.2010'
635 co = coolDbConn.GetAtlasRunDBConnection()
642 start_gmtime = time.gmtime( start_seconds_utc )
643 start_fstring = time.strftime(
"%Y%m%dT%H%M%S", start_gmtime)
646 subq =
"SELECT MAX(RUNNUMBER) FROM ATLAS_RUN_NUMBER.RUNNUMBER WHERE STARTAT<'%s' AND PARTITIONNAME='ATLAS'" % start_fstring
647 q =
"select RUNNUMBER,STARTAT,DURATION from ATLAS_RUN_NUMBER.RUNNUMBER where RUNNUMBER=(%s)" % subq
650 run1,startat,duration = cu.fetchone()
652 startAtGmtime = time.strptime( startat,
"%Y%m%dT%H%M%S" )
653 startAtUtcSecond = calendar.timegm( startAtGmtime )
656 endAtUtcSecond = startAtUtcSecond + duration
673 if endAtUtcSecond < start_seconds_utc:
674 print(
"Run started and ended before the specified start time, so need to take the first one that started of the specified start time")
675 q =
"SELECT MIN(RUNNUMBER) FROM ATLAS_RUN_NUMBER.RUNNUMBER WHERE STARTAT>'%s' AND PARTITIONNAME='ATLAS'" % start_fstring
678 run1 = cu.fetchone()[0]
679 except cx_Oracle.Error:
681 except cx_Oracle.Error:
688 endtime = time.strftime(
"%Y%m%dT%H%M%S",start_gmtime)
689 q =
"SELECT MAX(RUNNUMBER) FROM ATLAS_RUN_NUMBER.RUNNUMBER WHERE STARTAT<'%s'" % endtime
691 run2 = cu.fetchone()[0]
709 return "<%s %s>" % (self.
tag,
" ".
join([
'%s="%s"' % x
for x
in self.
items()]))
714 raise KeyError (
"'%s'. XML element '%s' has attributes %s" % (k,self.
tag, self.
attributes.
keys()))
730 raise AttributeError (
"'%s'. XML element '%s' has tags %s" % (name,self.
tag, [
"%ss" % t
for t
in self.
childtags]))
734 import xml.etree.cElementTree
as ET
735 self.
doc = ET.parse(filename)
739 self.__dict__[root.tag] = root
742 raise AttributeError (
"'%s'. XML document '%s' has root tag '%s'" % (name,self.
__filename, self.
__root.tag))