CMS 3D CMS Logo

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