CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
generateEDF.py
Go to the documentation of this file.
1 #! /usr/bin/env python
2 
3 import sys
4 import re
5 import optparse
6 from pprint import pprint
7 import array
8 import ROOT
9 import math
10 
11 sepRE = re.compile (r'[\s,;:]+')
12 nonSpaceRE = re.compile (r'\S')
13 
14 ##########################
15 ## #################### ##
16 ## ## LumiInfo Class ## ##
17 ## #################### ##
18 ##########################
19 
20 class LumiInfo (object):
21 
22  lastSingleXingRun = 136175
23  lumiSectionLength = 23.310779
24 
25  def __init__ (self, line):
26  self.totInstLum = 0.
27  self.aveInstLum = 0.
28  self.numXings = 0
29  self.instLums = []
30  self.events = []
31  self.xingInfo = False
32  self.badXingInfo = False
33  pieces = sepRE.split (line.strip())
34  size = len (pieces)
35  if size % 2:
36  raise RuntimeError, "Odd number of pieces"
37  if size < 4:
38  raise RuntimeError, "Not enough pieces"
39  try:
40  self.run = int (pieces[0])
41  self.lumi = int (pieces[1])
42  self.delivered = float (pieces[2])
43  self.recorded = float (pieces[3])
44  except:
45  raise RuntimeError, "Pieces not right format"
46  if size > 4:
47  try:
48  for xing, lum in zip (pieces[4::2],pieces[5::2]):
49  xing = int (xing)
50  lum = float (lum)
51  self.instLums.append( (xing, lum) )
52  self.totInstLum += lum
53  self.numXings += 1
54  except:
55  raise RuntimeError, "Inst Lumi Info malformed"
56  self.aveInstLum = self.totInstLum / (self.numXings)
57  self.xingInfo = True
58  self.key = (self.run, self.lumi)
59  self.keyString = self.key.__str__()
60 
61 
62  def fixXingInfo (self):
63  if self.numXings:
64  # You shouldn't try and fix an event if it already has
65  # xing information.
66  raise RuntimeError, "This event %s already has Xing information" \
67  % self.keyString
68  if self.run > LumiInfo.lastSingleXingRun:
69  # this run may have more than one crossing. I don't know
70  # how to fix this.
71  self.badXingInfo = True
72  return False
73  self.numXings = 1
74  xing = 1
75  self.aveInstLum = self.totInstLum = lum = \
76  self.delivered / LumiInfo.lumiSectionLength
77  self.instLums.append( (xing, lum) )
78  self.xingInfo = True
79  return True
80 
81 
82  def deadtime (self):
83  if not self.delivered:
84  return 1
85  return 1 - (self.recorded / self.delivered)
86 
87 
88  def __str__ (self):
89  return "%6d, %4d: %6.1f (%4.1f%%) %4.2f (%3d)" % \
90  (self.run,
91  self.lumi,
92  self.delivered,
93  self.deadtime(),
94  self.totInstLum,
95  self.numXings)
96 
97 
98 ##############################
99 ## ######################## ##
100 ## ## LumiInfoCont Class ## ##
101 ## ######################## ##
102 ##############################
103 
105 
106  def __init__ (self, filename, **kwargs):
107  print "loading luminosity information from '%s'." % filename
108  source = open (filename, 'r')
109  self.minMaxKeys = ['totInstLum', 'aveInstLum', 'numXings',
110  'delivered', 'recorded']
111  self._min = {}
112  self._max = {}
113  self.totalRecLum = 0.
114  self.xingInfo = False
115  self.allowNoXing = kwargs.get ('ignore')
116  self.noWarnings = kwargs.get ('noWarnings')
117  self.minRun = 0
118  self.maxRun = 0
119  self.minIntLum = 0
120  self.maxIntLum = 0
121 
122  for key in self.minMaxKeys:
123  self._min[key] = -1
124  self._max[key] = 0
125  for line in source:
126  try:
127  lumi = LumiInfo (line)
128  except:
129  continue
130  self[lumi.key] = lumi
131  self.totalRecLum += lumi.recorded
132  if not self.xingInfo and lumi.xingInfo:
133  self.xingInfo = True
134  if lumi.xingInfo:
135  #print "yes", lumi.keyString
136  if not self.xingInfo:
137  print "huh?"
138  for key in self.minMaxKeys:
139  val = getattr (lumi, key)
140  if val < self._min[key] or self._min[key] < 0:
141  self._min[key] = val
142  if val > self._max[key] or not self._max[key]:
143  self._max[key] = val
144  source.close()
145  ######################################################
146  ## Now that everything is setup, switch integrated ##
147  ## luminosity to more reasonable units. ##
148  ######################################################
149  # the default is '1/mb', but that's just silly.
150  self.invunits = 'nb'
151  lumFactor = 1e3
152  if self.totalRecLum > 1e9:
153  lumFactor = 1e9
154  self.invunits = 'fb'
155  elif self.totalRecLum > 1e6:
156  lumFactor = 1e6
157  self.invunits = 'pb'
158  # use lumFactor to make everything consistent
159  #print "units", self.invunits, "factor", lumFactor
160  self.totalRecLum /= lumFactor
161  for lumis in self.values():
162  lumis.delivered /= lumFactor
163  lumis.recorded /= lumFactor
164  # Probably want to rename this next subroutine, but I'll leave
165  # it alone for now...
166  self._integrateContainer()
167 
168 
169 
170  def __str__ (self):
171  retval = 'run, lum del ( dt ) inst (#xng)\n'
172  for key, value in sorted (self.iteritems()):
173  retval += "%s\n" % value
174  return retval
175 
176 
177  def min (self, key):
178  return self._min[key]
179 
180 
181  def max (self, key):
182  return self._max[key]
183 
184 
185  def keys (self):
186  return sorted (dict.keys (self))
187 
188 
189  def iteritems (self):
190  return sorted (dict.iteritems (self))
191 
192 
194  # calculate numbers for recorded integrated luminosity
195  total = 0.
196  for key, lumi in self.iteritems():
197  total += lumi.recorded
198  lumi.totalRecorded = total
199  lumi.fracRecorded = total / self.totalRecLum
200  # calculate numbers for average xing instantaneous luminosity
201  if not self.xingInfo:
202  # nothing to do here
203  return
204  xingKeyList = []
205  maxAveInstLum = 0.
206  for key, lumi in self.iteritems():
207  if not lumi.xingInfo and not lumi.fixXingInfo():
208  if not self.noWarnings:
209  print "Do not have lumi xing info for %s" % lumi.keyString
210  if not self.allowNoXing:
211  print "Setting no Xing info flag"
212  self.xingInfo = False
213  return
214  continue
215  xingKeyList.append( (lumi.aveInstLum, key) )
216  if lumi.aveInstLum > maxAveInstLum:
217  maxAveInstLum = lumi.aveInstLum
218  xingKeyList.sort()
219  total = 0.
220  for tup in xingKeyList:
221  lumi = self[tup[1]]
222  total += lumi.recorded
223  lumi.totalAXILrecorded = total
224  lumi.fracAXILrecorded = total / self.totalRecLum
225  lumi.fracAXIL = lumi.aveInstLum / maxAveInstLum
226 
227 
228 #############################
229 ## ####################### ##
230 ## ## General Functions ## ##
231 ## ####################### ##
232 #############################
233 
234 def loadEvents (filename, cont, options):
235  eventsDict = {}
236  print "loading events from '%s'" % filename
237  events = open (filename, 'r')
238  runIndex, lumiIndex, eventIndex, weightIndex = 0, 1, 2, 3
239  if options.relOrder:
240  lumiIndex, eventIndex = 2,1
241  minPieces = 3
242  totalWeight = 0.
243  if options.weights:
244  minPieces = 4
245  for line in events:
246  pieces = sepRE.split (line.strip())
247  if len (pieces) < minPieces:
248  if nonSpaceRE.search (line):
249  print "skipping", line
250  continue
251  try:
252  run, lumi, event = int( pieces[runIndex] ), \
253  int( pieces[lumiIndex] ), \
254  int( pieces[eventIndex] )
255  except:
256  continue
257  key = (run, lumi)
258  if not cont.has_key (key):
259  if options.ignore:
260  print "Warning, %s is not found in the lumi information" \
261  % key.__str__()
262  continue
263  else:
264  raise RuntimeError, "%s is not found in lumi information. Use '--ignoreNoLumiEvents' option to ignore these events and continue." \
265  % key.__str__()
266  if options.edfMode != 'time' and not cont[key].xingInfo:
267  if options.ignore:
268  print "Warning, %s does not have Xing information" \
269  % key.__str__()
270  continue
271  else:
272  raise RuntimeError, "%s does not have Xing information. Use '--ignoreNoLumiEvents' option to ignore these events and continue." \
273  % key.__str__()
274  if options.weights:
275  weight = float (pieces[weightIndex])
276  else:
277  weight = 1
278  eventsDict.setdefault( key, []).append( (event, weight) )
279  totalWeight += weight
280  events.close()
281  return eventsDict, totalWeight
282 
283 
284 def makeEDFplot (lumiCont, eventsDict, totalWeight, outputFile, options):
285  # make TGraph
286  xVals = [0]
287  yVals = [0]
288  expectedVals = [0]
289  predVals = [0]
290  weight = 0
291  expectedChunks = []
292  ########################
293  ## Time Ordering Mode ##
294  ########################
295  if 'time' == options.edfMode:
296  # if we have a minimum run number, clear the lists
297  if lumiCont.minRun or lumiCont.minIntLum:
298  xVals = []
299  yVals = []
300  expectedVals = []
301  predVals = []
302  # loop over events
303  for key, eventList in sorted( eventsDict.iteritems() ):
304  usePoints = True
305  # should we add this point?
306  if lumiCont.minRun and lumiCont.minRun > key[0] or \
307  lumiCont.maxRun and lumiCont.maxRun < key[0]:
308  usePoints = False
309  for event in eventList:
310  weight += event[1]
311  if not usePoints:
312  continue
313  factor = weight / totalWeight
314  try:
315  intLum = lumiCont[key].totalRecorded
316  except:
317  raise RuntimeError, "key %s not found in lumi information" \
318  % key.__str__()
319  if lumiCont.minIntLum and lumiCont.minIntLum > intLum or \
320  lumiCont.maxIntLum and lumiCont.maxIntLum < intLum:
321  continue
322  lumFrac = intLum / lumiCont.totalRecLum
323  xVals.append( lumiCont[key].totalRecorded)
324  yVals.append (factor)
325  expectedVals.append (lumFrac)
326  predVals.append (lumFrac * options.pred)
327  # put on the last point if we aren't giving a maximum run
328  if not lumiCont.maxRun and not lumiCont.maxIntLum:
329  xVals.append (lumiCont.totalRecLum)
330  yVals.append (1)
331  expectedVals.append (1)
332  predVals.append (options.pred)
333  ####################
334  ## Reset Expected ##
335  ####################
336  if options.resetExpected:
337  slope = (yVals[-1] - yVals[0]) / (xVals[-1] - xVals[0])
338  print "slope", slope
339  for index, old in enumerate (expectedVals):
340  expectedVals[index] = yVals[0] + \
341  slope * (xVals[index] - xVals[0])
342  #############################################
343  ## Break Expected by Integrated Luminosity ##
344  #############################################
345  if options.breakExpectedIntLum:
346  breakExpectedIntLum = []
347  for chunk in options.breakExpectedIntLum:
348  pieces = sepRE.split (chunk)
349  try:
350  for piece in pieces:
351  breakExpectedIntLum.append( float(piece) )
352  except:
353  raise RuntimeError, "'%s' from '%s' is not a valid float" \
354  % (piece, chunk)
355  breakExpectedIntLum.sort()
356  boundaries = []
357  breakIndex = 0
358  done = False
359  for index, xPos in enumerate (xVals):
360  if xPos > breakExpectedIntLum[breakIndex]:
361  boundaries.append (index)
362  while breakIndex < len (breakExpectedIntLum):
363  breakIndex += 1
364  if breakIndex >= len (breakExpectedIntLum):
365  done = True
366  break
367  # If this next position is different, than
368  # we're golden. Otherwise, let it go through
369  # the loop again.
370  if xPos <= breakExpectedIntLum[breakIndex]:
371  break
372  if done:
373  break
374  # do we have any boundaries?
375  if not boundaries:
376  raise RuntimeError, "No values of 'breakExpectedIntLum' are in current range."
377  # is the first boundary at 0? If not, add 0
378  if boundaries[0]:
379  boundaries.insert (0, 0)
380  # is the last boundary at the end? If not, make the end a
381  # boundary
382  if boundaries[-1] != len (xVals) - 1:
383  boundaries.append( len (xVals) - 1 )
384  rangeList = zip (boundaries, boundaries[1:])
385  for thisRange in rangeList:
386  upper = thisRange[1]
387  lower = thisRange[0]
388  slope = (yVals[upper] - yVals[lower]) / \
389  (xVals[upper] - xVals[lower])
390  print "slope", slope
391  # now go over the range inclusively
392  pairList = []
393  for index in range (lower, upper + 1):
394  newExpected = yVals[lower] + \
395  slope * (xVals[index] - xVals[lower])
396  pairList.append( (xVals[index], newExpected) )
397  expectedVals[index] = newExpected
398  expectedChunks.append (pairList)
399  ###########################################
400  ## Instantanous Luminosity Ordering Mode ##
401  ###########################################
402  elif 'instLum' == options.edfMode or 'instIntLum' == options.edfMode:
403  eventTupList = []
404  if not lumiCont.xingInfo:
405  raise RuntimeError, "Luminosity Xing information missing."
406  for key, eventList in sorted( eventsDict.iteritems() ):
407  try:
408  lumi = lumiCont[key]
409  instLum = lumi.aveInstLum
410  fracAXIL = lumi.fracAXILrecorded
411  totalAXIL = lumi.totalAXILrecorded
412  except:
413  raise RuntimeError, "key %s not found in lumi information" \
414  % key.__str__()
415  for event in eventList:
416  eventTupList.append( (instLum, fracAXIL, totalAXIL, key,
417  event[0], event[1], ) )
418  eventTupList.sort()
419  for eventTup in eventTupList:
420  weight += eventTup[5]
421  factor = weight / totalWeight
422  if 'instLum' == options.edfMode:
423  xVals.append (eventTup[0])
424  else:
425  xVals.append (eventTup[2])
426  yVals.append (factor)
427  expectedVals.append (eventTup[1])
428  predVals.append (eventTup[1] * options.pred)
429  else:
430  raise RuntimeError, "It looks like Charles screwed up if you are seeing this."
431 
432  size = len (xVals)
433  step = int (math.sqrt(size) / 2 + 1)
434  if options.printValues:
435  for index in range (size):
436  print "%8f %8f %8f" % (xVals[index], yVals[index], expectedVals[index]),
437  if index > step:
438  denom = xVals[index] - xVals[index - step]
439  numer = yVals[index] - yVals[index - step]
440  if denom:
441  print " %8f" % (numer / denom),
442  if 0 == index % step:
443  print " **", ## indicates statistically independent
444  ## slope measurement
445  print
446  print
447 
448  xArray = array.array ('d', xVals)
449  yArray = array.array ('d', yVals)
450  expected = array.array ('d', expectedVals)
451  graph = ROOT.TGraph( size, xArray, yArray)
452  graph.SetTitle (options.title)
453  graph.SetMarkerStyle (20)
454  expectedGraph = ROOT.TGraph( size, xArray, expected)
455  expectedGraph.SetLineColor (ROOT.kRed)
456  expectedGraph.SetLineWidth (3)
457  if options.noDataPoints:
458  expectedGraph.SetLineStyle (2)
459 
460  # run statistical tests
461  if options.weights:
462  print "average weight per event:", weight / ( size - 1)
463  maxDistance = ROOT.TMath.KolmogorovTest (size, yArray,
464  size, expected,
465  "M")
466  prob = ROOT.TMath.KolmogorovProb( maxDistance * math.sqrt( size ) )
467 
468  # display everything
469  ROOT.gROOT.SetStyle('Plain')
470  ROOT.gROOT.SetBatch()
471  c1 = ROOT.TCanvas()
472  graph.GetXaxis().SetRangeUser (min (xVals), max (xVals))
473  minValue = min (min(yVals), min(expected))
474  if options.pred:
475  minValue = min (minValue, min (predVals))
476  graph.GetYaxis().SetRangeUser (minValue,
477  max (max(yVals), max(expected), max(predVals)))
478  graph.SetLineWidth (3)
479  if options.noDataPoints:
480  graph.Draw ("AL")
481  else:
482  graph.Draw ("ALP")
483  if 'instLum' == options.edfMode:
484  graph.GetXaxis().SetTitle ("Average Xing Inst. Luminosity (1/ub/s)")
485  graph.GetXaxis().SetRangeUser (0., lumiCont.max('aveInstLum'))
486  else:
487  if 'instIntLum' == options.edfMode:
488  graph.GetXaxis().SetTitle ("Integrated Luminosity - Inst. Lum. Ordered (1/%s)" \
489  % lumiCont.invunits)
490  else:
491  graph.GetXaxis().SetTitle ("Integrated Luminosity (1/%s)" \
492  % lumiCont.invunits)
493  graph.GetYaxis().SetTitle ("Fraction of Events Seen")
494  expectedGraphs = []
495  if expectedChunks:
496  for index, chunk in enumerate (expectedChunks):
497  expectedXarray = array.array ('d', [item[0] for item in chunk])
498  expectedYarray = array.array ('d', [item[1] for item in chunk])
499  expectedGraph = ROOT.TGraph( len(chunk),
500  expectedXarray,
501  expectedYarray )
502  expectedGraph.SetLineWidth (3)
503  if options.noDataPoints:
504  expectedGraph.SetLineStyle (2)
505  if index % 2:
506  expectedGraph.SetLineColor (ROOT.kBlue)
507  else:
508  expectedGraph.SetLineColor (ROOT.kRed)
509  expectedGraph.Draw("L")
510  expectedGraphs.append (expectedGraph)
511  exptectedGraph = expectedGraphs[0]
512  else:
513  expectedGraph.Draw ("L")
514  green = 0
515  if options.pred:
516  predArray = array.array ('d', predVals)
517  green = ROOT.TGraph (size, xArray, predArray)
518  green.SetLineWidth (3)
519  green.SetLineColor (8)
520  green.Draw ('l')
521  legend = ROOT.TLegend(0.15, 0.65, 0.50, 0.85)
522  legend.SetFillStyle (0)
523  legend.SetLineColor(ROOT.kWhite)
524  observed = 'Observed'
525  if options.weights:
526  observed += ' (weighted)'
527  legend.AddEntry(graph, observed,"PL")
528  if options.resetExpected:
529  legend.AddEntry(expectedGraph, "Expected from partial yield","L")
530  else:
531  legend.AddEntry(expectedGraph, "Expected from total yield","L")
532  if options.pred:
533  legend.AddEntry(green, options.predLabel,"L")
534  legend.AddEntry("","D_{stat}=%.3f, N=%d" % (maxDistance, size),"")
535  legend.AddEntry("","P_{KS}=%.3f" % prob,"")
536  legend.Draw()
537 
538  # save file
539  c1.Print (outputFile)
540 
541 
542 ######################
543 ## ################ ##
544 ## ## ########## ## ##
545 ## ## ## Main ## ## ##
546 ## ## ########## ## ##
547 ## ################ ##
548 ######################
549 
550 if __name__ == '__main__':
551  ##########################
552  ## command line options ##
553  ##########################
554  allowedEDF = ['time', 'instLum', 'instIntLum']
555  parser = optparse.OptionParser ("Usage: %prog [options] lumi.csv events.txt output.png", description='Script for generating EDF curves. See https://twiki.cern.ch/twiki/bin/viewauth/CMS/SWGuideGenerateEDF for more details.')
556  plotGroup = optparse.OptionGroup (parser, "Plot Options")
557  rangeGroup = optparse.OptionGroup (parser, "Range Options")
558  inputGroup = optparse.OptionGroup (parser, "Input Options")
559  modeGroup = optparse.OptionGroup (parser, "Mode Options")
560  plotGroup.add_option ('--title', dest='title', type='string',
561  default = 'Empirical Distribution Function',
562  help = 'title of plot (default %default)')
563  plotGroup.add_option ('--predicted', dest='pred', type='float',
564  default = 0,
565  help = 'factor by which predicted curve is greater than observed')
566  plotGroup.add_option ('--predLabel', dest='predLabel', type='string',
567  default = 'Predicted',
568  help = 'label of predicted in legend')
569  plotGroup.add_option ('--noDataPoints', dest='noDataPoints',
570  action='store_true',
571  help="Draw lines but no points for data")
572  rangeGroup.add_option ('--minRun', dest='minRun', type='int', default=0,
573  help='Minimum run number to consider')
574  rangeGroup.add_option ('--maxRun', dest='maxRun', type='int', default=0,
575  help='Maximum run number to consider')
576  rangeGroup.add_option ('--minIntLum', dest='minIntLum', type='float', default=0,
577  help='Minimum integrated luminosity to consider')
578  rangeGroup.add_option ('--maxIntLum', dest='maxIntLum', type='float', default=0,
579  help='Maximum integrated luminosity to consider')
580  rangeGroup.add_option ('--resetExpected', dest='resetExpected',
581  action='store_true',
582  help='Reset expected from total yield to highest point considered')
583  rangeGroup.add_option ('--breakExpectedIntLum', dest='breakExpectedIntLum',
584  type='string', action='append', default=[],
585  help='Break expected curve into pieces at integrated luminosity boundaries')
586  inputGroup.add_option ('--ignoreNoLumiEvents', dest='ignore',
587  action='store_true',
588  help = 'Ignore (with a warning) events that do not have a lumi section')
589  inputGroup.add_option ('--noWarnings', dest='noWarnings',
590  action='store_true',
591  help = 'Do not print warnings about missing luminosity information')
592  inputGroup.add_option ('--runEventLumi', dest='relOrder',
593  action='store_true',
594  help = 'Parse event list assuming Run, Event #, Lumi# order')
595  inputGroup.add_option ('--weights', dest='weights', action='store_true',
596  help = 'Read fourth column as a weight')
597  modeGroup.add_option ('--print', dest='printValues', action='store_true',
598  help = 'Print X and Y values of EDF plot')
599  modeGroup.add_option ('--runsWithLumis', dest='runsWithLumis',
600  type='string',action='append', default=[],
601  help='Print out run and lumi sections corresponding to integrated luminosities provided and then exits')
602  modeGroup.add_option ('--edfMode', dest='edfMode', type='string',
603  default='time',
604  help="EDF Mode %s (default '%%default')" % allowedEDF)
605  parser.add_option_group (plotGroup)
606  parser.add_option_group (rangeGroup)
607  parser.add_option_group (inputGroup)
608  parser.add_option_group (modeGroup)
609  (options, args) = parser.parse_args()
610 
611  if options.edfMode not in allowedEDF:
612  raise RuntimeError, "edfMode (currently '%s') must be one of %s" \
613  % (options.edfMode, allowedEDF)
614 
615  if len (args) != 3 and not (options.runsWithLumis and len(args) >= 1):
616  raise RuntimeError, "Must provide lumi.csv, events.txt, and output.png"
617 
618 
619  ##########################
620  ## load Luminosity info ##
621  ##########################
622  cont = LumiInfoCont (args[0], **options.__dict__)
623  cont.minRun = options.minRun
624  cont.maxRun = options.maxRun
625  cont.minIntLum = options.minIntLum
626  cont.maxIntLum = options.maxIntLum
627 
628  ##################################################
629  ## look for which runs correspond to what total ##
630  ## recorded integrated luminosity ##
631  ##################################################
632  if options.runsWithLumis:
633  recLumis = []
634  for line in options.runsWithLumis:
635  pieces = sepRE.split (line)
636  for piece in pieces:
637  try:
638  recLumValue = float (piece)
639  except:
640  raise RuntimeError, "'%s' in '%s' is not a float" % \
641  (piece, line)
642  if recLumValue <= 0:
643  raise RuntimeError, "You must provide positive values for -runsWithLumis ('%f' given)" % recLumValue
644  recLumis.append (recLumValue)
645  if not recLumis:
646  raise RuntimeError, "What did Charles do now?"
647  recLumis.sort()
648  recLumIndex = 0
649  recLumValue = recLumis [recLumIndex]
650  prevRecLumi = 0.
651  done = False
652  for key, lumi in cont.iteritems():
653  if prevRecLumi >= recLumValue and recLumValue < lumi.totalRecorded:
654  # found it
655  print "%s contains total recorded lumi %f" % \
656  (key.__str__(), recLumValue)
657  while True:
658  recLumIndex += 1
659  if recLumIndex == len (recLumis):
660  done = True
661  break
662  recLumValue = recLumis [recLumIndex]
663  if prevRecLumi >= recLumValue and recLumValue < lumi.totalRecorded:
664  # found it
665  print "%s contains total recorded lumi %f" % \
666  (key.__str__(), recLumValue)
667  else:
668  break
669  if done:
670  break
671  prevRecLumi = lumi.totalRecorded
672  if recLumIndex < len (recLumis):
673  print "Theses lumis not found: %s" % recLumis[recLumIndex:]
674  sys.exit()
675 
676  ####################
677  ## make EDF plots ##
678  ####################
679  if options.edfMode != 'time' and not cont.xingInfo:
680  raise RuntimeError, "'%s' does not have Xing info" % args[0]
681  eventsDict, totalWeight = loadEvents (args[1], cont, options)
682  makeEDFplot (cont, eventsDict, totalWeight, args[2], options)
invunits
Now that everything is setup, switch integrated ## luminosity to more reasonable units.
Definition: generateEDF.py:150
T min(T a, T b)
Definition: MathUtil.h:58
def loadEvents
General Functions
Definition: generateEDF.py:234
list object
Definition: dbtoconf.py:77
LumiInfoCont Class
Definition: generateEDF.py:104
LumiInfo Class
Definition: generateEDF.py:20