CMS 3D CMS Logo

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