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