2 from __future__
import print_function
7 from RecoLuminosity.LumiDB
import sessionManager,csvSelectionParser,selectionParser,lumiCorrections,lumiCalcAPI
10 beamChoices=[
'PROTPHYS',
'IONPHYS']
21 runNumber=0, hist =
None, debug =
False):
23 bxlumiinfo:[[cmslsnum(0),avgdelivered(1),avgrecorded(2),bxlumiarray[3]]] 25 Given luminfo , deadfrac info and run number, will (create if necessary 26 and) fill histogram with expected pileup distribution. If a 27 histogram is created, it is owned by the user and is his/her 28 responsibility to clean up the memory.''' 30 maxBin = hist.GetNbinsX()
31 upper =
int( hist.GetBinLowEdge(maxBin) + \
32 hist.GetBinWidth(maxBin) + 0.25 )
34 histname =
'%s_%s' % (pileupHistName, runNumber)
35 hist = ROOT.TH1D (histname, histname, maxPileupBin + 1,
36 -0.5,maxPileupBin + 0.5)
39 for perlsinfo
in bxlumiinfo:
41 avgdelivered=perlsinfo[1]
42 avgrecorded=perlsinfo[2]
51 livetime=avgrecorded/avgdelivered
54 for idx,bxvalue
in enumerate(bxvaluelist):
55 xingIntLumi=bxvalue * p.lumiSectionLen * livetime
56 if options.minBiasXsec:
57 mean = bxvalue * options.minBiasXsec * p.rotationTime
59 mean = bxvalue * p.minBiasXsec * p.rotationTime
62 print(
"mean number of pileup events > 100 for run %d, lum %d : m %f l %f" % \
63 (runNumber, lumiSection, mean, bxvalue))
65 print(
"mean number of pileup events > 100 for lum %d: m %f l %f" % \
66 (cmslsnum, mean, bxvalue))
68 for obs
in range (upper):
69 prob = ROOT.TMath.Poisson (obs, mean)
71 hist.Fill (obs, prob * xingIntLumi)
74 print(
"ls", lumiSection,
"xing", xing,
"inst", bxvalue, \
75 "mean", mean,
"totalProb", totalProb, 1 - totalProb)
76 print(
" hist mean", hist.GetMean())
78 hist.Fill (obs, (1 - totalProb) * xingIntLumi)
89 if __name__ ==
'__main__':
90 beamModeChoices = [
"",
"stable",
"quiet",
"either"]
91 amodetagChoices = [
"PROTPHYS",
"IONPHYS" ]
92 xingAlgoChoices =[
"OCC1",
"OCC2",
"ET"]
93 parser = optparse.OptionParser (
"Usage: %prog [--options] output.root",
94 description =
"Script to estimate pileup distribution using xing instantaneous luminosity information and minimum bias cross section. Output is TH1D stored in root file")
95 dbGroup = optparse.OptionGroup (parser,
"Database Options")
96 inputGroup = optparse.OptionGroup (parser,
"Input Options")
97 pileupGroup = optparse.OptionGroup (parser,
"Pileup Options")
98 dbGroup.add_option (
'-c', dest =
'connect', action =
'store',
99 default=
'frontier://LumiCalc/CMS_LUMI_PROD',
100 help =
'connect string to lumiDB ,default %default')
101 dbGroup.add_option (
'-P', dest =
'authpath', action =
'store',
102 help =
'path to authentication file')
103 dbGroup.add_option (
'--siteconfpath', dest =
'siteconfpath', action =
'store',
104 help =
'specific path to site-local-config.xml file, default to $CMS_PATH/SITECONF/local/JobConfig, ' \
105 'if path undefined, fallback to cern proxy&server')
106 dbGroup.add_option (
'--debug', dest =
'debug', action =
'store_true',
109 inputGroup.add_option (
'-r', dest =
'runnumber', action =
'store',
111 inputGroup.add_option (
'-i', dest =
'inputfile', action =
'store',
112 help =
'lumi range selection file')
113 inputGroup.add_option (
'-b', dest =
'beamstatus', default=
'', choices=beamModeChoices,
114 help =
"beam mode, optional for delivered action, default ('%%default' out of %s)" % beamModeChoices)
115 inputGroup.add_option (
'--hltpath', dest =
'hltpath', action =
'store',
116 help =
'specific hltpath to calculate the recorded luminosity, default to all')
117 inputGroup.add_option (
'--csvInput', dest =
'csvInput', type=
'string', default=
'',
118 help =
'Use CSV file from lumiCalc2.py instead of lumiDB')
119 inputGroup.add_option (
'--without-correction', dest =
'withoutFineCorrection', action=
'store_true',
120 help =
'not apply fine correction on calibration')
121 pileupGroup.add_option(
'--algoname',dest=
'algoname',default=
'OCC1',
122 help =
'lumi algorithm , default %default')
123 pileupGroup.add_option (
'--xingMinLum', dest =
'xingMinLum', type=
'float', default = 1.0e-3,
124 help =
'Minimum luminosity considered for "lsbylsXing" action, default %default')
125 pileupGroup.add_option (
'--minBiasXsec', dest =
'minBiasXsec', type=
'float', default = 71300,
126 help =
'Minimum bias cross section assumed (in mb), default %default mb')
127 pileupGroup.add_option (
'--histName', dest=
'pileupHistName', type=
'string', default =
'pileup',
128 help =
'Histrogram name (default %default)')
129 pileupGroup.add_option (
'--maxPileupBin', dest=
'maxPileupBin', type=
'int', default = 10,
130 help =
'Maximum bin in pileup histogram (default %default)')
131 pileupGroup.add_option (
'--saveRuns', dest=
'saveRuns', action=
'store_true',
132 help =
'Save pileup histograms for individual runs')
133 pileupGroup.add_option (
'--debugLumi', dest=
'debugLumi',
135 help =
'Print out debug info for individual lumis')
136 pileupGroup.add_option (
'--nowarning', dest =
'nowarning',
137 action =
'store_true', default =
False,
138 help =
'suppress bad for lumi warnings' )
139 parser.add_option_group (dbGroup)
140 parser.add_option_group (inputGroup)
141 parser.add_option_group (pileupGroup)
144 (options, args) = parser.parse_args()
145 except Exception
as e:
152 raise RuntimeError(
"Exactly one output file must be given")
157 os.environ[
'CORAL_AUTH_PATH'] = options.authpath
161 if not options.inputfile
and not options.runnumber
and not options.csvInput:
162 raise "must specify either a run (-r), an input run selection file (-i), or an input CSV file (--csvInput)" 170 sepRE = re.compile (
r'[\s,;:]+')
171 events = open (options.csvInput,
'r') 173 pieces = sepRE.split (line.strip())
180 run, cmslsnum = int ( pieces[0] ), int ( pieces[1] )
182 xingIdx = [
int(myidx)
for myidx
in pieces[4::2] ]
183 xingVal = [
float(myval)
for myval
in pieces[5::2] ]
190 runDict.setdefault(run,[]).
append([cmslsnum,delivered,recorded,(xingIdx,xingVal)])
194 session=svc.openSession(isReadOnly=
True,cpp2sqltype=[(
'unsigned int',
'NUMBER(10)'),(
'unsigned long long',
'NUMBER(20)')])
196 if options.runnumber:
197 inputRange = {
int(options.runnumber):
None}
199 basename, extension = os.path.splitext (options.inputfile)
200 if extension ==
'.csv':
204 f = open (options.inputfile,
'r') 205 inputfilecontent = f.read() 208 print(
'failed to parse the input file', options.inputfile)
210 if not options.withoutFineCorrection:
211 rruns=inputRange.keys()
212 schema=session.nominalSchema()
213 session.transaction().
start(
True)
214 finecorrections=lumiCorrections.correctionsForRange(schema,rruns)
215 session.transaction().commit()
216 session.transaction().
start(
True)
217 schema=session.nominalSchema()
218 lumiData=lumiCalcAPI.lumiForRange(schema,inputRange,beamstatus=options.beamstatus,withBXInfo=
True,bxAlgo=options.algoname,xingMinLum=options.xingMinLum,withBeamIntensity=
False,datatag=
None,finecorrections=finecorrections)
219 session.transaction().commit()
222 for runnum,perrundata
in lumiData.items():
224 for perlsdata
in perrundata:
225 cmslsnum=perlsdata[1]
226 deliveredlumi=perlsdata[5]
227 recordedlumi=perlsdata[6]
229 bxlumiinfo.append([cmslsnum,deliveredlumi,recordedlumi,bxlist])
230 runDict.setdefault(runnum,[]).
append([cmslsnum,deliveredlumi,recordedlumi,bxlist])
234 pileupHist = ROOT.TH1D (options.pileupHistName,options.pileupHistName,
235 options.maxPileupBin + 1,
236 -0.5, options.maxPileupBin + 0.5)
238 for runNumber, lumiList
in sorted( six.iteritems(runDict) ):
240 hist = fillPileupHistogram (lumiList,options.pileupHistName,options.maxPileupBin,
241 runNumber = runNumber,
242 debug = options.debugLumi)
243 pileupHist.Add (hist)
244 histList.append (hist)
246 fillPileupHistogram (lumiList, options.pileupHistName,options.maxPileupBin,
248 debug = options.debugLumi)
249 histFile = ROOT.TFile.Open (output,
'recreate')
251 raise RuntimeError(
"Could not open '%s' as an output root file" % output)
253 for hist
in histList:
S & print(S &os, JobReport::InputFile const &f)
def fillPileupHistogram(bxlumiinfo, pileupHistName, maxPileupBin, runNumber=0, hist=None, debug=False)