1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
|
#!/usr/bin/env python3
from sys import stderr, exit
import subprocess, os
from optparse import OptionParser
parser = OptionParser(usage=
"""
usage: %prog [options] csv_output_file
examples:
%prog out.csv
produces a table of ALL runs and ALL paths (can take quite some time)
%prog --path='*ele*' --path='*photon*' out.csv
select only paths containing 'ele' and 'photon'
""")
parser.add_option("--firstRun", dest="firstRun", help="first run", type="int", metavar="RUN", default="1")
parser.add_option("--lastRun", dest="lastRun", help="last run", type="int", metavar="RUN", default="9999999")
parser.add_option("--groupName", dest="groupName", help="select runs of name like NAME", metavar="NAME", default="Collisions%")
parser.add_option("--overwrite", dest="overwrite", help="force overwriting of output CSV file", action="store_true", default=False)
parser.add_option("--path",
dest="pathPatterns",
default = [],
action="append",
metavar="PATTERN",
help="restrict paths to PATTERN. Note that this can be a single path name or a pattern " +
"using wildcards (*,?) similar to those used for selecting multiple files (see " +
"the documentation of the fnmatch module for details). Note also that this option " +
"can be specified more than once to select multiple paths or patterns. If this option " +
"is not specified, all paths are considered. Note that the comparison is done " +
"in a case-INsensitive manner. " +
"You may have to escape wildcards (with quotes or backslash) in order to avoid "+
"expansion by the shell"
)
# parser.add_option("--jsonOut", dest="jsonOut", help="dump prescales in JSON format on FILE", metavar="FILE")
(options, args) = parser.parse_args()
if len(args) != 1:
parser.print_help()
exit(2)
csv_output_file = args[0]
if os.path.exists(csv_output_file) and not options.overwrite:
print("cowardly refusing to overwrite existing output file '" + csv_output_file + "'. Run this script without argument to see options for overriding this check.", file=stderr)
exit(1)
#----------------------------------------------------------------------
def getPrescaleTableFromProcessObject(process):
""" returns a dict of hlt key to vector of prescales
mapping """
retval = {}
for entry in process.PrescaleService.prescaleTable:
retval[entry.pathName.value()] = entry.prescales.value()
return retval
#----------------------------------------------------------------------
def getProcessObjectFromConfDB(hlt_key):
# print >> stderr,"\t%s ..." % hlt_key
cmd = "edmConfigFromDB --orcoff --configName " + hlt_key
# print >> stderr, "cmd=",cmd
res = subprocess.getoutput(cmd)
# potentially dangerous: we're running python code here
# which we get from an external process (confDB).
# we trust that there are no file deletion commands
# in the HLT configurations...
# for some keys, edmConfigFromDB seems to produce error messages.
# just return None in this case
try:
exec(res)
except:
return None
return process
#----------------------------------------------------------------------
from .queryRR import queryRR
#----------------------------------------------------------------------
# main
#----------------------------------------------------------------------
# check whether we have a CMSSW environment initalized
if os.system("which edmConfigFromDB") != 0:
print("could not find the command edmConfigFromDB. Did you initialize your CMSSW runtime environment ?", file=stderr)
exit(1)
runKeys = queryRR(options.firstRun,options.lastRun,options.groupName)
# maps from HLT key to prescale information.
# indexed as: prescaleTable[hlt_key][hlt_path_name]
prescaleTable = {}
# maps from
hlt_path_names_table = {}
# set of all HLT paths seen so far
all_hlt_path_names_seen = set()
runs = sorted(runKeys.keys())
# loop over all hlt keys found
all_hlt_keys_seen = set(runKeys.values())
print("found %d runs and %d HLT menus" % ( len(runKeys), len(all_hlt_keys_seen)), file=stderr)
index = 1
for hlt_key in all_hlt_keys_seen:
print("(%3d/%3d) Querying ConfDB for HLT menu %s" % (index, len(all_hlt_keys_seen) , hlt_key), file=stderr)
process = getProcessObjectFromConfDB(hlt_key)
if process == None:
print("WARNING: unable to retrieve hlt_key '" + hlt_key + "'", file=stderr)
continue
prescaleTable[hlt_key] = getPrescaleTableFromProcessObject(process)
all_path_names = set(process.paths.keys())
# remember which hlt paths were in this menu
hlt_path_names_table[hlt_key] = all_path_names
# add this configuration's HLT paths to the list
# of overall path names seen
all_hlt_path_names_seen.update(all_path_names)
index += 1
# end of loop over all HLT keys
# make sure the list of all HLT path names ever seen is sorted
all_hlt_path_names_seen = sorted(all_hlt_path_names_seen)
#--------------------
# filter paths if required by the user
if len(options.pathPatterns) > 0:
import fnmatch
tmp = []
for path in all_hlt_path_names_seen:
for pattern in options.pathPatterns:
if fnmatch.fnmatch(path.lower(), pattern.lower()):
# accept this path
tmp.append(path)
break
all_hlt_path_names_seen = tmp
# sanity check
if len(all_hlt_path_names_seen) == 0:
print("no HLT paths found, exiting", file=stderr)
exit(1)
#--------------------
# now that we know all path names of all runs, produce the CSV
import csv
previous_hlt_key = None
fout = open(csv_output_file,"w")
csv_writer = csv.writer(fout,delimiter=";")
csv_writer.writerow(['Table of HLT prescale factors'])
csv_writer.writerow([])
csv_writer.writerow(['Explanation:'])
csv_writer.writerow(['number(s) = prescale factor(s), HLT path present in this menu'])
csv_writer.writerow(['empty = HLT path NOT present in this menu'])
csv_writer.writerow(['0 = HLT path present in this menu but prescale factor is zero'])
csv_writer.writerow(['U = could not retrieve menu for this HLT key from confDB'])
csv_writer.writerow([])
csv_writer.writerow([])
# write the header line
column_names = [ 'run','' ]
column_names.extend(all_hlt_path_names_seen)
csv_writer.writerow(column_names)
csv_writer.writerow([])
for run in runs:
hlt_key = runKeys[run]
if hlt_key == previous_hlt_key:
# the hlt key is the same as for the previous run
# just reuse the existing contents of the variable 'values'
# (apart from the run number)
values[0] = run
csv_writer.writerow(values)
continue
# HLT key has changed
# insert a line with the menu's name
#
# check whether we actually could determine the menu
if hlt_key not in hlt_path_names_table:
# could previously not retrieve the python
# configuration for this key
#
# put some warnings in the output table
csv_writer.writerow([hlt_key, "COULD NOT RETRIEVE MENU FROM CONFDB"])
values = [ run , '' ]
values.extend(len(all_hlt_path_names_seen) * [ "U" ])
csv_writer.writerow(values)
previous_hlt_key = hlt_key
continue
# everything seems ok for this key
csv_writer.writerow([hlt_key])
# now put together the list of prescales
values = [ run , '' ]
# find out which HLT keys were present and which prescale factors
# they had
for hlt_path in all_hlt_path_names_seen:
if hlt_path in hlt_path_names_table[hlt_key]:
# this HLT path was present in this menu
# check whether there was an entry in the prescale
# table
# get the prescale factors (list) or just a list with 1
# if this path was not present in the prescale table
# for this menu
prescales = prescaleTable[hlt_key].get(hlt_path, [ 1 ] )
# merge the values to one comma separated string
# print "prescales=",prescales
values.append(",".join([str(x) for x in prescales]))
else:
# path not found for this hlt key. append
# an empty string for this column
values.append('')
# end loop over hlt paths
csv_writer.writerow(values)
previous_hlt_key = hlt_key
# end loop over runs
fout.close()
print("created CSV file",csv_output_file,". Field delimiter is semicolon.", file=stderr)
|