6 from RecoLuminosity.LumiDB
import csvSelectionParser, selectionParser
7 import RecoLuminosity.LumiDB.lumiQueryAPI
as LumiQueryAPI
11 from pprint
import pprint
14 def CalcPileup (deadTable, parameters, luminometer, mode='deadtable'):
15 '''Given a deadtable, will calculate parameters of pileup distribution. Return formatted
16 string with LumiSection, LS integrated lumi, RMS of bunch to bunch lumi and pileup.'''
21 for lumiSection, deadArray
in sorted (deadTable.iteritems()):
23 if luminometer ==
"HFOC":
28 numerator = float (deadArray[1])
29 denominator = float (deadArray[0])
30 instLumiArray = deadArray[2]
35 livetime = numerator / denominator
42 print "no csv input! Doh!"
52 for xing, xingInstLumi, xingDelvLumi
in instLumiArray:
53 if selBXs
and xing
not in selBXs:
55 xingIntLumi = xingInstLumi * livetime
56 mean = xingInstLumi * parameters.rotationTime / parameters.lumiSectionLen
59 print "mean number of pileup events > 100 for run %d, lum %d : m %f l %f" % \
60 (runNumber, lumiSection, mean, xingInstLumi)
62 print "mean number of pileup events > 100 for lum %d: m %f l %f" % \
63 (lumiSection, mean, xingInstLumi)
66 if xingInstLumi > threshold:
68 TotalLumi = TotalLumi+xingIntLumi
69 TotalInt+= mean*xingIntLumi
70 FilledXings = FilledXings+1
76 MeanInt = TotalInt/TotalLumi
77 for xing, xingInstLumi, xingDelvlumi
in instLumiArray:
78 if selBXs
and xing
not in selBXs:
80 if xingInstLumi > threshold:
81 xingIntLumi = xingInstLumi * livetime
82 mean = xingInstLumi * parameters.rotationTime / parameters.lumiSectionLen
83 TotalInt2+= xingIntLumi*(mean-MeanInt)*(mean-MeanInt)
84 TotalWeight+= xingIntLumi
85 TotalWeight2+= xingIntLumi*xingIntLumi
89 if ((lumiSection > 0)):
92 AveLumi = TotalLumi/FilledXings
96 Denom = TotalWeight*TotalWeight-TotalWeight2
97 if TotalLumi > 0
and Denom > 0:
98 RMSLumi =
sqrt(TotalWeight/(TotalWeight*TotalWeight-TotalWeight2)*TotalInt2)
99 LumiString =
"[%d,%2.4e,%2.4e,%2.4e]," % (lumiSection, TotalLumi, RMSLumi, MeanInt)
100 LumiArray.append(lumiSection)
101 LumiArray.append(TotalLumi)
102 LumiArray.append(RMSLumi)
103 LumiArray.append(MeanInt)
104 lumiX=MeanInt*parameters.lumiSectionLen*FilledXings*(1./parameters.rotationTime)
133 if __name__ ==
'__main__':
134 parameters = LumiQueryAPI.ParametersObject()
135 parser = optparse.OptionParser (
"Usage: %prog [--options] output.root",
136 description =
"Script to estimate average instantaneous bunch crossing luminosity using xing instantaneous luminosity information. Output is JSON format file with one entry per LumiSection")
137 inputGroup = optparse.OptionGroup (parser,
"Input Options")
138 pileupGroup = optparse.OptionGroup (parser,
"Pileup Options")
139 inputGroup.add_option (
'--csvInput', dest =
'csvInput', type=
'string', default=
'',
140 help =
'Use CSV file from lumiCalc.py instead of lumiDB')
141 inputGroup.add_option (
'--selBXs', dest =
'selBXs', type=
'string', default=
'',
142 help =
'CSV of BXs to use; if empty, select all')
143 parser.add_option_group (inputGroup)
144 parser.add_option_group (pileupGroup)
146 (options, args) = parser.parse_args()
153 raise RuntimeError(
"Please specify an output file as your last argument")
157 if not options.csvInput:
158 raise "you must specify an input CSV file with (--csvInput)"
160 if options.selBXs !=
"":
161 for iBX
in options.selBXs.split(
","):
167 print iBX,
"is not an int"
169 print "selBXs",selBXs
176 sepRE = re.compile (
r'[\]\[\s,;:]+')
177 events = open (options.csvInput,
'r')
191 if re.search(
'^#', line):
194 pieces = sepRE.split (line.strip())
198 if len (pieces) < 15:
201 run, lumi = int ( pieces[0] ), int ( pieces[2] )
202 delivered, recorded = float( pieces[11] ), float( pieces[12] )
204 if pieces[0] !=
'run':
205 print " cannot parse csv file "
208 GapDict[lumi] = [delivered, recorded]
214 run, lumi = int ( pieces[0] ), int ( pieces[2] )
215 delivered, recorded = float( pieces[11] ), float( pieces[12] )
216 luminometer = str( pieces[14] )
217 xingInstLumiArray = [( int(orbit), float(lum), float(lumdelv) ) \
218 for orbit, lum, lumdelv
in zip( pieces[15::3],
222 print " Bad Parsing: Check if the input format has changed"
223 print pieces[0],pieces[1],pieces[2],pieces[3],pieces[4],pieces[5],pieces[6],pieces[7],pieces[8],pieces[9]
226 csvDict.setdefault (run, {})[lumi] = \
227 ( delivered, recorded, xingInstLumiArray )
233 for lumiS, lumiInfo
in sorted ( GapDict.iteritems() ):
238 peakratio = lumiInfo[0]/LastDelivered
239 pileup = LastValidLumi[3]*peakratio
242 aveLumi = LastValidLumi[1]*peakratio*lumiInfo[1]/lumiInfo[0]
243 LumiString =
"[%d,%2.4e,%2.4e,%2.4e]," % (lumiS, aveLumi, LastValidLumi[2],pileup)
244 OUTPUTLINE += LumiString
246 LumiString =
"[%d,0.0,0.0,0.0]," % (lumiS)
247 OUTPUTLINE+=LumiString
249 LumiString =
"[%d,0.0,0.0,0.0]," % (lastLumiS+1)
250 OUTPUTLINE+=LumiString
256 LumiString =
"[%d,0.0,0.0,0.0]," % (LastValidLumi[0]+1)
257 OUTPUTLINE+=LumiString
259 lastindex=len(OUTPUTLINE)-1
260 trunc = OUTPUTLINE[0:lastindex]
264 OUTPUTLINE+= (
'"%d":' % run )
268 OUTPUTLINE+=
'[1,0.0,0.0,0.0],'
270 for runNumber, lumiDict
in sorted( csvDict.iteritems() ):
272 LumiArray = CalcPileup (lumiDict, parameters, luminometer,
275 LastValidLumi = LumiArray
276 LastDelivered = lumiDict[LumiArray[0]][0]
279 for lumiS, lumiInfo
in sorted ( GapDict.iteritems() ):
280 peakratio = lumiInfo[0]/LastDelivered
281 pileup = LumiArray[3]*peakratio
284 aveLumi = LumiArray[1]*peakratio*lumiInfo[1]/lumiInfo[0]
285 LumiString =
"[%d,%2.4e,%2.4e,%2.4e]," % (lumiS, aveLumi, LumiArray[2],pileup)
286 OUTPUTLINE += LumiString
288 LumiString =
"[%d,%2.4e,%2.4e,%2.4e]," % (LumiArray[0], LumiArray[1], LumiArray[2], LumiArray[3])
289 OUTPUTLINE += LumiString
292 lastindex=len(OUTPUTLINE)-1
293 trunc = OUTPUTLINE[0:lastindex]
298 outputfile = open(output,
'w')
300 raise RuntimeError(
"Could not open '%s' as an output JSON file" % output)
302 outputfile.write(OUTPUTLINE)
OutputIterator zip(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp)