2 from __future__
import print_function
3 from builtins
import range
7 from RecoLuminosity.LumiDB
import pileupParser
8 from RecoLuminosity.LumiDB
import selectionParser
15 output ({run:[ls:[inlumi, meanint]]}) 17 selectf=open(inputfilename,
'r') 18 inputfilecontent=selectf.read() 22 runlsbyfile=p.runsandls()
36 cErf = 1.0 - (b1*T + b2*T*T + b3*T*T*T)*
exp(-1.0*X*X)
59 lumiinfo:[intlumi per LS, mean interactions ] 61 intlumi is the deadtime corrected average integrated lumi per lumisection 64 LSintLumi = lumiInfo[0]
65 RMSInt = lumiInfo[1]*minbXsec
66 AveNumInt = lumiInfo[2]*minbXsec
80 BinWidth = hist.GetBinWidth(1)
88 for obs
in range (Nbins):
94 left = hist.GetBinLowEdge(obs+1)
97 argR = (AveNumInt-right)/Sqrt2/RMSInt
101 argL = (AveNumInt-left)/Sqrt2/RMSInt
107 NewProb = (AreaL-AreaR)*0.5
109 ProbFromRMS.append(NewProb)
114 obs = hist.FindBin(AveNumInt)
115 for bin
in range (Nbins):
116 ProbFromRMS.append(0.0)
118 ProbFromRMS[obs] = 1.0
119 if AveNumInt < 1.0E-5:
120 ProbFromRMS[obs] = 0.
122 if calcOption ==
'true':
125 for obs
in range (Nbins):
126 prob = ProbFromRMS[obs]
127 val = hist.GetBinCenter(obs+1)
130 hist.Fill (val, prob * LSintLumi)
132 if 1.0-totalProb > 0.01:
133 print(
"Run %d, LS %d: Significant probability density outside of your histogram (mean %.2f," % (run, ls, AveNumInt))
134 print(
"rms %.2f, integrated probability %.3f). Consider using a higher value of --maxPileupBin." % (RMSInt, totalProb))
136 hist.Fill(AveNumInt,LSintLumi)
140 BinWidth = hist.GetBinWidth(1)
141 for obs
in range (Nbins):
142 Peak = hist.GetBinCenter(obs+1)
143 RMSWeight = ProbFromRMS[obs]
144 for bin
in range (Nbins):
145 val = hist.GetBinCenter(bin+1)-0.5*BinWidth
146 prob = ROOT.TMath.Poisson (val, Peak)
148 hist.Fill (val, prob * LSintLumi * RMSWeight)
150 if 1.0-totalProb > 0.01:
151 print(
"Run %d, LS %d: significant probability density outside of your histogram" % (run, ls))
152 print(
"Consider using a higher value of --maxPileupBin")
167 if __name__ ==
'__main__':
169 parser = argparse.ArgumentParser(description =
"Script to estimate pileup distribution using bunch instantaneous luminosity information and minimum bias cross section. Outputs a TH1D of the pileup distribution stored in a ROOT file.")
172 req_group = parser.add_argument_group(
'required arguments')
173 req_group.add_argument(
'outputfile', action=
'store', help=
'output ROOT file')
174 req_group.add_argument(
'-i',
'--input', dest=
'inputfile', action=
'store', required=
True,
175 help=
'input Run/LS file for your analysis in JSON format')
176 req_group.add_argument(
'-j',
'--inputLumiJSON', dest=
'inputLumiJSON', action=
'store', required=
True,
177 help=
'input pileup file in JSON format')
178 req_group.add_argument(
'-c',
'--calcMode' ,dest=
'calcMode', action=
'store',
179 help=
'calculate either "true" or "observed" distributions',
180 choices=[
'true',
'observed'], required=
True)
183 parser.add_argument(
'-x',
'--minBiasXsec', dest=
'minBiasXsec', action=
'store',
184 type=float, default=69200.0,
185 help=
'minimum bias cross section to use (in microbarn) (default: %(default).0f)')
186 parser.add_argument(
'-m',
'--maxPileupBin', dest=
'maxPileupBin', action=
'store',
187 type=int, default=100, help=
'maximum value of pileup histogram (default: %(default)d)')
188 parser.add_argument(
'-n',
'--numPileupBins', dest=
'numPileupBins', action=
'store',
189 type=int, default=1000, help=
'number of bins in pileup histogram (default: %(default)d)')
190 parser.add_argument(
'--pileupHistName', dest=
'pileupHistName', action=
'store',
191 default=
'pileup', help=
'name of pileup histogram (default: %(default)s)')
192 parser.add_argument(
'-v',
'--verbose', dest=
'verbose', action=
'store_true',
193 help=
'verbose mode for printing' )
195 options = parser.parse_args()
196 output = options.outputfile
199 print(
'General configuration')
200 print(
'\toutputfile:' ,options.outputfile)
201 print(
'\tAction:' ,options.calcMode,
'luminosity distribution will be calculated')
202 print(
'\tinput selection file:', options.inputfile)
203 print(
'\tinput lumi JSON:', options.inputLumiJSON)
204 print(
'\tMinBiasXsec:', options.minBiasXsec)
205 print(
'\tmaxPileupBin:', options.maxPileupBin)
206 print(
'\tnumPileupBins:', options.numPileupBins)
209 pileupHist = ROOT.TH1D (options.pileupHistName,options.pileupHistName,
210 options.numPileupBins,
211 0., options.maxPileupBin)
213 nbins = options.numPileupBins
214 upper = options.maxPileupBin
216 inpf = open(options.inputfile,
'r') 217 inputfilecontent = inpf.read() 227 for (run, lslist)
in sorted (six.iteritems(inputRange)):
230 if run
in inputPileupRange.keys():
232 LSPUlist = inputPileupRange[run]
234 for LSnumber
in lslist:
235 if LSnumber
in LSPUlist.keys():
237 lumiInfo = LSPUlist[LSnumber]
240 options.minBiasXsec, nbins, run, LSnumber)
242 print(
"Run %d, LumiSection %d not found in Lumi/Pileup input file. Check your files!" \
246 print(
"Run %d not found in Lumi/Pileup input file. Check your files!" % (run))
251 histFile = ROOT.TFile.Open(output,
'recreate')
253 raise RuntimeError(
"Could not open '%s' as an output root file" % output)
258 print(
"Wrote output histogram to", output)
def parseInputFile(inputfilename)
S & print(S &os, JobReport::InputFile const &f)
Abs< T >::type abs(const T &t)
def fillPileupHistogram(lumiInfo, calcOption, hist, minbXsec, Nbins, run, ls)