6 from RecoLuminosity.LumiDB
import csvSelectionParser, selectionParser
7 import RecoLuminosity.LumiDB.lumiQueryAPI
as LumiQueryAPI
10 from pprint
import pprint
13 runNumber = 0, hist =
None, debug =
False,
15 '''Given a deadtable and run number, will (create if necessary 16 and) fill histogram with expected pileup distribution. If a 17 histogram is created, it is owned by the user and is his/her 18 responsibility to clean up the memory.''' 20 maxBin = hist.GetNbinsX()
21 upper =
int( hist.GetBinLowEdge(maxBin) + \
22 hist.GetBinWidth(maxBin) + 0.25 )
24 histname =
'%s_%s' % (parameters.pileupHistName, runNumber)
25 hist = ROOT.TH1D (histname, histname, parameters.maxPileupBin + 1,
26 -0.5, parameters.maxPileupBin + 0.5)
27 upper = parameters.maxPileupBin
28 for lumiSection, deadArray
in sorted (deadTable.iteritems()):
30 numerator = float (deadArray[1])
31 denominator = float (deadArray[0])
32 instLumiArray = deadArray[2]
37 livetime = numerator / denominator
40 if len(deadArray) <= parameters.xingIndex:
44 if parameters.noWarnings:
47 print "No Xing Instantaneous luminosity information for run %d, lumi section %d" \
48 % (runNumber, lumiSection)
50 print "No Xing Instantaneous luminosity information for lumi section %d" \
53 numerator = float (deadArray[0])
54 denominator = float (deadArray[2] * deadArray[4])
55 xingInstLumiArray = deadArray[parameters.xingIndex]
58 instLumiArray = [(xingInstLumiArray[index], xingInstLumiArray[index + 1]) \
59 for index
in xrange( 0, len (xingInstLumiArray), 2 ) ]
64 livetime = 1 - numerator / denominator
66 for xing, xingInstLumi
in instLumiArray:
67 xingIntLumi = xingInstLumi * parameters.lumiSectionLen * livetime
68 mean = xingInstLumi * parameters.minBiasXsec * \
69 parameters.rotationTime
72 print "mean number of pileup events > 100 for run %d, lum %d : m %f l %f" % \
73 (runNumber, lumiSection, mean, xingInstLumi)
75 print "mean number of pileup events > 100 for lum %d: m %f l %f" % \
76 (lumiSection, mean, xingInstLumi)
78 for obs
in range (upper):
79 prob = ROOT.TMath.Poisson (obs, mean)
81 hist.Fill (obs, prob * xingIntLumi)
83 print "ls", lumiSection,
"xing", xing,
"inst", xingInstLumi, \
84 "mean", mean,
"totalProb", totalProb, 1 - totalProb
85 print " hist mean", hist.GetMean()
87 hist.Fill (obs, (1 - totalProb) * xingIntLumi)
100 if __name__ ==
'__main__':
101 parameters = LumiQueryAPI.ParametersObject()
102 beamModeChoices = [
"",
"stable",
"quiet",
"either"]
103 parser = optparse.OptionParser (
"Usage: %prog [--options] output.root",
104 description =
"Script to estimate pileup distribution using xing instantaneous luminosity information and minimum bias cross section. Output is TH1D stored in root file")
105 dbGroup = optparse.OptionGroup (parser,
"Database Options")
106 inputGroup = optparse.OptionGroup (parser,
"Input Options")
107 pileupGroup = optparse.OptionGroup (parser,
"Pileup Options")
108 dbGroup.add_option (
'--parameters', dest =
'connect', action =
'store',
109 help =
'connect string to lumiDB (optional, default to frontier://LumiCalc/CMS_LUMI_PROD)')
110 dbGroup.add_option (
'-P', dest =
'authpath', action =
'store',
111 help =
'path to authentication file')
112 dbGroup.add_option (
'--siteconfpath', dest =
'siteconfpath', action =
'store',
113 help =
'specific path to site-local-config.xml file, default to $CMS_PATH/SITECONF/local/JobConfig, ' \
114 'if path undefined, fallback to cern proxy&server')
115 dbGroup.add_option (
'--debug', dest =
'debug', action =
'store_true',
117 inputGroup.add_option (
'-r', dest =
'runnumber', action =
'store',
119 inputGroup.add_option (
'-i', dest =
'inputfile', action =
'store',
120 help =
'lumi range selection file')
121 inputGroup.add_option (
'-b', dest =
'beammode', default=
'', choices=beamModeChoices,
122 help =
"beam mode, optional for delivered action, default ('%%default' out of %s)" % beamModeChoices)
123 inputGroup.add_option (
'--lumiversion', dest =
'lumiversion', type=
'string', default=
'0001',
124 help =
'lumi data version, optional for all, default %default')
125 inputGroup.add_option (
'--hltpath', dest =
'hltpath', action =
'store',
126 help =
'specific hltpath to calculate the recorded luminosity, default to all')
127 inputGroup.add_option (
'--csvInput', dest =
'csvInput', type=
'string', default=
'',
128 help =
'Use CSV file from lumiCalc.py instead of lumiDB')
129 pileupGroup.add_option (
'--xingMinLum', dest =
'xingMinLum', type=
'float', default = 1e-3,
130 help =
'Minimum luminosity considered for "lsbylsXing" action, default %default')
131 pileupGroup.add_option (
'--minBiasXsec', dest =
'minBiasXsec', type=
'float', default = parameters.minBiasXsec,
132 help =
'Minimum bias cross section assumed (in mb), default %default mb')
133 pileupGroup.add_option (
'--histName', dest=
'histName', type=
'string', default = parameters.pileupHistName,
134 help =
'Histrogram name (default %default)')
135 pileupGroup.add_option (
'--maxPileupBin', dest=
'maxPileupBin', type=
'int', default = parameters.maxPileupBin,
136 help =
'Maximum bin in pileup histogram (default %default)')
137 pileupGroup.add_option (
'--saveRuns', dest=
'saveRuns', action=
'store_true',
138 help =
'Save pileup histograms for individual runs')
139 pileupGroup.add_option (
'--debugLumi', dest=
'debugLumi',
141 help =
'Print out debug info for individual lumis')
142 pileupGroup.add_option (
'--nowarning', dest =
'nowarning',
143 action =
'store_true', default =
False,
144 help =
'suppress bad for lumi warnings' )
145 parser.add_option_group (dbGroup)
146 parser.add_option_group (inputGroup)
147 parser.add_option_group (pileupGroup)
149 (options, args) = parser.parse_args()
156 raise RuntimeError(
"Exactly one output file must be given")
161 os.environ[
'CORAL_AUTH_PATH'] = options.authpath
164 parameters.verbose =
True 165 parameters.noWarnings = options.nowarning
166 parameters.lumiXing =
True 167 parameters.lumiversion = options.lumiversion
168 if options.beammode==
'stable':
169 parameters.beammode =
'STABLE BEAMS' 170 parameters.xingMinLum = options.xingMinLum
171 parameters.minBiasXsec = options.minBiasXsec
172 parameters.pileupHistName = options.histName
173 parameters.maxPileupBin = options.maxPileupBin
176 LumiQueryAPI.setupSession (options.connect
or \
177 'frontier://LumiCalc/CMS_LUMI_PROD',
178 options.siteconfpath, parameters,options.debug)
181 if not options.inputfile
and not options.runnumber
and not options.csvInput:
182 raise "must specify either a run (-r), an input run selection file (-i), or an input CSV file (--csvInput)" 183 pileupHist = ROOT.TH1D(parameters.pileupHistName, parameters.pileupHistName,
191 sepRE = re.compile (
r'[\s,;:]+')
193 events = open (options.csvInput,
'r') 196 pieces = sepRE.split (line.strip())
203 run, lumi = int ( pieces[0] ), int ( pieces[2] )
206 for orbit, lum
in zip( pieces[9::2],
210 csvDict.setdefault (run, {})[lumi] = \
211 ( delivered, recorded, xingInstLumiArray )
213 for runNumber, lumiDict
in sorted( csvDict.iteritems() ):
215 hist = fillPileupHistogram (lumiDict, parameters,
216 runNumber = runNumber,
217 debug = options.debugLumi,
219 pileupHist.Add (hist)
220 histList.append (hist)
222 fillPileupHistogram (lumiDict, parameters,
224 debug = options.debugLumi,
227 histFile = ROOT.TFile.Open (output,
'recreate')
229 raise RuntimeError(
"Could not open '%s' as an output root file" % output)
231 for hist
in histList:
239 if options.runnumber:
240 inputRange = options.runnumber
242 basename, extension = os.path.splitext (options.inputfile)
243 if extension ==
'.csv':
247 f = open (options.inputfile,
'r') 248 inputfilecontent = f.read() 251 print 'failed to parse the input file', options.inputfile
254 recordedData = LumiQueryAPI.recordedLumiForRange (session, parameters, inputRange)
256 for runDTarray
in recordedData:
257 runNumber = runDTarray[0]
258 deadTable = runDTarray[2]
260 hist = fillPileupHistogram (deadTable, parameters,
261 runNumber = runNumber,
262 debug = options.debugLumi)
263 pileupHist.Add (hist)
264 histList.append (hist)
266 fillPileupHistogram (deadTable, parameters,
268 debug = options.debugLumi)
269 histFile = ROOT.TFile.Open (output,
'recreate')
271 raise RuntimeError(
"Could not open '%s' as an output root file" % output)
273 for hist
in histList:
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')