CMS 3D CMS Logo

lumiCalc2.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 ########################################################################
4 # Command to calculate luminosity from HF measurement stored in lumiDB #
5 # #
6 # Author: Zhen Xie #
7 ########################################################################
8 
9 import os,sys,time
10 from RecoLuminosity.LumiDB import sessionManager,lumiTime,inputFilesetParser,csvSelectionParser,selectionParser,csvReporter,argparse,CommonUtil,revisionDML,lumiCalcAPI,lumiReport,RegexValidator,normDML
11 
12 beamChoices=['PROTPHYS','IONPHYS','PAPHYS']
13 
14 def parseInputFiles(inputfilename):
15  '''
16  output ({run:[cmsls,cmsls,...]},[[resultlines]])
17  '''
18  selectedrunlsInDB={}
19  resultlines=[]
21  runlsbyfile=p.runsandls()
22  selectedProcessedRuns=p.selectedRunsWithresult()
23  selectedNonProcessedRuns=p.selectedRunsWithoutresult()
24  resultlines=p.resultlines()
25  for runinfile in selectedNonProcessedRuns:
26  selectedrunlsInDB[runinfile]=runlsbyfile[runinfile]
27  return (selectedrunlsInDB,resultlines)
28 
29 ##############################
30 ## ######################## ##
31 ## ## ################## ## ##
32 ## ## ## Main Program ## ## ##
33 ## ## ################## ## ##
34 ## ######################## ##
35 ##############################
36 
37 if __name__ == '__main__':
38  parser = argparse.ArgumentParser(prog=os.path.basename(sys.argv[0]),description = "Lumi Calculation",formatter_class=argparse.ArgumentDefaultsHelpFormatter)
39  allowedActions = ['overview', 'delivered', 'recorded', 'lumibyls','lumibylsXing']
40  beamModeChoices = [ "stable"]
41  amodetagChoices = [ "PROTPHYS","IONPHYS",'PAPHYS' ]
42  xingAlgoChoices =[ "OCC1","OCC2","ET"]
43 
44  #
45  # parse arguments
46  #
47  ################################################
48  # basic arguments
49  ################################################
50  parser.add_argument('action',choices=allowedActions,
51  help='command actions')
52  parser.add_argument('-c',dest='connect',action='store',
53  required=False,
54  help='connect string to lumiDB,optional',
55  default='frontier://LumiCalc/CMS_LUMI_PROD')
56  parser.add_argument('-P',dest='authpath',action='store',
57  required=False,
58  help='path to authentication file')
59  parser.add_argument('-r',dest='runnumber',action='store',
60  type=int,
61  required=False,
62  help='run number')
63  parser.add_argument('-o',dest='outputfile',action='store',
64  required=False,
65  help='output to csv file' )
66 
67  #################################################
68  #arg to select exact run and ls
69  #################################################
70  parser.add_argument('-i',dest='inputfile',action='store',
71  required=False,
72  help='lumi range selection file')
73  #################################################
74  #arg to select exact hltpath or pattern
75  #################################################
76  parser.add_argument('--hltpath',dest='hltpath',action='store',
77  default=None,required=False,
78  help='specific hltpath or hltpath pattern to calculate the effectived luminosity')
79  #################################################
80  #versions control
81  #################################################
82  parser.add_argument('--normtag',dest='normtag',action='store',
83  required=False,
84  help='version of lumi norm/correction')
85  parser.add_argument('--datatag',dest='datatag',action='store',
86  required=False,
87  help='version of lumi/trg/hlt data')
88 
89  ###############################################
90  # run filters
91  ###############################################
92  parser.add_argument('-f','--fill',dest='fillnum',action='store',
93  default=None,required=False,
94  help='fill number (optional) ')
95  parser.add_argument('--amodetag',dest='amodetag',action='store',
96  choices=amodetagChoices,
97  required=False,
98  help='specific accelerator mode choices [PROTOPHYS,IONPHYS,PAPHYS] (optional)')
99  parser.add_argument('--beamenergy',dest='beamenergy',action='store',
100  type=float,
101  default=None,
102  help='nominal beam energy in GeV')
103  parser.add_argument('--beamfluctuation',dest='beamfluctuation',
104  type=float,action='store',
105  default=0.2,
106  required=False,
107  help='fluctuation in fraction allowed to nominal beam energy, default 0.2, to be used together with -beamenergy (optional)')
108 
109  parser.add_argument('--begin',dest='begin',action='store',
110  default=None,
111  required=False,
112  type=RegexValidator.RegexValidator("^\d\d/\d\d/\d\d \d\d:\d\d:\d\d$|^\d{6}$|^\d{4}$","wrong format"),
113  help='min run start time (mm/dd/yy hh:mm:ss),min fill or min run'
114  )
115  parser.add_argument('--end',dest='end',action='store',
116  default=None,
117  required=False,
118  type=RegexValidator.RegexValidator("^\d\d/\d\d/\d\d \d\d:\d\d:\d\d$|^\d{6}$|^\d{4}$","wrong format"),
119  help='max run start time (mm/dd/yy hh:mm:ss),max fill or max run'
120  )
121  parser.add_argument('--minBiasXsec',dest='minbiasxsec',action='store',
122  default=69300.0,
123  type=float,
124  required=False,
125  help='minbias cross-section in ub'
126  )
127  #############################################
128  #ls filter
129  #############################################
130  parser.add_argument('-b',dest='beammode',action='store',
131  choices=beamModeChoices,
132  required=False,
133  help='beam mode choices [stable]')
134 
135  parser.add_argument('--xingMinLum', dest = 'xingMinLum',
136  type=float,
137  default=1e-03,
138  required=False,
139  help='Minimum perbunch luminosity to print, default=1e-03/ub')
140 
141  parser.add_argument('--xingAlgo', dest = 'xingAlgo',
142  default='OCC1',
143  required=False,
144  help='algorithm name for per-bunch lumi ')
145 
146  #############################################
147  #global scale factor
148  #############################################
149  parser.add_argument('-n',dest='scalefactor',action='store',
150  type=float,
151  default=1.0,
152  required=False,
153  help='user defined global scaling factor on displayed lumi values,optional')
154 
155  #################################################
156  #command configuration
157  #################################################
158  parser.add_argument('--siteconfpath',dest='siteconfpath',action='store',
159  default=None,
160  required=False,
161  help='specific path to site-local-config.xml file, optional. If path undefined, fallback to cern proxy&server')
162 
163  parser.add_argument('--headerfile',dest='headerfile',action='store',
164  default=None,
165  required=False,
166  help='write command header output to specified file'
167  )
168  #################################################
169  #switches
170  #################################################
171  parser.add_argument('--without-correction',
172  dest='withoutNorm',
173  action='store_true',
174  help='without any correction/calibration'
175  )
176  parser.add_argument('--without-checkforupdate',
177  dest='withoutCheckforupdate',
178  action='store_true',
179  help='without check for update'
180  )
181  #parser.add_argument('--verbose',
182  # dest='verbose',
183  # action='store_true',
184  # help='verbose mode for printing'
185  # )
186  parser.add_argument('--nowarning',
187  dest='nowarning',
188  action='store_true',
189  help='suppress bad for lumi warnings'
190  )
191  parser.add_argument('--debug',
192  dest='debug',
193  action='store_true',
194  help='debug'
195  )
196  options=parser.parse_args()
197  if not options.runnumber and not options.inputfile and not options.fillnum and not options.begin:
198  raise RuntimeError('at least one run selection argument in [-r,-f,-i,--begin] is required')
199  reqrunmin=None
200  reqfillmin=None
201  reqtimemin=None
202  reqrunmax=None
203  reqfillmax=None
204  reqtimemax=None
205  timeFilter=[None,None]
206  noWarning=options.nowarning
207  pbeammode = None
208  if options.beammode=='stable':
209  pbeammode = 'STABLE BEAMS'
210  iresults=[]
211  reqTrg=False
212  reqHlt=False
213  if options.action=='overview' or options.action=='lumibyls' or options.action=='lumibylsXing':
214  reqTrg=True
215  if options.action=='lumibyls' and options.hltpath:
216  reqHlt=True
217  if options.action=='recorded':
218  reqTrg=True
219  reqHlt=True
220  if options.runnumber:
221  reqrunmax=options.runnumber
222  reqrunmin=options.runnumber
223  if options.fillnum:
224  reqfillmin=options.fillnum
225  reqfillmax=options.fillnum
226 
227 
228  if options.begin:
229  (runbeg,fillbeg,timebeg)=CommonUtil.parseTime(options.begin)
230  if runbeg: #there's --begin runnum #priority run,fill,time
231  if not reqrunmin:# there's no -r, then take this
232  reqrunmin=runbeg
233  elif fillbeg:
234  if not reqfillmin:
235  reqfillmin=fillbeg
236  elif timebeg:
237  reqtimemin=timebeg
238  if reqtimemin:
240  reqtimeminT=lute.StrToDatetime(reqtimemin,customfm='%m/%d/%y %H:%M:%S')
241  timeFilter[0]=reqtimeminT
242  if options.end:
243  (runend,fillend,timeend)=CommonUtil.parseTime(options.end)
244  if runend:
245  if not reqrunmax:#priority run,fill,time
246  reqrunmax=runend
247  elif fillend:
248  if not reqfillmax:
249  reqfillmax=fillend
250  elif timeend:
251  reqtimemax=timeend
252  if reqtimemax:
253  lute=lumiTime.lumiTime()
254  reqtimemaxT=lute.StrToDatetime(reqtimemax,customfm='%m/%d/%y %H:%M:%S')
255  timeFilter[1]=reqtimemaxT
256  if options.inputfile and (reqtimemax or reqtimemin):
257  #if use time and file filter together, there's no point of warning about missing LS,switch off
258  noWarning=True
259 
260  ##############################################################
261  # check working environment
262  ##############################################################
263  workingversion='UNKNOWN'
264  updateversion='NONE'
265  thiscmmd=sys.argv[0]
266  if not options.withoutCheckforupdate:
267  from RecoLuminosity.LumiDB import checkforupdate
268  cmsswWorkingBase=os.environ['CMSSW_BASE']
269  if not cmsswWorkingBase:
270  print 'Please check out RecoLuminosity/LumiDB from CVS,scram b,cmsenv'
271  sys.exit(11)
273  workingversion=c.runningVersion(cmsswWorkingBase,'lumiCalc2.py',isverbose=False)
274  if workingversion:
275  updateversionList=c.checkforupdate(workingversion,isverbose=False)
276  if updateversionList:
277  updateversion=updateversionList[-1][0]
278  #
279  # check DB environment
280  #
281  if options.authpath:
282  os.environ['CORAL_AUTH_PATH'] = options.authpath
283 
284  #############################################################
285  #pre-check option compatibility
286  #############################################################
287 
288  if options.action=='recorded':
289  if not options.hltpath:
290  raise RuntimeError('argument --hltpath pathname is required for recorded action')
291 
292  svc=sessionManager.sessionManager(options.connect,
293  authpath=options.authpath,
294  siteconfpath=options.siteconfpath,
295  debugON=options.debug)
296  session=svc.openSession(isReadOnly=True,cpp2sqltype=[('unsigned int','NUMBER(10)'),('unsigned long long','NUMBER(20)')])
297 
298  ##############################################################
299  # check run/ls list
300  ##############################################################
301  irunlsdict={}
302  rruns=[]
303  session.transaction().start(True)
304  filerunlist=None
305  if options.inputfile:
306  (irunlsdict,iresults)=parseInputFiles(options.inputfile)
307  filerunlist=irunlsdict.keys()
308 
309 
310  #if not irunlsdict: #no file
311  # irunlsdict=dict(zip(rruns,[None]*len(rruns)))
312  #else:
313  # for selectedrun in irunlsdict.keys():#if there's further filter on the runlist,clean input dict
314  # if selectedrun not in rruns:
315  # del irunlsdict[selectedrun]
316 
317  ##############################################################
318  # check datatag
319  # #############################################################
320  datatagname=options.datatag
321  if not datatagname:
322  (datatagid,datatagname)=revisionDML.currentDataTag(session.nominalSchema())
323  else:
324  datatagid=revisionDML.getDataTagId(session.nominalSchema(),datatagname)
325 
326  dataidmap=lumiCalcAPI.runList(session.nominalSchema(),datatagid,runmin=reqrunmin,runmax=reqrunmax,fillmin=reqfillmin,fillmax=reqfillmax,startT=reqtimemin,stopT=reqtimemax,l1keyPattern=None,hltkeyPattern=None,amodetag=options.amodetag,nominalEnergy=options.beamenergy,energyFlut=options.beamfluctuation,requiretrg=reqTrg,requirehlt=reqHlt,preselectedruns=filerunlist)
327  if not dataidmap:
328  print '[INFO] No qualified run found, do nothing'
329  sys.exit(14)
330  rruns=[]
331  #crosscheck dataid value
332  for irun,(lid,tid,hid) in dataidmap.items():
333  if not lid:
334  print '[INFO] No qualified lumi data found for run, ',irun
335  if reqTrg and not tid:
336  print '[INFO] No qualified trg data found for run ',irun
337  # continue
338  if reqHlt and not hid:
339  print '[INFO] No qualified hlt data found for run ',irun
340  # continue
341  rruns.append(irun)
342  if not irunlsdict: #no file
343  irunlsdict=dict(list(zip(rruns,[None]*len(rruns))))
344  else:
345  for selectedrun in irunlsdict.keys():#if there's further filter on the runlist,clean input dict
346  if selectedrun not in rruns:
347  del irunlsdict[selectedrun]
348  if not irunlsdict:
349  print '[INFO] No qualified run found, do nothing'
350  sys.exit(13)
351 
352  ###############################################################
353  # check normtag and get norm values if required
354  ###############################################################
355  normname='NONE'
356  normid=0
357  normvalueDict={}
358  if not options.withoutNorm:
359  normname=options.normtag
360  if not normname:
361  normmap=normDML.normIdByType(session.nominalSchema(),lumitype='HF',defaultonly=True)
362  if len(normmap):
363  normname=normmap.keys()[0]
364  normid=normmap[normname]
365  else:
366  normid=normDML.normIdByName(session.nominalSchema(),normname)
367  if not normid:
368  raise RuntimeError('[ERROR] cannot resolve norm/correction')
369  sys.exit(12)
370  normvalueDict=normDML.normValueById(session.nominalSchema(),normid) #{since:[corrector(0),{paramname:paramvalue}(1),amodetag(2),egev(3),comment(4)]}
371  session.transaction().commit()
372  lumiReport.toScreenHeader(thiscmmd,datatagname,normname,workingversion,updateversion,'HF',toFile=options.headerfile)
373 
374 
375  ##################
376  # ls level #
377  ##################
378  session.transaction().start(True)
379 
380  GrunsummaryData=lumiCalcAPI.runsummaryMap(session.nominalSchema(),irunlsdict,dataidmap,lumitype='HF')
381  if options.action == 'delivered':
382  result=lumiCalcAPI.deliveredLumiForIds(session.nominalSchema(),irunlsdict,dataidmap,runsummaryMap=GrunsummaryData,beamstatusfilter=pbeammode,timeFilter=timeFilter,normmap=normvalueDict,lumitype='HF')
383  lumiReport.toScreenTotDelivered(result,iresults,options.scalefactor,irunlsdict=irunlsdict,noWarning=noWarning,toFile=options.outputfile)
384  if options.action == 'overview':
385  result=lumiCalcAPI.lumiForIds(session.nominalSchema(),irunlsdict,dataidmap,runsummaryMap=GrunsummaryData,beamstatusfilter=pbeammode,timeFilter=timeFilter,normmap=normvalueDict,lumitype='HF')
386  lumiReport.toScreenOverview(result,iresults,options.scalefactor,irunlsdict=irunlsdict,noWarning=noWarning,toFile=options.outputfile)
387  if options.action == 'lumibyls':
388  if not options.hltpath:
389  result=lumiCalcAPI.lumiForIds(session.nominalSchema(),irunlsdict,dataidmap,runsummaryMap=GrunsummaryData,beamstatusfilter=pbeammode,timeFilter=timeFilter,normmap=normvalueDict,lumitype='HF',minbiasXsec=options.minbiasxsec)
390  lumiReport.toScreenLumiByLS(result,iresults,options.scalefactor,irunlsdict=irunlsdict,noWarning=noWarning,toFile=options.outputfile)
391  else:
392  hltname=options.hltpath
393  hltpat=None
394  if hltname=='*' or hltname=='all':
395  hltname=None
396  elif 1 in [c in hltname for c in '*?[]']: #is a fnmatch pattern
397  hltpat=hltname
398  hltname=None
399  result=lumiCalcAPI.effectiveLumiForIds(session.nominalSchema(),irunlsdict,dataidmap,runsummaryMap=GrunsummaryData,beamstatusfilter=pbeammode,timeFilter=timeFilter,normmap=normvalueDict,hltpathname=hltname,hltpathpattern=hltpat,withBXInfo=False,bxAlgo=None,xingMinLum=options.xingMinLum,withBeamIntensity=False,lumitype='HF')
400  lumiReport.toScreenLSEffective(result,iresults,options.scalefactor,irunlsdict=irunlsdict,noWarning=noWarning,toFile=options.outputfile)
401  if options.action == 'recorded':#recorded actually means effective because it needs to show all the hltpaths...
402  hltname=options.hltpath
403  hltpat=None
404  if hltname is not None:
405  if hltname=='*' or hltname=='all':
406  hltname=None
407  elif 1 in [c in hltname for c in '*?[]']: #is a fnmatch pattern
408  hltpat=hltname
409  hltname=None
410  result=lumiCalcAPI.effectiveLumiForIds(session.nominalSchema(),irunlsdict,dataidmap,runsummaryMap=GrunsummaryData,beamstatusfilter=pbeammode,timeFilter=timeFilter,normmap=normvalueDict,hltpathname=hltname,hltpathpattern=hltpat,withBXInfo=False,bxAlgo=None,xingMinLum=options.xingMinLum,withBeamIntensity=False,lumitype='HF')
411  lumiReport.toScreenTotEffective(result,iresults,options.scalefactor,irunlsdict=irunlsdict,noWarning=noWarning,toFile=options.outputfile)
412  if options.action == 'lumibylsXing':
413  result=lumiCalcAPI.lumiForIds(session.nominalSchema(),irunlsdict,dataidmap,runsummaryMap=GrunsummaryData,beamstatusfilter=pbeammode,timeFilter=timeFilter,normmap=normvalueDict,withBXInfo=True,bxAlgo=options.xingAlgo,xingMinLum=options.xingMinLum,withBeamIntensity=False,lumitype='HF')
414  outfile=options.outputfile
415  if not outfile:
416  print '[WARNING] no output file given. lumibylsXing writes per-bunch lumi only to default file lumibylsXing.csv'
417  outfile='lumibylsXing.csv'
418  lumiReport.toCSVLumiByLSXing(result,options.scalefactor,outfile,irunlsdict=irunlsdict,noWarning=noWarning)
419  session.transaction().commit()
420  del session
421  del svc
Definition: start.py:1
def toScreenOverview(lumidata, resultlines, scalefactor, irunlsdict=None, noWarning=True, toFile=None)
Definition: lumiReport.py:260
def effectiveLumiForIds(schema, irunlsdict, dataidmap, runsummaryMap=None, beamstatusfilter=None, timeFilter=None, normmap=None, hltpathname=None, hltpathpattern=None, withBXInfo=False, bxAlgo=None, xingMinLum=None, withBeamIntensity=False, lumitype='HF', minbiasXsec=None)
Definition: lumiCalcAPI.py:532
def normIdByName(schema, normname)
Definition: normDML.py:60
def currentDataTag(schema, lumitype='HF')
Definition: revisionDML.py:513
def toScreenLumiByLS(lumidata, resultlines, scalefactor, irunlsdict=None, noWarning=True, toFile=None)
Definition: lumiReport.py:392
def parseInputFiles(inputfilename)
Definition: lumiCalc2.py:14
def normIdByType(schema, lumitype='HF', defaultonly=True)
Definition: normDML.py:92
def runsummaryMap(schema, irunlsdict, dataidmap, lumitype='HF')
Definition: lumiCalcAPI.py:21
def toScreenTotDelivered(lumidata, resultlines, scalefactor, irunlsdict=None, noWarning=True, toFile=None)
Definition: lumiReport.py:148
def lumiForIds(schema, irunlsdict, dataidmap, runsummaryMap, beamstatusfilter=None, timeFilter=None, normmap=None, withBXInfo=False, bxAlgo=None, xingMinLum=None, withBeamIntensity=False, lumitype='HF', minbiasXsec=None)
Definition: lumiCalcAPI.py:480
def toCSVLumiByLSXing(lumidata, scalefactor, filename, irunlsdict=None, noWarning=True)
Definition: lumiReport.py:875
OutputIterator zip(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp)
def parseTime(iTime)
Definition: CommonUtil.py:14
def toScreenHeader(commandname, datatagname, normtag, worktag, updatetag, lumitype, toFile=None)
Definition: lumiReport.py:27
def normValueById(schema, normid)
Definition: normDML.py:181
def toScreenTotEffective(lumidata, resultlines, scalefactor, irunlsdict=None, noWarning=True, toFile=None)
Definition: lumiReport.py:692
def toScreenLSEffective(lumidata, resultlines, scalefactor, irunlsdict=None, noWarning=True, toFile=None)
Definition: lumiReport.py:538
def deliveredLumiForIds(schema, irunlsdict, dataidmap, runsummaryMap, beamstatusfilter=None, timeFilter=None, normmap=None, withBXInfo=False, bxAlgo=None, xingMinLum=None, withBeamIntensity=False, lumitype='HF', minbiasXsec=None)
Definition: lumiCalcAPI.py:369
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger list("!*","!HLTx*"if it matches 2 triggers or more) will accept the event if all the matching triggers are FAIL.It will reject the event if any of the triggers are PASS or EXCEPTION(this matches the behavior of"!*"before the partial wildcard feature was incorporated).Triggers which are in the READY state are completely ignored.(READY should never be returned since the trigger paths have been run
def getDataTagId(schema, tagname, lumitype='HF')
Definition: revisionDML.py:658
def runList(schema, datatagid, runmin=None, runmax=None, fillmin=None, fillmax=None, startT=None, stopT=None, l1keyPattern=None, hltkeyPattern=None, amodetag=None, nominalEnergy=None, energyFlut=0.2, requiretrg=True, requirehlt=True, preselectedruns=None, lumitype='HF')
Definition: lumiCalcAPI.py:47