CMS 3D CMS Logo

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