2 from __future__
import print_function
7 from RecoLuminosity.LumiDB
import csvSelectionParser, selectionParser
8 import RecoLuminosity.LumiDB.lumiQueryAPI
as LumiQueryAPI
11 from pprint
import pprint
15 runNumber = 0, hist =
None, debug =
False,
17 '''Given a deadtable and run number, will (create if necessary 18 and) fill histogram with expected pileup distribution. If a 19 histogram is created, it is owned by the user and is his/her 20 responsibility to clean up the memory.''' 22 maxBin = hist.GetNbinsX()
23 upper =
int( hist.GetBinLowEdge(maxBin) + \
24 hist.GetBinWidth(maxBin) + 0.25 )
26 histname =
'%s_%s' % (parameters.pileupHistName, runNumber)
27 hist = ROOT.TH1D (histname, histname, parameters.maxPileupBin + 1,
28 -0.5, parameters.maxPileupBin + 0.5)
29 upper = parameters.maxPileupBin
30 for lumiSection, deadArray
in sorted (six.iteritems(deadTable)):
32 numerator = float (deadArray[1])
33 denominator = float (deadArray[0])
34 instLumiArray = deadArray[2]
39 livetime = numerator / denominator
42 if len(deadArray) <= parameters.xingIndex:
46 if parameters.noWarnings:
49 print(
"No Xing Instantaneous luminosity information for run %d, lumi section %d" \
50 % (runNumber, lumiSection))
52 print(
"No Xing Instantaneous luminosity information for lumi section %d" \
55 numerator = float (deadArray[0])
56 denominator = float (deadArray[2] * deadArray[4])
57 xingInstLumiArray = deadArray[parameters.xingIndex]
60 instLumiArray = [(xingInstLumiArray[index], xingInstLumiArray[index + 1]) \
61 for index
in xrange( 0, len (xingInstLumiArray), 2 ) ]
66 livetime = 1 - numerator / denominator
68 for xing, xingInstLumi
in instLumiArray:
69 xingIntLumi = xingInstLumi * parameters.lumiSectionLen * livetime
70 mean = xingInstLumi * parameters.minBiasXsec * \
71 parameters.rotationTime
74 print(
"mean number of pileup events > 100 for run %d, lum %d : m %f l %f" % \
75 (runNumber, lumiSection, mean, xingInstLumi))
77 print(
"mean number of pileup events > 100 for lum %d: m %f l %f" % \
78 (lumiSection, mean, xingInstLumi))
80 for obs
in range (upper):
81 prob = ROOT.TMath.Poisson (obs, mean)
83 hist.Fill (obs, prob * xingIntLumi)
85 print(
"ls", lumiSection,
"xing", xing,
"inst", xingInstLumi, \
86 "mean", mean,
"totalProb", totalProb, 1 - totalProb)
87 print(
" hist mean", hist.GetMean())
89 hist.Fill (obs, (1 - totalProb) * xingIntLumi)
102 if __name__ ==
'__main__':
103 parameters = LumiQueryAPI.ParametersObject()
104 beamModeChoices = [
"",
"stable",
"quiet",
"either"]
105 parser = optparse.OptionParser (
"Usage: %prog [--options] output.root",
106 description =
"Script to estimate pileup distribution using xing instantaneous luminosity information and minimum bias cross section. Output is TH1D stored in root file")
107 dbGroup = optparse.OptionGroup (parser,
"Database Options")
108 inputGroup = optparse.OptionGroup (parser,
"Input Options")
109 pileupGroup = optparse.OptionGroup (parser,
"Pileup Options")
110 dbGroup.add_option (
'--parameters', dest =
'connect', action =
'store',
111 help =
'connect string to lumiDB (optional, default to frontier://LumiCalc/CMS_LUMI_PROD)')
112 dbGroup.add_option (
'-P', dest =
'authpath', action =
'store',
113 help =
'path to authentication file')
114 dbGroup.add_option (
'--siteconfpath', dest =
'siteconfpath', action =
'store',
115 help =
'specific path to site-local-config.xml file, default to $CMS_PATH/SITECONF/local/JobConfig, ' \
116 'if path undefined, fallback to cern proxy&server')
117 dbGroup.add_option (
'--debug', dest =
'debug', action =
'store_true',
119 inputGroup.add_option (
'-r', dest =
'runnumber', action =
'store',
121 inputGroup.add_option (
'-i', dest =
'inputfile', action =
'store',
122 help =
'lumi range selection file')
123 inputGroup.add_option (
'-b', dest =
'beammode', default=
'', choices=beamModeChoices,
124 help =
"beam mode, optional for delivered action, default ('%%default' out of %s)" % beamModeChoices)
125 inputGroup.add_option (
'--lumiversion', dest =
'lumiversion', type=
'string', default=
'0001',
126 help =
'lumi data version, optional for all, default %default')
127 inputGroup.add_option (
'--hltpath', dest =
'hltpath', action =
'store',
128 help =
'specific hltpath to calculate the recorded luminosity, default to all')
129 inputGroup.add_option (
'--csvInput', dest =
'csvInput', type=
'string', default=
'',
130 help =
'Use CSV file from lumiCalc.py instead of lumiDB')
131 pileupGroup.add_option (
'--xingMinLum', dest =
'xingMinLum', type=
'float', default = 1e-3,
132 help =
'Minimum luminosity considered for "lsbylsXing" action, default %default')
133 pileupGroup.add_option (
'--minBiasXsec', dest =
'minBiasXsec', type=
'float', default = parameters.minBiasXsec,
134 help =
'Minimum bias cross section assumed (in mb), default %default mb')
135 pileupGroup.add_option (
'--histName', dest=
'histName', type=
'string', default = parameters.pileupHistName,
136 help =
'Histrogram name (default %default)')
137 pileupGroup.add_option (
'--maxPileupBin', dest=
'maxPileupBin', type=
'int', default = parameters.maxPileupBin,
138 help =
'Maximum bin in pileup histogram (default %default)')
139 pileupGroup.add_option (
'--saveRuns', dest=
'saveRuns', action=
'store_true',
140 help =
'Save pileup histograms for individual runs')
141 pileupGroup.add_option (
'--debugLumi', dest=
'debugLumi',
143 help =
'Print out debug info for individual lumis')
144 pileupGroup.add_option (
'--nowarning', dest =
'nowarning',
145 action =
'store_true', default =
False,
146 help =
'suppress bad for lumi warnings' )
147 parser.add_option_group (dbGroup)
148 parser.add_option_group (inputGroup)
149 parser.add_option_group (pileupGroup)
151 (options, args) = parser.parse_args()
158 raise RuntimeError(
"Exactly one output file must be given")
163 os.environ[
'CORAL_AUTH_PATH'] = options.authpath
166 parameters.verbose =
True 167 parameters.noWarnings = options.nowarning
168 parameters.lumiXing =
True 169 parameters.lumiversion = options.lumiversion
170 if options.beammode==
'stable':
171 parameters.beammode =
'STABLE BEAMS' 172 parameters.xingMinLum = options.xingMinLum
173 parameters.minBiasXsec = options.minBiasXsec
174 parameters.pileupHistName = options.histName
175 parameters.maxPileupBin = options.maxPileupBin
178 LumiQueryAPI.setupSession (options.connect
or \
179 'frontier://LumiCalc/CMS_LUMI_PROD',
180 options.siteconfpath, parameters,options.debug)
183 if not options.inputfile
and not options.runnumber
and not options.csvInput:
184 raise "must specify either a run (-r), an input run selection file (-i), or an input CSV file (--csvInput)" 185 pileupHist = ROOT.TH1D(parameters.pileupHistName, parameters.pileupHistName,
193 sepRE = re.compile (
r'[\s,;:]+')
195 events = open (options.csvInput,
'r') 198 pieces = sepRE.split (line.strip())
205 run, lumi = int ( pieces[0] ), int ( pieces[2] )
208 for orbit, lum
in zip( pieces[9::2],
212 csvDict.setdefault (run, {})[lumi] = \
213 ( delivered, recorded, xingInstLumiArray )
215 for runNumber, lumiDict
in sorted( six.iteritems(csvDict) ):
217 hist = fillPileupHistogram (lumiDict, parameters,
218 runNumber = runNumber,
219 debug = options.debugLumi,
221 pileupHist.Add (hist)
222 histList.append (hist)
224 fillPileupHistogram (lumiDict, parameters,
226 debug = options.debugLumi,
229 histFile = ROOT.TFile.Open (output,
'recreate')
231 raise RuntimeError(
"Could not open '%s' as an output root file" % output)
233 for hist
in histList:
241 if options.runnumber:
242 inputRange = options.runnumber
244 basename, extension = os.path.splitext (options.inputfile)
245 if extension ==
'.csv':
249 f = open (options.inputfile,
'r') 250 inputfilecontent = f.read() 253 print(
'failed to parse the input file', options.inputfile)
256 recordedData = LumiQueryAPI.recordedLumiForRange (session, parameters, inputRange)
258 for runDTarray
in recordedData:
259 runNumber = runDTarray[0]
260 deadTable = runDTarray[2]
262 hist = fillPileupHistogram (deadTable, parameters,
263 runNumber = runNumber,
264 debug = options.debugLumi)
265 pileupHist.Add (hist)
266 histList.append (hist)
268 fillPileupHistogram (deadTable, parameters,
270 debug = options.debugLumi)
271 histFile = ROOT.TFile.Open (output,
'recreate')
273 raise RuntimeError(
"Could not open '%s' as an output root file" % output)
275 for hist
in histList:
S & print(S &os, JobReport::InputFile const &f)
OutputIterator zip(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp)
def fillPileupHistogram(deadTable, parameters, runNumber=0, hist=None, debug=False, mode='deadtable')