14 from CoolRunQuery.utils.AtlRunQueryTimer
import timer
16 import sys, os, time, re, calendar
17 from math
import exp,sqrt,pi
29 h = http.client.HTTP(p[1])
30 h.putrequest(
'HEAD', p[2])
32 if h.getreply()[0] == 200:
38 from CoolRunQuery.AtlRunQueryCOMA
import ARQ_COMA
39 s =
",".
join( ARQ_COMA.get_periods_for_run(runno) )
44 for number, name
in enumerate(names.split()):
45 setattr(self, name, number)
48 hostname = os.getenv(
'HOSTNAME')
49 print (
"Execution on host: %r" % hostname )
53 onserver = ( re.match(
r'aiatlas.*\.cern\.ch',hostname)
is not None )
54 print (
"Execution on server: %r" % onserver)
59 cmdline_args = sys.argv
64 ROOT.gROOT.SetBatch(batch)
67 ROOT.gErrorIgnoreLevel = 2000
73 """Converts a float to a string with appropriately placed commas"""
75 s =
"%.*f" % (width, n)
81 threes =
int((dec-1)/3)
82 for i
in range(threes):
84 s = s[:loc] + delim + s[loc:]
88 lst = duration_string.split()
92 sec +=
int(entry.replace(
's',
''))
94 sec +=
int(entry.replace(
'm',
''))*60
96 sec +=
int(entry.replace(
'h',
''))*3600
98 sec +=
int(entry.replace(
'd',
''))*3600*24
100 sec +=
int(entry.replace(
'w',
''))*3600*24*7
102 sec +=
int(entry.replace(
'y',
''))*3600*24*365
104 print (
'Big troubles... in function "AtlRunQueryUtils::durationInSeconds": cannot decode string "%s"' % entry)
114 """for example schema=COOLONL_TRIGGER', db='CONDBR2"""
118 if schema==
"DEFECTS":
121 defdb = DQDefects.DefectsDB(
"COOLOFL_GLOBAL/CONDBR2",tag=db)
122 defdb.closeDatabase =
lambda:
None
126 from CoolConvUtilities.AtlCoolLib
import indirectOpen
130 traceback.print_exc()
135 if key
not in self.
pw:
136 from os
import environ
as env
142 auth =
XMLReader(env[
'CORAL_AUTH_PATH']+
"/authentication.xml")
143 for c
in auth.connectionlist.connections:
146 self.
pw[key] = dict([(p[
'name'],p[
'value'])
for p
in c.parameters])
148 if key
not in self.
pw:
149 print (
"Can not authenticate DB",key)
156 auth = self.
get_auth(
'oracle://ATLAS_COOLPROD/ATLAS_COOLOFL_TRIGGER')
157 self.
openConn[
'run'] = cx_Oracle.connect(
"%s/%s@ATLAS_COOLPROD" % (auth[
'user'],auth[
'password']))
162 auth = self.
get_auth(
'oracle://ATLAS_CONFIG/ATLAS_SFO_T0_R')
163 with timer(
"Opening Connection to ATLAS_SFO_T0_R @ ATLAS_CONFIG"):
164 self.
openConn[
'sfo'] = cx_Oracle.connect(
"%s/%s@ATLAS_CONFIG" % (auth[
'user'],auth[
'password']))
169 auth = self.
get_auth(
'oracle://ATLAS_T0/ATLAS_T0')
170 self.
openConn[
'tier0'] = cx_Oracle.connect(
"%s/%s@ATLAS_T0" % (auth[
'user'],auth[
'password']))
175 auth = self.
get_auth(
'oracle://ATLAS_PVSSPROD/ATLAS_PVSS_READER')
176 self.
openConn[
'pvss'] = cx_Oracle.connect(
"%s/%s@ATLAS_PVSSPROD" % (auth[
'user'],auth[
'password']))
181 if isinstance(dbconn,cx_Oracle.Connection):
184 dbconn.closeDatabase()
191 if not gr[0].isdigit():
194 gr[0:1]=[gr[0][:-3],gr[0][-3:]]
195 return ','.
join(gr[1:])
200 if no > 0x4000000000000:
201 return "%1.1f PB" % (no*1.0/0x4000000000000)
202 if no > 0x10000000000:
203 return "%1.1f TB" % (no*1.0/0x10000000000)
205 return "%1.1f GB" % (no*1.0/0x40000000)
207 return "%1.1f MB" % (no*1.0/0x100000)
209 return "%1.1f kB" % (no*1.0/0x400)
211 return "%i B" % no
219 for rr
in listOfRanges:
220 if len(newRR)==0
or rr[0]-1>newRR[-1][1]:
221 newRR.append(
copy(rr))
223 newRR[-1] = [newRR[-1][0],
max(rr[1],newRR[-1][1]) ]
231 for rr
in listOfRanges:
232 if len(newRR)==0
or rr[0]>newRR[-1][1]:
233 newRR.append(
copy(rr))
235 newRR[-1] = (newRR[-1][0],
max(rr[1],newRR[-1][1]) )
245 for i
in range(rows):
247 for j
in range(cols):
252 self.
matrix[col-1][row-1] = v
255 return self.
matrix[col-1][row-1]
260 outStr +=
'Row %s = %s\n' % (i+1, self.
matrix[i])
266 yield (self.
matrix, row, col)
269 if re.match(
r"^\d+$",s):
275 t =
int(1E9*calendar.timegm(time.strptime(s,
"%d.%m.%Y")))
281 """ convert string into seconds since epoch
283 string is meant to be UTC time (hence we need calendar.timegm
284 and not time.mktime to convert the tuple into seconds)
286 format can be '1.5.2010_14:23:10', '1.5.2010 14:23:10', or '1.5.2010'
289 t = time.strptime(t,
"%d.%m.%Y")
292 t = time.strptime(t,
"%d.%m.%Y %H:%M:%S")
294 t = time.strptime(t,
"%d.%m.%Y_%H:%M:%S")
296 return int(calendar.timegm(t))
299 """ convert string into seconds since epoch
301 string is meant to be in local time (hence we use time.mktime
302 and not calender.timegm to convert the tuple into seconds)
304 format can be '1.5.2010_14:23:10', '1.5.2010 14:23:10', or '1.5.2010'
307 t = time.strptime(t,
"%d.%m.%Y")
310 t = time.strptime(t,
"%d.%m.%Y %H:%M:%S")
312 t = time.strptime(t,
"%d.%m.%Y_%H:%M:%S")
314 return int(time.mktime(t))
318 return time.strftime(
"%d.%m.%Y %H:%M:%S",time.gmtime(s))
323 return time.strftime(
"%d.%m.%Y %H:%M:%S",time.localtime(s))
327 def GetRanges(rangestr, intRepFnc=stringToIntOrTime, maxval=1<<30):
328 if type(rangestr)==list:
331 if rangestr[:4]==
'STR:':
332 return [ [rangestr[4:], rangestr[4:]] ]
333 ranges = rangestr.split(
',')
337 listOfRanges += [[0,maxval]]
338 elif not (
'-' in r
or '+' in r):
341 listOfRanges += [[x,x]]
343 listOfRanges += [[intRepFnc(r[:-1]),maxval]]
345 listOfRanges += [[0,intRepFnc(r[:-1])]]
347 startend = r.split(
'-')
349 raise RuntimeError (
"Range format error '%s'" % r)
350 listOfRanges += [[intRepFnc(x)
for x
in startend]]
358 time.strptime(s,
"%d.%m.")
359 year=
str(time.gmtime().tm_year)
360 return s+year+
"_00:00:00" if startofday
else s+year+
"_23:59:59"
363 time.strptime(s,
"%d.%m.%Y")
364 return s+
"_00:00:00" if startofday
else s+
"_23:59:59"
368 def GetTimeRanges(timeranges, intRepFnc=timeStringToSecondsUTC, maxval=1<<30):
369 if type(timeranges)==list:
370 timeranges =
','.
join(timeranges)
372 timeranges = timeranges.split(
',')
380 listOfRangesHR += [[
'0',
'inf']]
381 elif not (
'-' in r
or '+' in r):
391 start,end = r.split(
'-')
393 raise RuntimeError (
"Time format '%s' wrong, should be 'from-until'" % r)
397 listOfRangesHR += [[start,end]]
398 start = 0
if start==0
else intRepFnc(start)
399 end = maxval
if end==
'inf' else intRepFnc(end)
400 listOfRanges += [[start,end]]
406 if len(runlist) == 0:
408 if isinstance(runlist[0], list):
411 rr = [[r.runNr,r.runNr]
for r
in runlist]
413 rr = [[runlist[0].runNr,runlist[-1].runNr]]
420 packopt=dict([[1,
'B'],[2,
'H'],[4,
'f'],[8,
'd']])
423 fmt =
'%d%s' % (nval, packopt[nbyte])
424 ival=struct.unpack(fmt, b[0:nval*nbyte])
426 print (
'bConvertList: Unrecognized pack option')
435 beam2 = a[nb1:nb1+nb2]
441 return beam1, beam2, coll
449 for i
in range(3564):
455 if (val & 0x03) == 0x03:
461 return beam1, beam2, coll
477 print(
"Calling compute pileup with")
478 print(
" lumi_mb :", lumi_mb)
479 print(
" sigma :", sigma)
480 print(
" # bunches:", nbunch)
481 print(
" # fOrbit :", fOrbit)
488 nint = lumi_mb * sigma / fOrbit / nbunch
497 if n > 20
and p[-1] < 1e40:
506 return '<font color="red">ERROR: need at least 3 arguments for pileup calculation: inst.-lumi cross-section-in-mb nbunch [nevents]</font>'
508 fstarg =
float(args[0])
512 sigtrans =
float(args[1])
515 sigma =
float(args[2])
516 nbunch =
float(args[3])
517 lumi = nprotons**2 * fOrbit * nbunch / (4.0 * pi * sigtrans**2)
520 nevents =
float(args[4])
523 lumi =
float(args[0])
524 sigma =
float(args[1])
525 nbunch =
int(args[2])
528 nevents =
int(args[3])
532 nint, plist =
ComputePileup( lumi_mb, sigma, nbunch, fOrbit )
535 print(
" plist ",plist)
536 referenceInfo =
'7TeV: 60.3±2.1 mb'
537 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>], '
538 referenceInfo +=
'13TeV: 78.1±2.9mb'
539 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>]'
542 s +=
'<table class="datasettable" style="font-size: 140%">'
543 s +=
'<tr><td>Instantaneous luminosity :</td><td> %g cm−2s−1 (= %g mb−1s−1)</td></tr>' % (lumi, lumi_mb)
544 s +=
'<tr><td>Inelastic cross section :</td><td> %g mb (%s)</td></tr>' % (sigma, referenceInfo)
545 s +=
'<tr><td>Number of colliding bunches :</td><td> %g</td></tr>' % nbunch
546 s +=
'<tr><td colspan="2"><hr style="width:100%; #999999; background-color: #999999; height:1px; margin-left:0px; border:0"></td></tr>'
547 s +=
'<tr><td>Inelastic interaction rate:</td><td>%g Hz</td></tr>' % (lumi_mb*sigma)
548 s +=
'<tr><td>Average number of interactions per crossing: </td><td> %g</td></tr>' % nint
550 s +=
'<hr style="width:100%; #999999; background-color: #999999; height:0px; border:0">\n<p>\n'
552 s +=
'Very large pileup probability (assume Gaussian distribution): %g +- %g' % (nint, sqrt(nint))
554 s +=
'<table class="pileuptable">'
555 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>'
557 s +=
'<th>Expected number of events in sample*</th>'
562 for i,p
in enumerate(plist):
564 s +=
'<tr><td>>= %i</td><td>%g</td><td>%g</td>' % (i,1.0-psum,(1.0-psum)/pref)
566 nevexp = (1.0-psum)/pref*nevents
567 s +=
'<td> %g</td>' % (nevexp)
572 s +=
'</table><p></p>'
573 s +=
'<font size=-2>*assuming 100% trigger efficiency for inelastic events</font><br>'
578 return '<font color="red">ERROR: only numerical arguments allowed</font>'
586 return (runs[0],runs[0])
587 return (runs[0],runs[-1])
590 lt = last.replace(
'last',
'').strip()
592 start = time.gmtime( time.mktime(time.gmtime()) - nsec )
593 return get_runs(time.strftime(
"%d.%m.%Y_%H:%M:%S",start))
596 """start and end are given in the format '1.5.2010_14:23:10', '1.5.2010 14:23:10', or '1.5.2010'"""
598 co = coolDbConn.GetAtlasRunDBConnection()
603 records =
'RUNNUMBER'
606 starttime = time.strftime(
"%Y%m%dT%H%M%S",t)
609 q =
"SELECT %s FROM ATLAS_RUN_NUMBER.RUNNUMBER WHERE STARTAT>'%s' ORDER BY RUNNUMBER desc" % (records,starttime)
612 endtime = time.strftime(
"%Y%m%dT%H%M%S",t)
613 q =
"SELECT %s FROM ATLAS_RUN_NUMBER.RUNNUMBER WHERE STARTAT>'%s' and STARTAT<'%s' ORDER BY RUNNUMBER" % (records,starttime,endtime)
619 return [r[0]
for r
in res]
624 find all runs between two timestamps
625 start and end are given in the format '1.5.2010_14:23:10', '1.5.2010 14:23:10', or '1.5.2010'
634 co = coolDbConn.GetAtlasRunDBConnection()
641 start_gmtime = time.gmtime( start_seconds_utc )
642 start_fstring = time.strftime(
"%Y%m%dT%H%M%S", start_gmtime)
645 subq =
"SELECT MAX(RUNNUMBER) FROM ATLAS_RUN_NUMBER.RUNNUMBER WHERE STARTAT<'%s' AND PARTITIONNAME='ATLAS'" % start_fstring
646 q =
"select RUNNUMBER,STARTAT,DURATION from ATLAS_RUN_NUMBER.RUNNUMBER where RUNNUMBER=(%s)" % subq
649 run1,startat,duration = cu.fetchone()
651 startAtGmtime = time.strptime( startat,
"%Y%m%dT%H%M%S" )
652 startAtUtcSecond = calendar.timegm( startAtGmtime )
655 endAtUtcSecond = startAtUtcSecond + duration
672 if endAtUtcSecond < start_seconds_utc:
673 print(
"Run started and ended before the specified start time, so need to take the first one that started of the specified start time")
674 q =
"SELECT MIN(RUNNUMBER) FROM ATLAS_RUN_NUMBER.RUNNUMBER WHERE STARTAT>'%s' AND PARTITIONNAME='ATLAS'" % start_fstring
677 run1 = cu.fetchone()[0]
678 except cx_Oracle.Error:
680 except cx_Oracle.Error:
687 endtime = time.strftime(
"%Y%m%dT%H%M%S",start_gmtime)
688 q =
"SELECT MAX(RUNNUMBER) FROM ATLAS_RUN_NUMBER.RUNNUMBER WHERE STARTAT<'%s'" % endtime
690 run2 = cu.fetchone()[0]
708 return "<%s %s>" % (self.
tag,
" ".
join([
'%s="%s"' % x
for x
in self.
items()]))
713 raise KeyError (
"'%s'. XML element '%s' has attributes %s" % (k,self.
tag, self.
attributes.
keys()))
729 raise AttributeError (
"'%s'. XML element '%s' has tags %s" % (name,self.
tag, [
"%ss" % t
for t
in self.
childtags]))
733 import xml.etree.ElementTree
as ET
734 self.
doc = ET.parse(filename)
738 self.__dict__[root.tag] = root
741 raise AttributeError (
"'%s'. XML document '%s' has root tag '%s'" % (name,self.
__filename, self.
__root.tag))