ATLAS Offline Software
Loading...
Searching...
No Matches
AtlRunQueryXML.py
Go to the documentation of this file.
1#!/usr/env python
2
3# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
4#
5# ----------------------------------------------------------------
6# Script : AtlRunQueryXML.py
7# Project: AtlRunQuery
8# Purpose: XML file output of good run lists
9# Authors: Andreas Hoecker (CERN), Joerg Stelzer (DESY)
10# Created: May 6, 2009
11# ----------------------------------------------------------------
12#
13# ---------------------------------------------------------------------------------------------------
14# XML making
15# ---------------------------------------------------------------------------------------------------
16
17from CoolRunQuery.utils.AtlRunQueryTimer import timer
18
19import datetime, sys
20from xml.dom.minidom import Document, DocumentType, Element
21from CoolRunQuery.utils.AtlRunQueryUtils import prettyNumber
22
23# ---------------------------------------------------------------------------------------------------
24# Creation of XML output file
25# ---------------------------------------------------------------------------------------------------
26
27# This is an Element, but does not print sub-elements. It is designed
28# to hold attributes and CharacterData, and prints everything in one
29# line (unlike Element.writexml(), which always adds a 'newline'
30class TextElement(Element):
31 def __init__(self,name,data,doc):
32 Element.__init__(self,name)
33 if not isinstance(data, str):
34 raise TypeError ("node contents must be a string")
35 self.tagName = name
36 self.data = data
37 self.ownerDocument = doc
38 self.attOrder = []
39
40 def setAttribute(self, attname, value):
41 if attname not in self.attOrder:
42 self.attOrder += [attname]
43 Element.setAttribute(self, attname, value)
44
45 def writexml(self, writer, indent="", addindent="", newl=""):
46 attrs = self._get_attributes()
47 atstr = ''
48 for a_name in self.attOrder:
49 atstr += ' %s="%s"' % (a_name, attrs[a_name].value)
50
51 if self.data:
52 writer.write("%s<%s%s>%s</%s>%s" % (indent, self.tagName, atstr, self.data, self.tagName, newl ) )
53 else:
54 writer.write("%s<%s%s/>%s" % (indent, self.tagName, atstr, newl ) )
55
57
58 # open SFO DB connection
59 from CoolRunQuery.utils.AtlRunQueryUtils import coolDbConn
60 from CoolRunQuery.AtlRunQuerySFO import GetSFO_NeventsAllPhysics
61
62 cursor = coolDbConn.GetSFODBConnection().cursor()
63 cursor.arraysize=1000
64
65 # find streams
66 runnrlist = [r.runNr for r in runlist]
67 with timer('get SFO number of events AllPhysics'):
68 runstreamevents = GetSFO_NeventsAllPhysics( cursor, runnrlist ) # { runnr: { stream: [(LUMIBLOCKNR, NREVENTS)] } }
69 return runstreamevents, ",".join(['%i' % r for r in runnrlist])
70
71
72
73def CreateXMLFile( runlist, options, origQuery, datapath, xmlfname, xmllabel, svnversion='Unknown' ):
74 """
75 """
76
77
78 with timer('create RunStreamAndNeventsList'):
79
80 # show number of events per stream per run ?
81 ShowNumberOfEventsPerStreamPerRun = False
82 ShowNumberOfEventsPerStreamSummary = True
83
84
85 # find streams
86 runstreamevents, runnrliststr = CreateRunStreamAndNeventsList( runlist ) # { runnr: { stream: [(LUMIBLOCKNR, NREVENTS)] } }
87
88 with timer('prepare document'):
89
90
91
92
93
94
95 doc = Document()
96
97 docType = DocumentType('LumiRangeCollection')
98 docType.systemId = 'http://atlas-runquery.cern.ch/LumiRangeCollection.dtd'
99 doc.appendChild(docType)
100
101 # number of comments
102 txt = ' Good-runs-list created by %s on %s ' % (sys.argv[0].split('/')[-1], str(datetime.datetime.now()))
103 doc.appendChild( doc.createComment( txt ) )
104
105 # root element
106 lrc = doc.createElement('LumiRangeCollection')
107 doc.appendChild(lrc)
108
109 # NamedLumiRange
110 namedLR = doc.createElement('NamedLumiRange')
111 lrc.appendChild(namedLR)
112
113 # name of NamedLumiRange
114 namedLR.appendChild(TextElement('Name',xmllabel,doc))
115
116 # version of NamedLumiRange
117 namedLR.appendChild(TextElement('Version','2.1',doc))
118
119 # metadata of NamedLumiRange
120 metadata = {
121 'Query' : origQuery.split('/')[0],
122 'RQTSVNVersion' : svnversion,
123 'RunList' : runnrliststr
124 }
125
126 for md in metadata:
127 mdelm = TextElement('Metadata', metadata[md], doc)
128 mdelm.setAttribute('Name', md)
129 namedLR.appendChild(mdelm)
130
131 with timer('ShowNumberOfEventsPerStreamSummary'):
132 if ShowNumberOfEventsPerStreamSummary:
133 strsummdelm = doc.createElement('Metadata')
134 strsummdelm.setAttribute('Name','StreamListInfo')
135 namedLR.appendChild(strsummdelm)
136
137
138 # lumiblock collections of NamedLumiRange
139 streams_sum = {}
140 streams_byrun = {}
141 with timer('Loop over all runs'):
142 for run in runlist:
143 lbc = doc.createElement('LumiBlockCollection')
144 # run number
145 runnrelm = TextElement('Run',str(run.runNr),doc)
146
147
148 if len(run.stats['SMK']['random'])==2:
149 (rd0,rd1) = run.stats['SMK']['random'][0:2]
150 # protect against missing information
151 if rd0 == 'n.a.':
152 rd0 = 0
153 if rd1 == 'n.a.':
154 rd1 = 0
155 runnrelm.setAttribute('PrescaleRD0',0x1<<(3+rd0))
156 runnrelm.setAttribute('PrescaleRD1',0x1<<(3+rd1))
157 else:
158 (rd0,rd1,rd2,rd3) = run.stats['SMK']['random'][0:4]
159 # protect against missing information
160 if rd0 == 'n.a.':
161 rd0 = 0
162 if rd1 == 'n.a.':
163 rd1 = 0
164 if rd2 == 'n.a.':
165 rd2 = 0
166 if rd3 == 'n.a.':
167 rd3 = 0
168 runnrelm.setAttribute('Cut0', rd0)
169 runnrelm.setAttribute('Cut1', rd1)
170 runnrelm.setAttribute('Cut2', rd2)
171 runnrelm.setAttribute('Cut3', rd3)
172
173 lbc.appendChild(runnrelm)
174
175 # streams (initialisation)
176 streams = {}
177 streams_byrun[run.runNr] = streams
178 if run.runNr in runstreamevents: # protection in case the run does not have any stream
179 for stream in runstreamevents[run.runNr].keys():
180 if 'physics_' == stream[:8]:
181 streams[stream] = [0,0] # only for physics streams
182 if stream not in streams_sum:
183 streams_sum[stream] = [0,0]
184 # total number of events in stream
185 for (nlb,nev) in runstreamevents[run.runNr][stream]:
186 streams[stream][0] += nev
187
188 # lumiblock ranges
189
190 for lbrange in run.data.getLBRanges(activeOnly=True):
191 lbrelm = TextElement('LBRange','',doc)
192 lbrelm.setAttribute('Start',lbrange[1])
193 lbrelm.setAttribute('End',lbrange[2]-1)
194 lbc.appendChild(lbrelm)
195 # count nevents in streams
196 if run.runNr in runstreamevents: # protection in case the run does not have any stream
197 for stream, lbnevts in runstreamevents[run.runNr].items():
198 if 'physics_' == stream[:8]:
199 for (nlb,nev) in lbnevts:
200 if nlb>=lbrange[1] and nlb<lbrange[2]:
201 streams[stream][1] += nev
202
203 # append stream element
204 strselm = doc.createElement('StreamsInRun')
205
206 for stream in sorted (streams.keys()):
207 nevts = streams[stream]
208 if ShowNumberOfEventsPerStreamPerRun:
209 strelm = TextElement('Stream','',doc)
210 strelm.setAttribute('Name', stream)
211 strelm.setAttribute('TotalNumOfEvents', nevts[0])
212 strelm.setAttribute('NumOfSelectedEvents', nevts[1])
213 strselm.appendChild(strelm)
214 eff = 0
215 if nevts[0] > 0:
216 eff = nevts[1]/float(nevts[0])*100.0
217
218 # collect total number of events
219 streams_sum[stream][0] += nevts[0]
220 streams_sum[stream][1] += nevts[1]
221
222 # append streams
223 if ShowNumberOfEventsPerStreamPerRun:
224 lbc.appendChild(strselm)
225
226 # append LumiBlickCollection
227 namedLR.appendChild(lbc)
228
229 with timer('Streams'):
230 for stream in sorted(streams_sum.keys()):
231 nevts = streams_sum[stream]
232 if ShowNumberOfEventsPerStreamSummary:
233 strelm = TextElement('Stream','',doc)
234 strelm.setAttribute('Name', stream)
235 strelm.setAttribute('TotalNumOfEvents', nevts[0])
236 strelm.setAttribute('NumOfSelectedEvents', nevts[1])
237 strsummdelm.appendChild(strelm)
238
239
240 with timer('Save GRL'):
241
242 filename = '%s/%s' % (datapath, xmlfname)
243 #print "Writing",filename
244 xmlfile = open( filename, mode="w" )
245 xmlfile.write( doc.toprettyxml(' ') )
246 xmlfile.close()
247
248 with timer('Create HTML'):
249
250
251
252
253
254
255
256 # provide also pretty html text output
257 htmltext = ''
258 htmltext += '<table style=&quot;width: auto; border: 0px solid; border-width: margin: 0 0 0 0; 0px; border-spacing: 0px; border-collapse: separate; padding: 0px;&quot; font-family: sans-serif; font-size: 85%%&quot;>\n'
259 htmltext += '<tr><td colspan=&quot;2&quot;><b><font color=&quot;#999999&quot;>' + txt.strip() + '</font></b></td></tr>\n'
260 htmltext += '<tr><td style=&quot;vertical-align:top&quot;>SVN&nbsp;Version: </td><td> ' + svnversion + '</td></tr>\n'
261 htmltext += '<tr><td style=&quot;vertical-align:top&quot;>Query&nbsp;string:</td><td><b>' + origQuery.split('/')[0] + '</b></td></tr>\n'
262 htmltext += '<tr><td style=&quot;vertical-align:top&quot;>Run list:</td><td>' + runnrliststr + '</td></tr>\n'
263 htmltext += '</table>'
264 htmltext += '<hr color=&quot;#000000&quot; size=1><font color=&quot;#777777&quot;>\n'
265 htmltext += '<table style=&quot;width: auto; border: 0px solid; border-width: margin: 0 0 0 0; 0px; border-spacing: 0px; border-collapse: separate; padding: 0px;&quot; font-family: sans-serif; font-size: 90%%&quot;>\n'
266
267
268 # lumiblock collections of NamedLumiRange
269 for run in runlist:
270 # run number
271 htmltext += '<tr><td style=&quot;text-align:left;height:25px;vertical-align:bottom&quot;>Run <b>%i</b>:</td><td></td></tr>\n' % run.runNr
272
273 # lumiblock ranges
274
275 for lbrange in run.data.getLBRanges(activeOnly=True):
276 htmltext += '<tr><td></td><td style=&quot;text-align:left&quot;>LB range: [%5i-%5i]</td></tr>\n' % (lbrange[1],lbrange[2]-1)
277
278 # append stream element
279 htmltext += '<tr><td></td><td style=&quot;text-align:left&quot;></td></tr>'
280 htmltext += '<tr><td></td><td style=&quot;text-align:left&quot;><table style=&quot;width: auto; border: 0px solid; border-width: margin: 0 0 0 0; 0px; border-spacing: 0px; border-collapse: separate; padding: 0px;font-family: sans-serif; font-size: 90%&quot;><tr><td>Stream name</td><td>#Events total</td><td>&nbsp;&nbsp;&nbsp;#Events selected</td><td>&nbsp;&nbsp;&nbsp;Sel. fraction (%)</td></tr>\n'
281
282 streams = streams_byrun[run.runNr]
283 for stream in sorted(streams.keys()):
284 nevts = streams[stream]
285 eff = (nevts[1]/float(nevts[0])*100.0) if (nevts[0] > 0) else 0
286 htmltext += '<tr><td style=&quot;text-align:left&quot;><i>%s</i></td><td style=&quot;text-align:right&quot;>%s</td><td style=&quot;text-align:right&quot;>%s</td><td style=&quot;text-align:right&quot;>%.4g</td></tr>\n' % (stream, prettyNumber(nevts[0]),prettyNumber(nevts[1]),eff)
287
288 htmltext += '</table></td></tr>\n'
289
290
291 # append stream element
292 htmltext += '</table>'
293 htmltext += '<hr color=&quot;#000000&quot; size=1><font color=&quot;#777777&quot;>\n'
294 htmltext += '<b>Stream summary for all selected runs:</b><br>\n'
295 htmltext += '<table style=&quot;width: auto; border: 0px solid; border-width: margin: 0 0 0 0; 0px; border-spacing: 0px; border-collapse: separate; padding: 0px;font-family: sans-serif; font-size: 95%&quot;><tr><td>Stream name</td><td>#Events total</td><td>&nbsp;&nbsp;&nbsp;#Events selected</td><td>&nbsp;&nbsp;&nbsp;Sel. fraction (%)</td></tr>\n'
296 for stream in sorted(streams_sum.keys()):
297 nevts = streams_sum[stream]
298 eff = 0
299 if nevts[0] > 0:
300 eff = nevts[1]/float(nevts[0])*100.0
301 htmltext += '<tr><td style=&quot;text-align:left&quot;><i>%s</i></td><td style=&quot;text-align:right&quot;>%s</td><td style=&quot;text-align:right&quot;>%s</td><td style=&quot;text-align:right&quot;>%.4g</td></tr>\n' % (stream, prettyNumber(nevts[0]),prettyNumber(nevts[1]),eff)
302 htmltext += '</table>\n'
303
304 #print """========================================================
305 #%r
306 #===========================================================
307 #""" % htmltext
308
309
310 # provide also text output
311 return htmltext
writexml(self, writer, indent="", addindent="", newl="")
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177
CreateXMLFile(runlist, options, origQuery, datapath, xmlfname, xmllabel, svnversion='Unknown')