CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
runregparse.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 # LM: version date: 01/02/2010 --> fixed dataset search and added json output file (optional)
4 # LM: updated 03/04/2010 --> adapted to new runreg api (and dcs status info)
5 # LM: updated 15/04/2010 --> added bfield threshold
6 
7 # include XML-RPC client library
8 # RR API uses XML-RPC webservices interface for data access
9 import xmlrpclib,sys,ConfigParser,os,string,commands,time,re
10 # for json support
11 try: # FUTURE: Python 2.6, prior to 2.6 requires simplejson
12  import json
13 except:
14  try:
15  import simplejson as json
16  except:
17  print "Please use lxplus or set an environment (for example crab) with json lib available"
18  sys.exit(1)
19 
20 global QF_Req,ls_temp_data,QF_ALL_SYS,EXCEPTION,EXRUN
21 EXCEPTION=False
22 EXRUN=-1
23 
24 def invert_intervals(intervals,min_val=1,max_val=9999):
25  # first order and merge in case
26  if not intervals:
27  return []
28  intervals=merge_intervals(intervals)
29  intervals = sorted(intervals, key = lambda x: x[0])
30  result = []
31  if min_val==-1:
32  # defin min and max
33  (a,b)=intervals[0]
34  min_val=a
35  if max_val==-1:
36  (a,b)=intervals[len(intervals)-1]
37  max_val=b
38 
39  curr_min=min_val
40  for (x,y) in intervals:
41  if x>curr_min:
42  result.append((curr_min,x-1))
43  curr_min=y+1
44  if curr_min<max_val:
45  result.append((curr_min,max_val))
46 
47 # print min_val,max_val
48  return result
49 
50 def merge_intervals(intervals):
51  if not intervals:
52  return []
53  intervals = sorted(intervals, key = lambda x: x[0])
54  result = []
55  (a, b) = intervals[0]
56  for (x, y) in intervals[1:]:
57  if x <= b:
58  b = max(b, y)
59  else:
60  result.append((a, b))
61  (a, b) = (x, y)
62  result.append((a, b))
63  return result
64 
65 def remove_html_tags(data):
66  p = re.compile(r'<.*?>')
67  newdata=p.sub('', data)
68  newdata=newdata.replace("&nbsp;","")
69  return newdata
70 
72  result= re.sub(r'\s', '', data)
73  return result
74 
75 def searchrun(runno):
76  global QF_Req,ls_temp_data,QF_ALL_SYS,EXCEPTION,EXRUN
77  intervallist=[]
78  selectls=""
79 
80  for line in ls_temp_data.split("\n"):
81  if runno in line:
82 # print line
83  try:
84  if "%%%BAD LS INFO BEGIN%%%" in line:
85  selectls=line.split("%%%BAD LS INFO BEGIN%%%")[1]
86  selectls=selectls.split("%%%BAD LS INFO END%%%")[0]
87  selectls=remove_html_tags(selectls)
88  selectls=remove_extra_spaces(selectls)
89  # print selectls
90  for tag in QF_ALL_SYS:
91  selectls=selectls.replace(tag+":","\n"+tag+":")
92  # print selectls
93 
94  for line in selectls.split("\n"):
95  try:
96  tag=line.split(":")[0]
97  intervals=line.split(":")[1]
98  except:
99  continue
100  if tag in QF_Req.keys():
101  if QF_Req[tag]=="GOOD":
102  for interval in intervals.split(","):
103  if "ALL" in interval:
104  lmin=1
105  lmax=9999
106  else:
107  strmin=interval.split('-')[0]
108  strmax=interval.split('-')[1]
109  lmin=int(strmin)
110  if "END" in strmax:
111  lmax=9999
112  else:
113  lmax=int(strmax)
114  intervallist.append((lmin,lmax))
115  except:
116  EXCEPTION=True
117  EXRUN=int(runno)
118  intervallist=merge_intervals(intervallist)
119  # print runno, intervallist
120  return intervallist
121 
122 
123 
124 #main starts here#
125 
126 QF_Req={}
127 GOODRUN={}
128 compactList = {}
129 
130 QF_ALL_SYS=["Hcal","Track","Strip","Egam","Es","Dt","Csc","Pix","Muon","Rpc","Castor","Jmet","Ecal","L1t","Hlt","NONE"]
131 QF_ALL_STAT=["GOOD","BAD","EXCL","NONE"]
132 DCS_ALL=['Bpix','Fpix','Tibtid','TecM','TecP','Tob','Ebminus','Ebplus','EeMinus','EePlus','EsMinus','EsPlus','HbheA','HbheB','HbheC','H0','Hf','Dtminus','Dtplus','Dt0','CscMinus','CscPlus','Rpc','Castor',"NONE"]
133 
134 # reading config file
135 CONFIGFILE='runreg.cfg'
136 CONFIG = ConfigParser.ConfigParser()
137 print 'Reading configuration file from ',CONFIGFILE
138 CONFIG.read(CONFIGFILE)
139 
140 DATASET=CONFIG.get('Common','Dataset')
141 GROUP=CONFIG.get('Common','Group')
142 HLTNAMEFILTER=CONFIG.get('Common','HLTnameFilter')
143 ADDRESS=CONFIG.get('Common','RunReg')
144 RUNMIN=CONFIG.get('Common','Runmin')
145 RUNMAX=CONFIG.get('Common','Runmax')
146 QFLAGS=CONFIG.get('Common','QFLAGS')
147 BFIELD=CONFIG.get('Common','BField_thr')
148 LSPARSE=CONFIG.get('Common','LSCOMMENT')
149 DCSSTAT=CONFIG.get('Common','DCS')
150 DCSLIST=string.split(DCSSTAT,',')
151 
152 OUTPUTFILENAME=CONFIG.get('Common',"OutputFileName")
153 
154 LSCOMMENT=True
155 if "TRUE" in LSPARSE.upper() or "1" in LSPARSE.upper() or "YES" in LSPARSE.upper():
156  LSCOMMENT=True
157 elif "FALSE" in LSPARSE.upper() or "0" in LSPARSE.upper() or "NO" in LSPARSE.upper():
158  LSCOMMENT=False
159 else:
160  print "Error in parsing LSCOMMENT cfg parameter: LSPARSE"
161  sys.exit(1)
162 
163 QFlist=string.split(QFLAGS,',')
164 for QF in QFlist:
165  syst=string.split(QF,":")[0]
166  value=string.split(QF,":")[1]
167  if syst not in QF_ALL_SYS or value not in QF_ALL_STAT:
168  print "QFLAG not valid:",syst,value
169  sys.exit(1)
170  QF_Req[syst]=value
171 
172 for dcs in DCSLIST:
173  if dcs not in DCS_ALL:
174  print "DCS not valid:",dcs
175  sys.exit(1)
176 
177 
178 CFGLIST=CONFIG.items('Common')
179 JSONFILE=CONFIG.get('Common','JSONFILE')
180 
181 try:
182  BFIELD_float=float(BFIELD)
183 except:
184  print "BFIELD threshold value not understood:",BFIELD
185  sys.exit(1)
186 
187 # report the request
188 
189 print "You asked for the runreg info in the run range:"+RUNMIN+"-"+RUNMAX
190 print "for dataset: "+DATASET
191 print "with the following quality flags:"
192 for SS in QF_Req.keys():
193  print SS, QF_Req[SS]
194 print "and with the following DCS status:"
195 for dcs in DCSLIST:
196  print dcs
197 print "Manual bad LS in comment column:",LSCOMMENT
198 #sys.exit(1)
199 
200 # get handler to RR XML-RPC server
201 FULLADDRESS=ADDRESS+"/xmlrpc"
202 print "RunRegistry from: ",FULLADDRESS
203 server = xmlrpclib.ServerProxy(FULLADDRESS)
204 
205 # build up selection in RUN table
206 sel_runtable="{groupName} ='"+GROUP+"' and {runNumber} >= "+RUNMIN+" and {runNumber} <= "+RUNMAX+" and {bfield}>"+BFIELD+" and {datasetName} LIKE '"+DATASET+"'"
207 
208 # the lumisection selection is on the Express dataset:
209 sel_dstable="{groupName} ='"+GROUP+"' and {runNumber} >= "+RUNMIN+" and {runNumber} <= "+RUNMAX+" and {bfield}>"+BFIELD+" and {datasetName} LIKE '%Express%'"
210 
211 for key in QF_Req.keys():
212  if key != "NONE" and QF_Req[key]!="NONE":
213  sel_runtable+=" and {cmp"+key+"} = '"+QF_Req[key]+"'"
214  sel_dstable+=" and {cmp"+key+"} = '"+QF_Req[key]+"'"
215 #print sel_runtable
216 
217 # build up selection in RUNLUMISECTION table, not requestuing bfield here because only runs in the run table selection will be considered
218 sel_dcstable="{groupName} ='"+GROUP+"' and {runNumber} >= "+RUNMIN+" and {runNumber} <= "+RUNMAX
219 for dcs in DCSLIST:
220  if dcs !="NONE":
221  sel_dcstable+=" and {parDcs"+dcs+"} = 1"
222 # = 'True'"
223 # print sel_dcstable
224 
225 Tries=0
226 print " "
227 while Tries<10:
228  try:
229  print "Accessing run registry...."
230  dcs_data = server.DataExporter.export('RUNLUMISECTION', 'GLOBAL', 'json', sel_dcstable)
231  run_data = server.DataExporter.export('RUN', 'GLOBAL', 'csv_runs', sel_runtable)
232  ls_temp_data = server.DataExporter.export('RUN', 'GLOBAL', 'csv_datasets', sel_dstable)
233  break
234  except:
235  print "Something wrong in accessing runregistry, retrying in 3s...."
236  Tries=Tries+1
237  time.sleep(3)
238 if Tries==10:
239  print "Run registry unaccessible.....exiting now"
240  sys.exit(1)
241 
242 #print dcs_data
243 # print "run data: ", run_data
244 #print ls_temp_data
245 # find LS info in comment
246 
247 
248 
249 LISTOFRUN=[]
250 selectedRuns = open(OUTPUTFILENAME, 'w')
251 print "Saving selected runs to file OUTPUTFILENAME"
252 for line in run_data.split("\n"):
253  run=line.split(',')[0]
254  if run.isdigit():
255  hlt=line.split(',')[9]
256  print "for run", run, "hlt is", hlt
257  if HLTNAMEFILTER == "" or hlt.find(HLTNAMEFILTER):
258  LISTOFRUN.append(run)
259  selectedRuns.write(run+"\n")
260 selectedRuns.close()
261 
262 selected_dcs={}
263 jsonlist=json.loads(dcs_data)
264 
265 
266 for element in jsonlist:
267  if element in LISTOFRUN:
268 # first search manual ls certification
269  if LSCOMMENT:
270  # using LS intervals in comment
271  manualbad_int=searchrun(element)
272  # make a badlumi list
273  dcsbad_int=invert_intervals(jsonlist[element])
274  combined=[]
275  for interval in manualbad_int:
276  combined.append(interval)
277  for interval in dcsbad_int:
278  combined.append(interval)
279  combined=merge_intervals(combined)
280  combined=invert_intervals(combined)
281  selected_dcs[element]=combined
282  else:
283  # using only DCS info
284  selected_dcs[element]=jsonlist[element]
285  # combined include bith manual LS and DCS LS
286 
287 #JSONOUT=json.dumps(selected_dcs)
288 # WARNING: Don't use selected_dcs before dumping into file, it gets screwed up (don't know why!!)
289 if JSONFILE != "NONE":
290  lumiSummary = open(JSONFILE, 'w')
291  json.dump(selected_dcs, lumiSummary)
292  lumiSummary.close()
293  print " "
294  print "-------------------------------------------"
295  print "Json file: ",JSONFILE," written."
296 
297 
298 # buildup cms snippet
299 selectlumi="process.source.lumisToProcess = cms.untracked.VLuminosityBlockRange(\n"
300 ranges = []
301 runs_to_print = selected_dcs.keys()
302 runs_to_print.sort()
303 for run in runs_to_print:
304  blocks = selected_dcs[run]
305  blocks.sort()
306  prevblock = [-2,-2]
307  for lsrange in blocks:
308  if lsrange[0] == prevblock[1]+1:
309  print "Run: ",run,"- This lumi starts at ", lsrange[0], " previous ended at ", prevblock[1]+1, " so I should merge"
310  prevblock[1] = lsrange[1]
311  ranges[-1] = "\t'%s:%d-%s:%d',\n" % (run, prevblock[0],
312 run, prevblock[1])
313  else:
314  ranges.append("\t'%s:%d-%s:%d',\n" % (run, lsrange[0],
315 run, lsrange[1]))
316  prevblock = lsrange
317 selectlumi += "".join(ranges)
318 selectlumi += ")"
319 
320 
321 print "-------------------------------------------"
322 print " "
323 print "CFG snippet to select:"
324 print selectlumi
325 
326 if EXCEPTION:
327  print "WARNING: Something wrong in manual lumisection selection tag for run: "+str(EXRUN)
def merge_intervals
Definition: runregparse.py:50
def remove_html_tags
Definition: runregparse.py:65
def remove_extra_spaces
Definition: runregparse.py:71
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def invert_intervals
Definition: runregparse.py:24