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