CMS 3D CMS Logo

lumiPatch.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 VERSION='1.00'
3 import os,sys,datetime
4 import coral
5 from RecoLuminosity.LumiDB import argparse,selectionParser,csvSelectionParser
6 
7 '''
8 --on wbm db
9 select LUMISEGMENTNR,DEADTIMEBEAMACTIVE from cms_wbm.LEVEL1_TRIGGER_CONDITIONS where RUNNUMBER=:runnumber order by LUMISEGMENTNR;
10 --on lumidb
11 update TRG set DEADTIME=:deadtimebeamactive where RUNNUM=:runnum and CMSLSNUM=:lsnum
12 --reapply calibration to inst lumi
13 update LUMISUMMARY set INSTLUMI=1.006319*INSTLUMI where RUNNUM in (1,3,57,90)
14 '''
15 
17  def __init__(self):
18  self.debug=False
19  self.isdryrun=None
20  self.runinfoschema='CMS_RUNINFO'
21  self.wbmschema='CMS_WBM'
22  self.wbmdeadtable='LEVEL1_TRIGGER_CONDITIONS'
23  self.gtmonschema='CMS_GT_MON'
24  self.gtdeadview='GT_MON_TRIG_DEAD_VIEW'
25  self.lumitrgtable='TRG'
26  self.lumisummarytable='LUMISUMMARY'
27  self.runsummarytable='CMSRUNSUMMARY'
28 def missingTimeRuns(dbsession,c):
29  '''return all the runs with starttime or stoptime column NULL in lumi db
30  select runnum from CMSRUNSUMMARY where starttime is NULL or stoptime is NULL
31  '''
32  result=[]
33  try:
34  emptyBindVarList=coral.AttributeList()
35  dbsession.transaction().start(True)
36  schema=dbsession.nominalSchema()
37  if not schema:
38  raise 'cannot connect to schema '
39  if not schema.existsTable(c.runsummarytable):
40  raise 'non-existing table '+c.runsummarytable
41  query=schema.newQuery()
42  query.addToTableList(c.runsummarytable)
43  query.addToOutputList('RUNNUM','runnum')
44  query.setCondition('STARTTIME IS NULL AND STOPTIME IS NULL',emptyBindVarList)
45  query.addToOrderList('runnum')
46  queryOutput=coral.AttributeList()
47  queryOutput.extend('runnum','unsigned int')
48  query.defineOutput(queryOutput)
49  cursor=query.execute()
50  while next(cursor):
51  result.append(cursor.currentRow()['runnum'].data())
52  del query
53  dbsession.transaction().commit()
54  except Exception as e:
55  print str(e)
56  dbsession.transaction().rollback()
57  del dbsession
58  return result
59 def getTimeForRun(dbsession,c,runnums):
60  '''
61  get start stop time of run from runinfo database
62  select time from cms_runinfo.runsession_parameter where runnumber=:runnum and name='CMS.LVL0:START_TIME_T';
63  select time from cms_runinfo.runsession_parameter where runnumber=:runnum and name='CMS.LVL0:STOP_TIME_T';
64  '''
65  result={}#{runnum:(starttime,stoptime)}
66  tableName='RUNSESSION_PARAMETER'
67  try:
68  dbsession.transaction().start(True)
69  schema=dbsession.nominalSchema()
70  if not schema:
71  raise 'cannot connect to schema '
72  if not schema.existsTable(tableName):
73  raise 'non-existing table '+tableName
74 
75  startTime=''
76  stopTime=''
77  for runnum in runnums:
78  startTQuery=schema.newQuery()
79  startTQuery.addToTableList(tableName)
80  startTQuery.addToOutputList('TIME','starttime')
81  stopTQuery=schema.newQuery()
82  stopTQuery.addToTableList(tableName)
83  stopTQuery.addToOutputList('TIME','stoptime')
84  startTQueryCondition=coral.AttributeList()
85  stopTQueryCondition=coral.AttributeList()
86  startTQueryOutput=coral.AttributeList()
87  stopTQueryOutput=coral.AttributeList()
88  startTQueryCondition.extend('runnum','unsigned int')
89  startTQueryCondition.extend('name','string')
90  startTQueryOutput.extend('starttime','time stamp')
91  stopTQueryCondition.extend('runnum','unsigned int')
92  stopTQueryCondition.extend('name','string')
93  stopTQueryOutput.extend('stoptime','time stamp')
94  startTQueryCondition['runnum'].setData(int(runnum))
95  startTQueryCondition['name'].setData('CMS.LVL0:START_TIME_T')
96  startTQuery.setCondition('RUNNUMBER=:runnum AND NAME=:name',startTQueryCondition)
97  startTQuery.defineOutput(startTQueryOutput)
98  startTCursor=startTQuery.execute()
99  while next(startTCursor):
100  startTime=startTCursor.currentRow()['starttime'].data()
101  stopTQueryCondition['runnum'].setData(int(runnum))
102  stopTQueryCondition['name'].setData('CMS.LVL0:STOP_TIME_T')
103  stopTQuery.setCondition('RUNNUMBER=:runnum AND NAME=:name',stopTQueryCondition)
104  stopTQuery.defineOutput(stopTQueryOutput)
105  stopTCursor=stopTQuery.execute()
106  while next(stopTCursor):
107  stopTime=stopTCursor.currentRow()['stoptime'].data()
108  if not startTime or not stopTime:
109  print 'Warning: no startTime or stopTime found for run ',runnum
110  else:
111  result[runnum]=(startTime,stopTime)
112  del startTQuery
113  del stopTQuery
114  dbsession.transaction().commit()
115  except Exception as e:
116  print str(e)
117  dbsession.transaction().rollback()
118  del dbsession
119  return result
120 
121 def addTimeForRun(dbsession,c,runtimedict):
122  '''
123  Input runtimedict{runnumber:(startTimeT,stopTimeT)}
124  update CMSRUNSUMMARY set STARTTIME=:starttime,STOPTIME=:stoptime where RUNNUM=:runnum
125  #update CMSRUNSUMMARY set STOPTIME=:stoptime where RUNNUM=:runnum
126  '''
127  nchanged=0
128  totalchanged=0
129  try:
130  dbsession.transaction().start(False)
131  schema=dbsession.nominalSchema()
132  if not schema:
133  raise 'cannot connect to schema'
134  if not schema.existsTable(c.runsummarytable):
135  raise 'non-existing table '+c.runsummarytable
136  inputData=coral.AttributeList()
137  inputData.extend('starttime','time stamp')
138  inputData.extend('stoptime','time stamp')
139  inputData.extend('runnum','unsigned int')
140  runs=sorted(runtimedict.keys())
141  for runnum in runs:
142  (startTimeT,stopTimeT)=runtimedict[runnum]
143  inputData['starttime'].setData(startTimeT)
144  inputData['stoptime'].setData(stopTimeT)
145  inputData['runnum'].setData(int(runnum))
146  nchanged=schema.tableHandle(c.runsummarytable).dataEditor().updateRows('STARTTIME=:starttime,STOPTIME=:stoptime','RUNNUM=:runnum',inputData)
147  print 'run '+str(runnum)+' update '+str(nchanged)+' row with starttime ,stoptime'
148  print startTimeT,stopTimeT
149  totalchanged=totalchanged+nchanged
150  if c.isdryrun:
151  dbsession.transaction().rollback()
152  else:
153  dbsession.transaction().commit()
154  except Exception as e:
155  print str(e)
156  dbsession.transaction().rollback()
157  del dbsession
158  print 'total number of rows changed: ',totalchanged
159 
160 def recalibrateLumiForRun(dbsession,c,delta,runnums):
161  '''
162  update LUMISUMMARY set INSTLUMI=:delta*INSTLUMI where RUNNUM in (1,3,57,90)
163  '''
164  updaterows=0
165  try:
166  dbsession.transaction().start(False)
167  schema=dbsession.nominalSchema()
168  if not schema:
169  raise 'cannot connect to schema'
170  if not schema.existsTable(c.lumisummarytable):
171  raise 'non-existing table '+c.lumisummarytable
172  runliststring=','.join([str(x) for x in runnums])
173  print 'applying delta '+delta+' on run list '+runliststring
174  nchanged=0
175  inputData=coral.AttributeList()
176  inputData.extend('delta','float')
177  inputData['delta'].setData(float(delta))
178  nchanged=schema.tableHandle(c.lumisummarytable).dataEditor().updateRows('INSTLUMI=INSTLUMI*:delta','RUNNUM in ('+runliststring+')',inputData)
179  print 'total number of row changed ',nchanged
180  if c.isdryrun:
181  dbsession.transaction().rollback()
182  else:
183  dbsession.transaction().commit()
184  return nchanged
185  except Exception as e:
186  print str(e)
187  dbsession.transaction().rollback()
188  del dbsession
189 
190 def GTdeadtimeBeamActiveForRun(dbsession,c,runnum):
191  '''
192  select lsnr,counts from cms_gt_mon.gt_mon_trig_dead_view where runnr=:runnumber and deadcounter='DeadtimeBeamActive' order by lsnr;
193  return result{lumisection:deadtimebeamactive}
194 
195  '''
196  result={}
197  try:
198  dbsession.transaction().start(True)
199  schema=dbsession.schema(c.gtmonschema)
200 
201  if not schema:
202  raise Exception('cannot connect to schema '+c.gtmonschema)
203  if not schema.existsView(c.gtdeadview):
204  raise Exception('non-existing view '+c.gtdeadview)
205 
206  deadOutput=coral.AttributeList()
207  deadOutput.extend("lsnr","unsigned int")
208  deadOutput.extend("deadcount","unsigned long long")
209 
210  deadBindVarList=coral.AttributeList()
211  deadBindVarList.extend("runnumber","unsigned int")
212  deadBindVarList.extend("countername","string")
213  deadBindVarList["runnumber"].setData(int(runnum))
214  deadBindVarList["countername"].setData('DeadtimeBeamActive')
215 
216  query=schema.newQuery()
217  query.addToTableList(c.gtdeadview)
218  query.addToOutputList('LSNR','lsnr')
219  query.addToOutputList('COUNTS','deadcount')
220  query.setCondition('RUNNR=:runnumber AND DEADCOUNTER=:countername',deadBindVarList)
221  query.addToOrderList('lsnr')
222  query.defineOutput(deadOutput)
223 
224  cursor=query.execute()
225  while next(cursor):
226  cmslsnum=cursor.currentRow()['lsnr'].data()
227  deadcount=cursor.currentRow()['deadcount'].data()
228  result[cmslsnum]=deadcount
229  #print 'deadcount',deadcount
230  del query
231  return result
232  except Exception as e:
233  print str(e)
234  dbsession.transaction().rollback()
235  del dbsession
236 
237 def WBMdeadtimeBeamActiveForRun(dbsession,c,runnum):
238  '''
239  select LUMISEGMENTNR,DEADTIMEBEAMACTIVE from cms_wbm.LEVEL1_TRIGGER_CONDITIONS where RUNNUMBER=:runnum order by LUMISEGMENTNR;
240  return result{lumisection:deadtimebeamactive}
241 
242  '''
243  result={}
244  try:
245  dbsession.transaction().start(True)
246  schema=dbsession.nominalSchema()
247  if not schema:
248  raise Exception('cannot connect to schema'+c.wbmschema)
249  if not schema.existsTable(c.wbmdeadtable):
250  raise Exception('non-existing table'+c.wbmdeadtable)
251 
252  deadOutput=coral.AttributeList()
253  deadOutput.extend("lsnr","unsigned int")
254  deadOutput.extend("deadcount","unsigned long long")
255 
256  deadBindVarList=coral.AttributeList()
257  deadBindVarList.extend("runnum","unsigned int")
258  deadBindVarList["runnum"].setData(int(runnum))
259 
260  query=schema.newQuery()
261  query.addToTableList(c.wbmdeadtable)
262  query.addToOutputList('LUMISEGMENTNR','lsnr')
263  query.addToOutputList('DEADTIMEBEAMACTIVE','deadcount')
264  query.setCondition('RUNNUMBER=:runnum',deadBindVarList)
265  query.addToOrderList('LUMISEGMENTNR')
266  query.defineOutput(deadOutput)
267 
268  cursor=query.execute()
269  while next(cursor):
270  cmslsnum=cursor.currentRow()['lsnr'].data()
271  deadcount=cursor.currentRow()['deadcount'].data()
272  result[cmslsnum]=deadcount
273  #print 'deadcount',deadcount
274  del query
275  return result
276  except Exception as e:
277  print str(e)
278  dbsession.transaction().rollback()
279  del dbsession
280 
281 def patchDeadtimeForRun(dbsession,c,runnum,deadtimeDict):
282  '''
283  input: deadtimeDict{ls:deadtimebeamactive}
284  loop over input
285  update TRG set DEADTIME=:deadtimebeamactive where RUNNUM=:runnum and CMSLSNUM=:lsnum
286  output: number of rows changed
287  '''
288  totalchanged=0
289  try:
290  dbsession.transaction().start(False)
291  schema=dbsession.nominalSchema()
292  if not schema:
293  raise Exception('cannot connect to schema ')
294  if not schema.existsTable(c.lumitrgtable):
295  raise Exception('non-existing table '+c.lumitrgtable)
296  for lsnum,deadtimebeamactive in deadtimeDict.items():
297  nchanged=0
298  inputData=coral.AttributeList()
299  inputData.extend('deadtimebeamactive','unsigned int')
300  inputData.extend('runnum','unsigned int')
301  inputData.extend('lsnum','unsigned int')
302  inputData['deadtimebeamactive'].setData(deadtimebeamactive)
303  inputData['runnum'].setData(runnum)
304  inputData['lsnum'].setData(lsnum)
305  nchanged=schema.tableHandle(c.lumitrgtable).dataEditor().updateRows('DEADTIME=:deadtimebeamactive','RUNNUM=:runnum AND CMSLSNUM=:lsnum',inputData)
306  print 'rows changed for ls ',str(lsnum),str(nchanged)
307  totalchanged+=nchanged
308  dbsession.transaction().commit()
309  return totalchanged
310  except Exception as e:
311  print str(e)
312  dbsession.transaction().rollback()
313  del dbsession
314 
315 def main():
316  c=constants()
317  parser = argparse.ArgumentParser(prog=os.path.basename(sys.argv[0]),description="Patch LumiData")
318  parser.add_argument('-c',dest='destination',action='store',required=True,help='destination lumi db (required)')
319  parser.add_argument('-s',dest='source',action='store',required=False,help='source db (required except for lumicalib)')
320  parser.add_argument('-P',dest='authpath',action='store',required=True,help='path to authentication file (required)')
321  parser.add_argument('-r',dest='runnumber',action='store',required=False,help='run number (optional)')
322  parser.add_argument('-i',dest='inputfile',action='store',required=False,help='run selection file(optional)')
323  parser.add_argument('-delta',dest='delta',action='store',required=False,help='calibration factor wrt old data in lumiDB (required for lumicalib)')
324  parser.add_argument('action',choices=['deadtimeGT','deadtimeWBM','lumicalib','runtimestamp'],help='deadtimeGT: patch deadtime to deadtimebeamactive,\ndeadtimeWBM: patch deadtimeWBM to deadtimebeamactive,\nlumicalib: recalibrate inst lumi by delta where delta>1\n runtimestamp: add start,stop run timestamp where empty')
325  parser.add_argument('--dryrun',dest='dryrun',action='store_true',help='only print datasource query result, do not update destination')
326 
327  parser.add_argument('--debug',dest='debug',action='store_true',help='debug')
328  args=parser.parse_args()
329  runnumber=args.runnumber
330  destConnect=args.destination
331  sourceConnect=args.source
332  if args.authpath and len(args.authpath)!=0:
333  os.environ['CORAL_AUTH_PATH']=args.authpath
334  svc=coral.ConnectionService()
335  sourcesession=None
336  if sourceConnect:
337  sourcesession=svc.connect(sourceConnect,accessMode=coral.access_ReadOnly)
338  sourcesession.typeConverter().setCppTypeForSqlType("unsigned int","NUMBER(10)")
339  sourcesession.typeConverter().setCppTypeForSqlType("unsigned long long","NUMBER(20)")
340  destsession=svc.connect(destConnect,accessMode=coral.access_Update)
341  destsession.typeConverter().setCppTypeForSqlType("unsigned int","NUMBER(10)")
342  destsession.typeConverter().setCppTypeForSqlType("unsigned long long","NUMBER(20)")
343  if args.debug:
344  msg=coral.MessageStream('')
345  msg.setMsgVerbosity(coral.message_Level_Debug)
346  if args.dryrun:
347  c.isdryrun=True
348  else:
349  c.isdryrun=False
350 
351  deadresult={}
352 
353  if args.action == 'deadtimeGT':
354  if not sourceConnect:
355  raise Exception('deadtimeGT action requies -s option for source connection string')
356  deadresult=GTdeadtimeBeamActiveForRun(sourcesession,c,runnumber)
357  print 'reading from ',sourceConnect
358  print 'run : ',runnumber
359  print 'LS:deadtimebeamactive'
360  #print deadresult
361  if deadresult and len(deadresult)!=0:
362  for cmsls,deadtimebeamactive in deadresult.items():
363  print cmsls,deadtimebeamactive
364  else:
365  print 'no deadtime found for run ',runnumber
366  print 'exit'
367  return
368  print 'total LS: ',len(deadresult)
369 # if len(deadresult)!=max( [ (deadresult[x],x) for x in deadresult] )[1]:
370  if len(deadresult)!=max( [ x for x in deadresult.keys() ] ):
371  print 'total ls: ',len(deadresult)
372  #print 'max key: ',max( [ x for x in deadresult.keys()])
373  print 'alert: missing Lumi Sections in the middle'
374  for x in range(1,max( [ x for x in deadresult.keys()] ) ):
375  if x not in deadresult:
376  print 'filling up LS deadtime with 0: LS : ',x
377  deadresult[x]=0
378  #print deadresult
379  if not args.dryrun:
380  print 'updating ',destConnect
381  nupdated=patchDeadtimeForRun(destsession,c,int(runnumber),deadresult)
382  print 'number of updated rows ',nupdated
383  elif args.action == 'deadtimeWBM':
384  if not sourceConnect:
385  raise Exception('deadtimeWBM action requies -s option for source connection string')
386  deadresult=WBMdeadtimeBeamActiveForRun(sourcesession,c,runnumber)
387  print 'reading from ',sourceConnect
388  print 'run : ',runnumber
389  print 'LS:deadtimebeamactive'
390  #print deadresult
391  if deadresult and len(deadresult)!=0:
392  for cmsls,deadtimebeamactive in deadresult.items():
393  print cmsls,deadtimebeamactive
394  else:
395  print 'no deadtime found for run ',runnumber
396  print 'exit'
397  return
398  print 'total LS: ',len(deadresult)
399  if len(deadresult)!=max( [ (deadresult[x],x) for x in deadresult])[1]:
400  print 'alert: missing Lumi Sections in the middle'
401  for x in range(1,max( [ (deadresult[x],x) for x in deadresult])[1]):
402  if x not in deadresult:
403  print 'filling up LS deadtime with 0: LS : ',x
404  deadresult[x]=0
405  print deadresult
406  if not args.dryrun:
407  print 'updating ',destConnect
408  nupdated=patchDeadtimeForRun(destsession,c,int(runnumber),deadresult)
409  print 'number of updated rows ',nupdated
410  elif args.action == 'lumicalib':
411  if not args.delta or args.delta==0:
412  raise Exception('Must provide non-zero -delta argument')
413  runnums=[]
414  if args.runnumber:
415  runnums.append(args.runnumber)
416  elif args.inputfile:
417  basename,extension=os.path.splitext(args.inputfile)
418  if extension=='.csv':#if file ends with .csv,use csv parser,else parse as json file
419  fileparsingResult=csvSelectionParser.csvSelectionParser(args.inputfile)
420  else:
421  f=open(args.inputfile,'r')
422  inputfilecontent=f.read()
423  fileparsingResult=selectionParser.selectionParser(inputfilecontent)
424  if not fileparsingResult:
425  raise Exception('failed to parse the input file '+ifilename)
426  #print fileparsingResult.runsandls()
427  runnums=fileparsingResult.runs()
428  #print runnums
429  else:
430  raise Exception('Must provide -r or -i argument as input')
431  nupdated=recalibrateLumiForRun(destsession,c,args.delta,runnums)
432  elif args.action == 'runtimestamp':
433  if not sourceConnect:
434  raise Exception('runtimestamp action requies -s option for source connection string')
435  if not args.runnumber and not args.inputfile: #if no runnumber nor input file specified, check all
436  runnums=missingTimeRuns(destsession,c)
437  print 'these runs miss start/stop time: ',runnums
438  print 'total : ',len(runnums)
439  elif args.runnumber:
440  runnums=[int(args.runnumber)]
441  elif args.inputfile:
442  basename,extension=os.path.splitext(args.inputfile)
443  if extension=='.csv':#if file ends with .csv,use csv parser,else parse as json file
444  fileparsingResult=csvSelectionParser.csvSelectionParser(args.inputfile)
445  else:
446  f=open(args.inputfile,'r')
447  inputfilecontent=f.read()
448  fileparsingResult=selectionParser.selectionParser(inputfilecontent)
449  if not fileparsingResult:
450  raise Exception('failed to parse the input file '+ifilename)
451  runnums=fileparsingResult.runs()
452  result=getTimeForRun(sourcesession,c,runnums)
453  #for run,(startTimeT,stopTimeT) in result.items():
454  #print 'run: ',run
455  #if not startTimeT or not stopTimeT:
456  #print 'None'
457  #else:
458  #print 'start: ',startTimeT
459  #print 'stop: ',stopTimeT
460  addTimeForRun(destsession,c,result)
461  if sourcesession:
462  del sourcesession
463  del destsession
464  del svc
465 
466 if __name__=='__main__':
467  main()
468 
Definition: start.py:1
def getTimeForRun(dbsession, c, runnums)
Definition: lumiPatch.py:59
def addTimeForRun(dbsession, c, runtimedict)
Definition: lumiPatch.py:121
def WBMdeadtimeBeamActiveForRun(dbsession, c, runnum)
Definition: lumiPatch.py:237
def missingTimeRuns(dbsession, c)
Definition: lumiPatch.py:28
def recalibrateLumiForRun(dbsession, c, delta, runnums)
Definition: lumiPatch.py:160
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
def main()
Definition: lumiPatch.py:315
def patchDeadtimeForRun(dbsession, c, runnum, deadtimeDict)
Definition: lumiPatch.py:281
Definition: main.py:1
#define str(s)
def GTdeadtimeBeamActiveForRun(dbsession, c, runnum)
Definition: lumiPatch.py:190
def __init__(self)
Definition: lumiPatch.py:17