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