6 from RecoLuminosity.LumiDB
import csvSelectionParser, selectionParser
7 import RecoLuminosity.LumiDB.lumiQueryAPI
as LumiQueryAPI
10 from pprint
import pprint
14 runNumber = 0, hist =
None, debug =
False,
16 '''Given a deadtable and run number, will (create if necessary 17 and) fill histogram with expected pileup distribution. If a 18 histogram is created, it is owned by the user and is his/her 19 responsibility to clean up the memory.''' 21 maxBin = hist.GetNbinsX()
22 upper =
int( hist.GetBinLowEdge(maxBin) + \
23 hist.GetBinWidth(maxBin) + 0.25 )
25 histname =
'%s_%s' % (parameters.pileupHistName, runNumber)
26 hist = ROOT.TH1D (histname, histname, parameters.maxPileupBin + 1,
27 -0.5, parameters.maxPileupBin + 0.5)
28 upper = parameters.maxPileupBin
29 for lumiSection, deadArray
in sorted (six.iteritems(deadTable)):
31 numerator = float (deadArray[1])
32 denominator = float (deadArray[0])
33 instLumiArray = deadArray[2]
38 livetime = numerator / denominator
41 if len(deadArray) <= parameters.xingIndex:
45 if parameters.noWarnings:
48 print "No Xing Instantaneous luminosity information for run %d, lumi section %d" \
49 % (runNumber, lumiSection)
51 print "No Xing Instantaneous luminosity information for lumi section %d" \
54 numerator = float (deadArray[0])
55 denominator = float (deadArray[2] * deadArray[4])
56 xingInstLumiArray = deadArray[parameters.xingIndex]
59 instLumiArray = [(xingInstLumiArray[index], xingInstLumiArray[index + 1]) \
60 for index
in xrange( 0, len (xingInstLumiArray), 2 ) ]
65 livetime = 1 - numerator / denominator
67 for xing, xingInstLumi
in instLumiArray:
68 xingIntLumi = xingInstLumi * parameters.lumiSectionLen * livetime
69 mean = xingInstLumi * parameters.minBiasXsec * \
70 parameters.rotationTime
73 print "mean number of pileup events > 100 for run %d, lum %d : m %f l %f" % \
74 (runNumber, lumiSection, mean, xingInstLumi)
76 print "mean number of pileup events > 100 for lum %d: m %f l %f" % \
77 (lumiSection, mean, xingInstLumi)
79 for obs
in range (upper):
80 prob = ROOT.TMath.Poisson (obs, mean)
82 hist.Fill (obs, prob * xingIntLumi)
84 print "ls", lumiSection,
"xing", xing,
"inst", xingInstLumi, \
85 "mean", mean,
"totalProb", totalProb, 1 - totalProb
86 print " hist mean", hist.GetMean()
88 hist.Fill (obs, (1 - totalProb) * xingIntLumi)
101 if __name__ ==
'__main__':
102 parameters = LumiQueryAPI.ParametersObject()
103 beamModeChoices = [
"",
"stable",
"quiet",
"either"]
104 parser = optparse.OptionParser (
"Usage: %prog [--options] output.root",
105 description =
"Script to estimate pileup distribution using xing instantaneous luminosity information and minimum bias cross section. Output is TH1D stored in root file")
106 dbGroup = optparse.OptionGroup (parser,
"Database Options")
107 inputGroup = optparse.OptionGroup (parser,
"Input Options")
108 pileupGroup = optparse.OptionGroup (parser,
"Pileup Options")
109 dbGroup.add_option (
'--parameters', dest =
'connect', action =
'store',
110 help =
'connect string to lumiDB (optional, default to frontier://LumiCalc/CMS_LUMI_PROD)')
111 dbGroup.add_option (
'-P', dest =
'authpath', action =
'store',
112 help =
'path to authentication file')
113 dbGroup.add_option (
'--siteconfpath', dest =
'siteconfpath', action =
'store',
114 help =
'specific path to site-local-config.xml file, default to $CMS_PATH/SITECONF/local/JobConfig, ' \
115 'if path undefined, fallback to cern proxy&server')
116 dbGroup.add_option (
'--debug', dest =
'debug', action =
'store_true',
118 inputGroup.add_option (
'-r', dest =
'runnumber', action =
'store',
120 inputGroup.add_option (
'-i', dest =
'inputfile', action =
'store',
121 help =
'lumi range selection file')
122 inputGroup.add_option (
'-b', dest =
'beammode', default=
'', choices=beamModeChoices,
123 help =
"beam mode, optional for delivered action, default ('%%default' out of %s)" % beamModeChoices)
124 inputGroup.add_option (
'--lumiversion', dest =
'lumiversion', type=
'string', default=
'0001',
125 help =
'lumi data version, optional for all, default %default')
126 inputGroup.add_option (
'--hltpath', dest =
'hltpath', action =
'store',
127 help =
'specific hltpath to calculate the recorded luminosity, default to all')
128 inputGroup.add_option (
'--csvInput', dest =
'csvInput', type=
'string', default=
'',
129 help =
'Use CSV file from lumiCalc.py instead of lumiDB')
130 pileupGroup.add_option (
'--xingMinLum', dest =
'xingMinLum', type=
'float', default = 1e-3,
131 help =
'Minimum luminosity considered for "lsbylsXing" action, default %default')
132 pileupGroup.add_option (
'--minBiasXsec', dest =
'minBiasXsec', type=
'float', default = parameters.minBiasXsec,
133 help =
'Minimum bias cross section assumed (in mb), default %default mb')
134 pileupGroup.add_option (
'--histName', dest=
'histName', type=
'string', default = parameters.pileupHistName,
135 help =
'Histrogram name (default %default)')
136 pileupGroup.add_option (
'--maxPileupBin', dest=
'maxPileupBin', type=
'int', default = parameters.maxPileupBin,
137 help =
'Maximum bin in pileup histogram (default %default)')
138 pileupGroup.add_option (
'--saveRuns', dest=
'saveRuns', action=
'store_true',
139 help =
'Save pileup histograms for individual runs')
140 pileupGroup.add_option (
'--debugLumi', dest=
'debugLumi',
142 help =
'Print out debug info for individual lumis')
143 pileupGroup.add_option (
'--nowarning', dest =
'nowarning',
144 action =
'store_true', default =
False,
145 help =
'suppress bad for lumi warnings' )
146 parser.add_option_group (dbGroup)
147 parser.add_option_group (inputGroup)
148 parser.add_option_group (pileupGroup)
150 (options, args) = parser.parse_args()
157 raise RuntimeError(
"Exactly one output file must be given")
162 os.environ[
'CORAL_AUTH_PATH'] = options.authpath
165 parameters.verbose =
True 166 parameters.noWarnings = options.nowarning
167 parameters.lumiXing =
True 168 parameters.lumiversion = options.lumiversion
169 if options.beammode==
'stable':
170 parameters.beammode =
'STABLE BEAMS' 171 parameters.xingMinLum = options.xingMinLum
172 parameters.minBiasXsec = options.minBiasXsec
173 parameters.pileupHistName = options.histName
174 parameters.maxPileupBin = options.maxPileupBin
177 LumiQueryAPI.setupSession (options.connect
or \
178 'frontier://LumiCalc/CMS_LUMI_PROD',
179 options.siteconfpath, parameters,options.debug)
182 if not options.inputfile
and not options.runnumber
and not options.csvInput:
183 raise "must specify either a run (-r), an input run selection file (-i), or an input CSV file (--csvInput)" 184 pileupHist = ROOT.TH1D(parameters.pileupHistName, parameters.pileupHistName,
192 sepRE = re.compile (
r'[\s,;:]+')
194 events = open (options.csvInput,
'r') 197 pieces = sepRE.split (line.strip())
204 run, lumi = int ( pieces[0] ), int ( pieces[2] )
207 for orbit, lum
in zip( pieces[9::2],
211 csvDict.setdefault (run, {})[lumi] = \
212 ( delivered, recorded, xingInstLumiArray )
214 for runNumber, lumiDict
in sorted( six.iteritems(csvDict) ):
216 hist = fillPileupHistogram (lumiDict, parameters,
217 runNumber = runNumber,
218 debug = options.debugLumi,
220 pileupHist.Add (hist)
221 histList.append (hist)
223 fillPileupHistogram (lumiDict, parameters,
225 debug = options.debugLumi,
228 histFile = ROOT.TFile.Open (output,
'recreate')
230 raise RuntimeError(
"Could not open '%s' as an output root file" % output)
232 for hist
in histList:
240 if options.runnumber:
241 inputRange = options.runnumber
243 basename, extension = os.path.splitext (options.inputfile)
244 if extension ==
'.csv':
248 f = open (options.inputfile,
'r') 249 inputfilecontent = f.read() 252 print 'failed to parse the input file', options.inputfile
255 recordedData = LumiQueryAPI.recordedLumiForRange (session, parameters, inputRange)
257 for runDTarray
in recordedData:
258 runNumber = runDTarray[0]
259 deadTable = runDTarray[2]
261 hist = fillPileupHistogram (deadTable, parameters,
262 runNumber = runNumber,
263 debug = options.debugLumi)
264 pileupHist.Add (hist)
265 histList.append (hist)
267 fillPileupHistogram (deadTable, parameters,
269 debug = options.debugLumi)
270 histFile = ROOT.TFile.Open (output,
'recreate')
272 raise RuntimeError(
"Could not open '%s' as an output root file" % output)
274 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')