CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/RecoLuminosity/LumiDB/scripts/specificLumi.py

Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 #
00003 # dump all fills into files.
00004 # allfills.txt all the existing fills.
00005 # fill_num.txt all the runs in the fill
00006 # dumpFill -o outputdir
00007 # dumpFill -f fillnum generate runlist for the given fill
00008 #
00009 import os,os.path,sys,math,array,datetime,time,re
00010 import coral
00011 
00012 from RecoLuminosity.LumiDB import argparse,lumiTime,CommonUtil,lumiQueryAPI
00013 
00014 allfillname='allfills.txt'
00015         
00016 def calculateSpecificLumi(lumi,lumierr,beam1intensity,beam1intensityerr,beam2intensity,beam2intensityerr):
00017     '''
00018     '''
00019     specificlumi=0.0
00020     specificlumierr=0.0
00021     if lumi!=0.0 and beam1intensity!=0.0 and  beam2intensity!=0.0:
00022         specificlumi=float(lumi)/(float(beam1intensity)*float(beam2intensity))
00023         specificlumierr=specificlumi*math.sqrt(lumierr**2/lumi**2+beam1intensityerr**2/beam1intensity**2+beam2intensityerr**2/beam2intensity**2)
00024     return (specificlumi,specificlumierr)
00025 
00026 def getFillFromDB(dbsession,parameters,fillnum):
00027     runtimesInFill={}
00028     q=dbsession.nominalSchema().newQuery()
00029     fillrundict=lumiQueryAPI.runsByfillrange(q,fillnum,fillnum)
00030     del q
00031     if len(fillrundict)>0:
00032         for fill,runs in  fillrundict.items():
00033             for run in runs:
00034                 q=dbsession.nominalSchema().newQuery()
00035                 rresult=lumiQueryAPI.runsummaryByrun(q,run)
00036                 del q
00037                 if len(rresult)==0: continue
00038                 runtimesInFill[run]=rresult[3]
00039     return runtimesInFill
00040 
00041 def getFillFromFile(fillnum,inputdir):
00042     runtimesInFill={}
00043     #look for files 'fill_num.txt' in inputdir
00044     for filename in os.listdir(inputdir):
00045         filename=filename.strip()
00046         if filename.find('.')==-1: continue            
00047         basename,extension=filename.split('.')        
00048         if not extension or extension!='txt':
00049             continue
00050         if basename.find('_')==-1: continue
00051         prefix,number=basename.split('_')
00052         if not number : continue
00053         if fillnum!=int(number):continue
00054         f=open(os.path.join(inputdir,'fill_'+number+'.txt'),'r')
00055         for line in f:
00056             l=line.strip()
00057             fields=l.split(',')
00058             if len(fields)<2 : continue
00059             runtimesInFill[int(fields[0])]=fields[1]
00060         f.close()
00061     return runtimesInFill
00062     
00063 def getSpecificLumi(dbsession,parameters,fillnum,inputdir):
00064     '''
00065     specific lumi in 1e-30 (ub-1s-1) unit
00066     lumidetail occlumi in 1e-27
00067     1309_lumireg_401_CMS.txt
00068     ip fillnum time l(lumi in Hz/ub) dl(point-to-point error on lumi in Hz/ub) sl(specific lumi in Hz/ub) dsl(error on specific lumi)
00069     5  1309 20800119.0 -0.889948 0.00475996848729 0.249009 0.005583287562 -0.68359 6.24140208607 0.0 0.0 0.0 0.0 0.0 0.0 0.0383576 0.00430892097862 0.0479095 0.00430892097862 66.6447 4.41269758764 0.0 0.0 0.0
00070     result [(time,lumi,lumierror,speclumi,speclumierror)]
00071     '''
00072     #result=[]
00073     runtimesInFill=getFillFromFile(fillnum,inputdir)#{runnum:starttimestr}
00074     t=lumiTime.lumiTime()
00075     fillbypos={}#{bxidx:(lstime,lumi,lumierror,specificlumi,specificlumierror)}
00076     #'referencetime=time.mktime(datetime.datetime(2009,12,31,23,0,0).timetuple())
00077     #referencetime=time.mktime(datetime.datetime(2010,1,1,0,0,0).timetuple())
00078     referencetime=1262300400-7232
00079     #for i in range(3564):
00080     #    fillbypos[i]=[]
00081 
00082     if fillnum and len(runtimesInFill)==0:
00083         runtimesInFill=getFillFromDB(dbsession,parameters,fillnum)#{runnum:starttimestr}
00084     #precheck
00085     totalstablebeamLS=0
00086     for runnum in runtimesInFill.keys():
00087         q=dbsession.nominalSchema().newQuery()
00088         runinfo=lumiQueryAPI.lumisummaryByrun(q,runnum,'0001',beamstatus='STABLE BEAMS')
00089         del q
00090         totalstablebeamLS+=len(runinfo)
00091     if totalstablebeamLS<10:#less than 10 LS in a fill has 'stable beam', it's no a good fill
00092         print 'fill ',fillnum,' , having less than 10 stable beam lS, is not good, skip'
00093         return fillbypos
00094     
00095     for runnum,starttime in runtimesInFill.items():
00096         if not runtimesInFill.has_key(runnum):
00097             print 'run '+str(runnum)+' does not exist'
00098             continue
00099         q=dbsession.nominalSchema().newQuery()
00100         occlumidata=lumiQueryAPI.calibratedDetailForRunLimitresult(q,parameters,runnum)#{(startorbit,cmslsnum):[(bxidx,lumivalue,lumierr)]} #values after cut
00101         del q
00102         #print occlumidata
00103         q=dbsession.nominalSchema().newQuery()
00104         beamintensitydata=lumiQueryAPI.beamIntensityForRun(q,parameters,runnum)#{startorbit:[(bxidx,beam1intensity,beam2intensity)]}
00105         del q
00106         for (startorbit,cmslsnum),lumilist in occlumidata.items():
00107             if len(lumilist)==0: continue
00108             lstimestamp=t.OrbitToTimestamp(starttime,startorbit)
00109             if beamintensitydata.has_key(startorbit) and len(beamintensitydata[startorbit])>0:
00110                 for lumidata in lumilist:
00111                     bxidx=lumidata[0]
00112                     lumi=lumidata[1]
00113                     lumierror=lumidata[2]
00114                     for beamintensitybx in beamintensitydata[startorbit]:
00115                         if beamintensitybx[0]==bxidx:
00116                             if not fillbypos.has_key(bxidx):
00117                                 fillbypos[bxidx]=[]
00118                             beam1intensity=beamintensitybx[1]
00119                             beam2intensity=beamintensitybx[2]
00120                             speclumi=calculateSpecificLumi(lumi,lumierror,beam1intensity,0.0,beam2intensity,0.0)
00121                             fillbypos[bxidx].append([lstimestamp-referencetime,lumi,lumierror,beam1intensity,beam2intensity,speclumi[0],speclumi[1]])
00122     return fillbypos
00123 
00124 #####output methods####
00125 def filltofiles(allfills,runsperfill,runtimes,dirname):
00126     f=open(os.path.join(dirname,allfillname),'w')
00127     for fill in allfills:
00128         print >>f,'%d'%(fill)
00129     f.close()
00130     for fill,runs in runsperfill.items():
00131         filename='fill_'+str(fill)+'.txt'
00132         if len(runs)!=0:
00133             f=open(os.path.join(dirname,filename),'w')
00134             for run in runs:
00135                 print >>f,'%d,%s'%(run,runtimes[run])
00136             f.close()
00137             
00138 def specificlumiTofile(fillnum,filldata,outdir):
00139     timedict={}#{lstime:[[lumi,lumierr,speclumi,speclumierr]]}
00140     ipnumber=5
00141     for cmsbxidx,perbxdata in filldata.items():
00142         lhcbucket=0
00143         if cmsbxidx!=0:
00144             lhcbucket=(cmsbxidx-1)*10+1
00145         a=sorted(perbxdata,key=lambda x:x[0])
00146         lscounter=0
00147         filename=str(fillnum)+'_lumi_'+str(lhcbucket)+'_CMS.txt'
00148         for perlsdata in a:
00149             if perlsdata[-2]>0 and perlsdata[-1]>0 and perlsdata[1]>0:
00150                 if lscounter==0:
00151                     f=open(os.path.join(outdir,filename),'w')
00152                 print >>f, '%d\t%d\t%d\t%e\t%e\t%e\t%e\n'%(int(ipnumber),int(fillnum),int(perlsdata[0]),perlsdata[1],perlsdata[2],perlsdata[-2],perlsdata[-1])
00153                 if not timedict.has_key(int(perlsdata[0])):
00154                     timedict[int(perlsdata[0])]=[]
00155                 timedict[int(perlsdata[0])].append([perlsdata[1],perlsdata[2],perlsdata[-2],perlsdata[-1]])
00156                 lscounter+=1
00157         f.close()
00158         summaryfilename=str(fillnum)+'_lumi_CMS.txt'
00159         f=open(os.path.join(outdir,summaryfilename),'w')
00160         lstimes=timedict.keys()
00161         lstimes.sort()
00162         for lstime in lstimes:
00163             allvalues=timedict[lstime]
00164             transposedvalues=CommonUtil.transposed(allvalues,0.0)
00165             lumivals=transposedvalues[0]
00166             lumitot=sum(lumivals)
00167             lumierrs=transposedvalues[1]
00168             lumierrortot=math.sqrt(sum(map(lambda x:x**2,lumierrs)))
00169             specificvals=transposedvalues[2]
00170             specificavg=sum(specificvals)/float(len(specificvals))#avg spec lumi
00171             specificerrs=transposedvalues[3]
00172             specifictoterr=math.sqrt(sum(map(lambda x:x**2,specificerrs)))
00173             specificerravg=specifictoterr/float(len(specificvals))
00174             print >>f,'%d\t%d\t%d\t%e\t%e\t%e\t%e\n'%(int(ipnumber),int(fillnum),lstime,lumitot,lumierrortot,specificavg,specificerravg)
00175         f.close()
00176 if __name__ == '__main__':
00177     parser = argparse.ArgumentParser(prog=os.path.basename(sys.argv[0]),description = "Dump Fill",formatter_class=argparse.ArgumentDefaultsHelpFormatter)
00178     # parse arguments
00179     parser.add_argument('-c',dest='connect',action='store',required=False,help='connect string to lumiDB,optional',default='frontier://LumiCalc/CMS_LUMI_PROD')
00180     parser.add_argument('-P',dest='authpath',action='store',help='path to authentication file,optional')
00181     parser.add_argument('-i',dest='inputdir',action='store',required=False,help='output dir',default='.')
00182     parser.add_argument('-o',dest='outputdir',action='store',required=False,help='output dir',default='.')
00183     parser.add_argument('-f',dest='fillnum',action='store',required=False,help='specific fill',default=None)
00184     parser.add_argument('-siteconfpath',dest='siteconfpath',action='store',help='specific path to site-local-config.xml file, optional. If path undefined, fallback to cern proxy&server')
00185     parser.add_argument('--debug',dest='debug',action='store_true',help='debug')
00186     parser.add_argument('--toscreen',dest='toscreen',action='store_true',help='dump to screen')
00187     options=parser.parse_args()
00188     if options.authpath:
00189         os.environ['CORAL_AUTH_PATH'] = options.authpath
00190     parameters = lumiQueryAPI.ParametersObject()
00191     session,svc =  lumiQueryAPI.setupSession (options.connect or \
00192                                               'frontier://LumiCalc/CMS_LUMI_PROD',
00193                                                options.siteconfpath,parameters,options.debug)
00194 
00195     ##
00196     #query DB for all fills and compare with allfills.txt
00197     #if found newer fills, store  in mem fill number
00198     #reprocess anyway the last 5 fills in the dir
00199     #redo specific lumi for all marked fills
00200     ##
00201  
00202     allfillsFromFile=[]
00203     fillstoprocess=[]
00204     session.transaction().start(True)
00205     if options.fillnum: #if process a specific single fill
00206         fillstoprocess.append(int(options.fillnum))
00207     else: #if process fills automatically
00208         q=session.nominalSchema().newQuery()    
00209         allfillsFromDB=lumiQueryAPI.allfills(q)
00210         del q
00211         if os.path.exists(os.path.join(options.inputdir,allfillname)):
00212             allfillF=open(os.path.join(options.inputdir,allfillname),'r')
00213             for line in allfillF:
00214                 l=line.strip()
00215                 allfillsFromFile.append(int(l))
00216             allfillF.close()
00217             if len(allfillsFromDB)==0:
00218                 print 'no fill found in DB, exit'
00219                 sys.exit(-1)
00220             if len(allfillsFromDB)!=0:
00221                 allfillsFromDB.sort()
00222             if len(allfillsFromFile) != 0:
00223                 allfillsFromFile.sort()
00224             #print 'allfillsFromFile ',allfillsFromFile
00225             if max(allfillsFromDB)>max(allfillsFromFile) : #need not to be one to one match because data can be deleted in DB
00226                 print 'found new fill '
00227                 for fill in allfillsFromDB:
00228                     if fill>max(allfillsFromFile):
00229                         fillstoprocess.append(fill)
00230             else:
00231                 print 'no new fill '
00232                 fillstoprocess+=allfillsFromFile[-1:]
00233             #if len(allfillsFromFile)>5: #reprocess anyway old fills
00234             #    fillstoprocess+=allfillsFromFile[-5:]
00235         else:
00236             fillstoprocess=allfillsFromDB #process everything from scratch
00237     #print 'fillstoprocess ',fillstoprocess
00238     runsperfillFromDB={}
00239     q=session.nominalSchema().newQuery()
00240     runsperfillFromDB=lumiQueryAPI.runsByfillrange(q,int(min(fillstoprocess)),int(max(fillstoprocess)))
00241     del q
00242     #print 'runsperfillFromDB ',runsperfillFromDB
00243     runtimes={}
00244     runs=runsperfillFromDB.values()#list of lists
00245     allruns=[item for sublist in runs for item in sublist]
00246     allruns.sort()
00247     #print 'allruns ',allruns
00248     for run in allruns:
00249         q=session.nominalSchema().newQuery()
00250         runtimes[run]=lumiQueryAPI.runsummaryByrun(q,run)[3]
00251         del q
00252     #write specificlumi to outputdir
00253     #update inputdir
00254     if len(fillstoprocess)!=0 and options.fillnum is None:
00255         filltofiles(allfillsFromDB,runsperfillFromDB,runtimes,options.inputdir)
00256     print '===== Start Processing Fills',fillstoprocess
00257     print '====='
00258     for fillnum in fillstoprocess:
00259         filldata=getSpecificLumi(session,parameters,fillnum,options.inputdir)
00260         specificlumiTofile(fillnum,filldata,options.outputdir)
00261     session.transaction().commit()