CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/RecoLuminosity/LumiDB/scripts/pileupCalc.py

Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 VERSION='1.00'
00003 import os,sys,time
00004 import optparse
00005 from RecoLuminosity.LumiDB import pileupParser
00006 from RecoLuminosity.LumiDB import selectionParser
00007 from math import exp
00008 from math import sqrt
00009 
00010 def parseInputFile(inputfilename):
00011     '''
00012     output ({run:[ls:[inlumi, meanint]]})
00013     '''
00014     selectf=open(inputfilename,'r')
00015     inputfilecontent=selectf.read()
00016     p=pileupParser.pileupParser(inputfilecontent)                            
00017     
00018 #    p=inputFilesetParser.inputFilesetParser(inputfilename)
00019     runlsbyfile=p.runsandls()
00020     return runlsbyfile
00021 
00022 def fillPileupHistogram (lumiInfo, calcOption, hist, minbXsec, Nbins):
00023     '''
00024     lumiinfo:[intlumi per LS, mean interactions ]
00025 
00026     intlumi is the deadtime corrected average integraged lumi per lumisection
00027     '''
00028 
00029     LSintLumi = lumiInfo[0]
00030     RMSInt = lumiInfo[1]*minbXsec
00031     AveNumInt = lumiInfo[2]*minbXsec
00032 
00033     coeff = 0
00034     if RMSInt > 0:
00035         coeff = 1.0/RMSInt/sqrt(6.283185)
00036     expon = 2.0*RMSInt*RMSInt
00037 
00038     ##Nbins = hist.GetXaxis().GetNbins()
00039 
00040     ProbFromRMS = []
00041 
00042     # First, re-constitute lumi distribution for this LS from RMS:
00043     if RMSInt > 0:
00044         for obs in range (Nbins):
00045             val = hist.GetBinCenter(obs+1)
00046             prob = coeff*exp(-1.0*(val-AveNumInt)*(val-AveNumInt)/expon)
00047             ProbFromRMS.append(prob)
00048     else:
00049         obs = hist.FindBin(AveNumInt)
00050         for bin in range (Nbins):
00051             ProbFromRMS.append(0.0)
00052         ProbFromRMS[obs] = 1.0
00053         if AveNumInt < 1.0E-5:
00054            ProbFromRMS[obs] = 0.  # just ignore zero values
00055         
00056     if calcOption == 'true':  # Just put distribution into histogram
00057         if RMSInt > 0:
00058             totalProb = 0
00059             for obs in range (Nbins):
00060                 prob = ProbFromRMS[obs]
00061                 val = hist.GetBinCenter(obs+1)
00062                 # print obs, val, RMSInt,coeff,expon,prob
00063                 totalProb += prob
00064                 hist.Fill (val, prob * LSintLumi)
00065             if totalProb < 1:
00066                 hist.Fill (val, (1 - totalProb) * LSintLumi)
00067         else:
00068             hist.Fill(AveNumInt,LSintLumi)
00069     else: # have to convolute with a poisson distribution to get observed Nint
00070         totalProb = 0
00071         Peak = 0
00072         BinWidth = hist.GetBinWidth(1)
00073         for obs in range (Nbins):
00074             Peak = hist.GetBinCenter(obs+1)
00075             RMSWeight = ProbFromRMS[obs]
00076             for bin in range (Nbins):
00077                 val = hist.GetBinCenter(bin+1)-0.5*BinWidth
00078                 prob = ROOT.TMath.Poisson (val, Peak)
00079                 totalProb += prob
00080                 hist.Fill (val, prob * LSintLumi * RMSWeight)
00081         if totalProb < 1:
00082             hist.Fill (Peak, (1 - totalProb) * LSintLumi)
00083 
00084     return hist
00085 
00086 
00087 
00088 ##############################
00089 ## ######################## ##
00090 ## ## ################## ## ##
00091 ## ## ## Main Program ## ## ##
00092 ## ## ################## ## ##
00093 ## ######################## ##
00094 ##############################
00095 
00096 if __name__ == '__main__':
00097 
00098     parser = optparse.OptionParser ("Usage: %prog [--options] output.root",
00099                                     description = "Script to estimate pileup distribution using xing instantaneous luminosity information and minimum bias cross section.  Output is TH1D stored in root file")
00100 #
00101 #    parser = argparse.ArgumentParser(prog=os.path.basename(sys.argv[0]),description = "Pileup Lumi Calculation",formatter_class=argparse.ArgumentDefaultsHelpFormatter)
00102     CalculationModeChoices = ['truth', 'observed']
00103 
00104     #
00105     # parse arguments
00106     #  
00107     #
00108     # basic arguments
00109     #
00110     #parser.add_argument('action',choices=allowedActions,
00111     #                    help='command actions')
00112     parser.add_option('-o',dest='outputfile',action='store',
00113                         default='PileupCalc.root',
00114                         help='output root file')
00115     parser.add_option('-i',dest='inputfile',action='store',
00116                         help='Input Run/LS file for your analysis in JSON format (required)')
00117     parser.add_option('--inputLumiJSON',dest='inputLumiJSON',action='store',
00118                         help='Input Lumi/Pileup file in JSON format (required)')
00119     parser.add_option('--calcMode',dest='calcMode',action='store',
00120                         help='Calculate either True ="true" or Observed="observed" distributions')
00121     parser.add_option('--minBiasXsec',dest='minBiasXsec',action='store',
00122                         type=float,
00123                         default=73500,
00124                         help='Minimum bias cross section assumed (in microbbarn), default %default microbarn')
00125     parser.add_option('--maxPileupBin',dest='maxPileupBin',action='store',
00126                         type=int,
00127                         default=25,
00128                         help='Maximum value of pileup histogram, default %default')
00129     parser.add_option('--numPileupBins',dest='numPileupBins',action='store',
00130                         type=int,
00131                         default=1000,
00132                         help='number of bins in pileup histogram, default %default')
00133     parser.add_option('--pileupHistName',dest='pileupHistName',action='store',
00134                         default='pileup',
00135                         help='name of pileup histogram, default %default')
00136     parser.add_option('--verbose',dest='verbose',action='store_true',help='verbose mode for printing' )
00137     
00138     # parse arguments
00139     try:
00140         (options, args) = parser.parse_args()
00141     except Exception , e:
00142         print e
00143     if not args:
00144         parser.print_usage()
00145         sys.exit()
00146     if len (args) != 1:
00147         parser.print_usage()
00148         raise RuntimeError, "Exactly one output file must be given"
00149     output = args[0]
00150     
00151 #    options=parser.parse_args()
00152 
00153     if options.verbose:
00154         print 'General configuration'
00155         print '\toutputfile: ',options.outputfile
00156         print '\tAction: ',options.calcMode, 'luminosity distribution will be calculated'
00157         print '\tinput selection file: ',options.inputfile
00158         print '\tMinBiasXsec: ',options.minBiasXsec
00159         print '\tmaxPileupBin: ',options.maxPileupBin
00160         print '\tnumPileupBins: ',options.numPileupBins
00161 
00162     import ROOT 
00163     pileupHist = ROOT.TH1D (options.pileupHistName,options.pileupHistName,
00164                       options.numPileupBins,
00165                       0., options.maxPileupBin)
00166 
00167     nbins = options.numPileupBins
00168     upper = options.maxPileupBin
00169 
00170     inpf = open (options.inputfile, 'r')
00171     inputfilecontent = inpf.read()
00172     inputRange =  selectionParser.selectionParser (inputfilecontent).runsandls()
00173 
00174     #inputRange=inputFilesetParser.inputFilesetParser(options.inputfile)
00175 
00176     if options.calcMode in ['true','observed']:
00177         inputPileupRange=parseInputFile(options.inputLumiJSON)
00178 
00179         # now, we have to find the information for the input runs and LumiSections 
00180         # in the Lumi/Pileup list. First, loop over inputs
00181 
00182         for (run, lslist) in sorted (inputRange.iteritems() ):
00183             # now, look for matching run, then match lumi sections
00184             # print "searching for run %d" % (run)
00185             if run in inputPileupRange.keys():
00186                 # print run
00187                 LSPUlist = inputPileupRange[run]
00188                 # print "LSPUlist", LSPUlist
00189                 for LSnumber in lslist:
00190                     if LSnumber in LSPUlist.keys():
00191                         # print "found LS %d" % (LSnumber)
00192                         lumiInfo = LSPUlist[LSnumber]
00193                         # print lumiInfo
00194                         fillPileupHistogram (lumiInfo, options.calcMode,
00195                                 pileupHist, options.minBiasXsec, nbins)
00196                     else: # trouble
00197                         print "Run %d, LumiSection %d not found in Lumi/Pileup input file. Check your files!" \
00198                                 % (run,LSnumber)
00199 
00200             else:  # trouble
00201                 print "Run %d not found in Lumi/Pileup input file.  Check your files!" % (run)
00202 
00203 
00204 
00205 #            print run
00206 #            print lslist
00207 
00208         histFile = ROOT.TFile.Open (output, 'recreate')
00209         if not histFile:
00210             raise RuntimeError, \
00211                  "Could not open '%s' as an output root file" % output
00212         pileupHist.Write()
00213         #for hist in histList:
00214         #    hist.Write()
00215         histFile.Close()
00216         sys.exit()
00217 
00218     else:
00219         print "must specify a pileup calculation mode via --calcMode true or --calcMode observed"
00220         sys.exit()