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