CMS 3D CMS Logo

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