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 key not in cont:
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 = list(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)
boost::dynamic_bitset append(const boost::dynamic_bitset<> &bs1, const boost::dynamic_bitset<> &bs2)
this method takes two bitsets bs1 and bs2 and returns result of bs2 appended to the end of bs1 ...
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
LumiInfoCont Class
Definition: generateEDF.py:104
LumiInfo Class
Definition: generateEDF.py:20
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