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