CMS 3D CMS Logo

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