2 from __future__
import print_function
3 from builtins
import range
7 from RecoLuminosity.LumiDB
import pileupParser
8 from RecoLuminosity.LumiDB
import selectionParser
14 output ({run:[ls:[inlumi, meanint]]})
16 selectf=open(inputfilename,
'r')
17 inputfilecontent=selectf.read()
21 runlsbyfile=p.runsandls()
35 cErf = 1.0 - (b1*T + b2*T*T + b3*T*T*T)*
exp(-1.0*X*X)
58 lumiinfo:[intlumi per LS, mean interactions ]
60 intlumi is the deadtime corrected average integrated lumi per lumisection
63 LSintLumi = lumiInfo[0]
64 RMSInt = lumiInfo[1]*minbXsec
65 AveNumInt = lumiInfo[2]*minbXsec
79 BinWidth = hist.GetBinWidth(1)
87 for obs
in range (Nbins):
93 left = hist.GetBinLowEdge(obs+1)
96 argR = (AveNumInt-right)/Sqrt2/RMSInt
100 argL = (AveNumInt-left)/Sqrt2/RMSInt
106 NewProb = (AreaL-AreaR)*0.5
108 ProbFromRMS.append(NewProb)
113 obs = hist.FindBin(AveNumInt)
114 for bin
in range (Nbins):
115 ProbFromRMS.append(0.0)
117 ProbFromRMS[obs] = 1.0
118 if AveNumInt < 1.0E-5:
119 ProbFromRMS[obs] = 0.
121 if calcOption ==
'true':
124 for obs
in range (Nbins):
125 prob = ProbFromRMS[obs]
126 val = hist.GetBinCenter(obs+1)
129 hist.Fill (val, prob * LSintLumi)
131 if 1.0-totalProb > 0.01:
132 print(
"Run %d, LS %d: Significant probability density outside of your histogram (mean %.2f," % (run, ls, AveNumInt))
133 print(
"rms %.2f, integrated probability %.3f). Consider using a higher value of --maxPileupBin." % (RMSInt, totalProb))
135 hist.Fill(AveNumInt,LSintLumi)
139 BinWidth = hist.GetBinWidth(1)
140 for obs
in range (Nbins):
141 Peak = hist.GetBinCenter(obs+1)
142 RMSWeight = ProbFromRMS[obs]
143 for bin
in range (Nbins):
144 val = hist.GetBinCenter(bin+1)-0.5*BinWidth
145 prob = ROOT.TMath.Poisson (val, Peak)
147 hist.Fill (val, prob * LSintLumi * RMSWeight)
149 if 1.0-totalProb > 0.01:
150 print(
"Run %d, LS %d: significant probability density outside of your histogram" % (run, ls))
151 print(
"Consider using a higher value of --maxPileupBin")
166 if __name__ ==
'__main__':
168 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.")
171 req_group = parser.add_argument_group(
'required arguments')
172 req_group.add_argument(
'outputfile', action=
'store', help=
'output ROOT file')
173 req_group.add_argument(
'-i',
'--input', dest=
'inputfile', action=
'store', required=
True,
174 help=
'input Run/LS file for your analysis in JSON format')
175 req_group.add_argument(
'-j',
'--inputLumiJSON', dest=
'inputLumiJSON', action=
'store', required=
True,
176 help=
'input pileup file in JSON format')
177 req_group.add_argument(
'-c',
'--calcMode' ,dest=
'calcMode', action=
'store',
178 help=
'calculate either "true" or "observed" distributions',
179 choices=[
'true',
'observed'], required=
True)
182 parser.add_argument(
'-x',
'--minBiasXsec', dest=
'minBiasXsec', action=
'store',
183 type=float, default=69200.0,
184 help=
'minimum bias cross section to use (in microbarn) (default: %(default).0f)')
185 parser.add_argument(
'-m',
'--maxPileupBin', dest=
'maxPileupBin', action=
'store',
186 type=int, default=100, help=
'maximum value of pileup histogram (default: %(default)d)')
187 parser.add_argument(
'-n',
'--numPileupBins', dest=
'numPileupBins', action=
'store',
188 type=int, default=1000, help=
'number of bins in pileup histogram (default: %(default)d)')
189 parser.add_argument(
'--pileupHistName', dest=
'pileupHistName', action=
'store',
190 default=
'pileup', help=
'name of pileup histogram (default: %(default)s)')
191 parser.add_argument(
'-v',
'--verbose', dest=
'verbose', action=
'store_true',
192 help=
'verbose mode for printing' )
194 options = parser.parse_args()
195 output = options.outputfile
198 print(
'General configuration')
199 print(
'\toutputfile:' ,options.outputfile)
200 print(
'\tAction:' ,options.calcMode,
'luminosity distribution will be calculated')
201 print(
'\tinput selection file:', options.inputfile)
202 print(
'\tinput lumi JSON:', options.inputLumiJSON)
203 print(
'\tMinBiasXsec:', options.minBiasXsec)
204 print(
'\tmaxPileupBin:', options.maxPileupBin)
205 print(
'\tnumPileupBins:', options.numPileupBins)
208 pileupHist = ROOT.TH1D (options.pileupHistName,options.pileupHistName,
209 options.numPileupBins,
210 0., options.maxPileupBin)
212 nbins = options.numPileupBins
213 upper = options.maxPileupBin
215 inpf = open(options.inputfile,
'r')
216 inputfilecontent = inpf.read()
226 for (run, lslist)
in sorted (inputRange.items()):
229 if run
in inputPileupRange.keys():
231 LSPUlist = inputPileupRange[run]
233 for LSnumber
in lslist:
234 if LSnumber
in LSPUlist.keys():
236 lumiInfo = LSPUlist[LSnumber]
239 options.minBiasXsec, nbins, run, LSnumber)
241 print(
"Run %d, LumiSection %d not found in Lumi/Pileup input file. Check your files!" \
245 print(
"Run %d not found in Lumi/Pileup input file. Check your files!" % (run))
250 histFile = ROOT.TFile.Open(output,
'recreate')
252 raise RuntimeError(
"Could not open '%s' as an output root file" % output)
257 print(
"Wrote output histogram to", output)