6 from pprint
import pprint
11 sepRE = re.compile (
r'[\s,;:]+')
12 nonSpaceRE = re.compile (
r'\S')
22 lastSingleXingRun = 136175
23 lumiSectionLength = 23.310779
33 pieces = sepRE.split (line.strip())
36 raise RuntimeError(
"Odd number of pieces")
38 raise RuntimeError(
"Not enough pieces")
40 self.
run = int (pieces[0])
41 self.
lumi = int (pieces[1])
45 raise RuntimeError(
"Pieces not right format")
48 for xing, lum
in zip (pieces[4::2],pieces[5::2]):
51 self.instLums.append( (xing, lum) )
55 raise RuntimeError(
"Inst Lumi Info malformed")
66 raise RuntimeError(
"This event %s already has Xing information" \
68 if self.
run > LumiInfo.lastSingleXingRun:
76 self.
delivered / LumiInfo.lumiSectionLength
77 self.instLums.append( (xing, lum) )
89 return "%6d, %4d: %6.1f (%4.1f%%) %4.2f (%3d)" % \
107 print "loading luminosity information from '%s'." % filename
108 source = open (filename,
'r') 110 'delivered',
'recorded']
127 lumi = LumiInfo (line)
130 self[lumi.key] = lumi
132 if not self.
xingInfo and lumi.xingInfo:
139 val = getattr (lumi, key)
140 if val < self.
_min[key]
or self.
_min[key] < 0:
142 if val > self.
_max[key]
or not self.
_max[key]:
161 for lumis
in self.values():
162 lumis.delivered /= lumFactor
163 lumis.recorded /= lumFactor
171 retval =
'run, lum del ( dt ) inst (#xng)\n' 172 for key, value
in sorted (self.
iteritems()):
173 retval +=
"%s\n" % value
178 return self.
_min[key]
182 return self.
_max[key]
186 return sorted (dict.keys (self))
190 return sorted (dict.iteritems (self))
197 total += lumi.recorded
198 lumi.totalRecorded = total
207 if not lumi.xingInfo
and not lumi.fixXingInfo():
209 print "Do not have lumi xing info for %s" % lumi.keyString
211 print "Setting no Xing info flag" 215 xingKeyList.append( (lumi.aveInstLum, key) )
216 if lumi.aveInstLum > maxAveInstLum:
217 maxAveInstLum = lumi.aveInstLum
220 for tup
in xingKeyList:
222 total += lumi.recorded
223 lumi.totalAXILrecorded = total
225 lumi.fracAXIL = lumi.aveInstLum / maxAveInstLum
236 print "loading events from '%s'" % filename
237 events = open (filename,
'r') 238 runIndex, lumiIndex, eventIndex, weightIndex = 0, 1, 2, 3 240 lumiIndex, eventIndex = 2,1
246 pieces = sepRE.split (line.strip())
247 if len (pieces) < minPieces:
248 if nonSpaceRE.search (line):
249 print "skipping", line
252 run, lumi, event =
int( pieces[runIndex] ), \
253 int( pieces[lumiIndex] ), \
254 int( pieces[eventIndex] )
260 print "Warning, %s is not found in the lumi information" \
264 raise RuntimeError(
"%s is not found in lumi information. Use '--ignoreNoLumiEvents' option to ignore these events and continue." \
266 if options.edfMode !=
'time' and not cont[key].xingInfo:
268 print "Warning, %s does not have Xing information" \
272 raise RuntimeError(
"%s does not have Xing information. Use '--ignoreNoLumiEvents' option to ignore these events and continue." \
275 weight = float (pieces[weightIndex])
278 eventsDict.setdefault( key, []).
append( (event, weight) )
279 totalWeight += weight
281 return eventsDict, totalWeight
284 def makeEDFplot (lumiCont, eventsDict, totalWeight, outputFile, options):
295 if 'time' == options.edfMode:
297 if lumiCont.minRun
or lumiCont.minIntLum:
303 for key, eventList
in sorted( eventsDict.iteritems() ):
306 if lumiCont.minRun
and lumiCont.minRun > key[0]
or \
307 lumiCont.maxRun
and lumiCont.maxRun < key[0]:
309 for event
in eventList:
313 factor = weight / totalWeight
315 intLum = lumiCont[key].totalRecorded
317 raise RuntimeError(
"key %s not found in lumi information" \
319 if lumiCont.minIntLum
and lumiCont.minIntLum > intLum
or \
320 lumiCont.maxIntLum
and lumiCont.maxIntLum < intLum:
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)
328 if not lumiCont.maxRun
and not lumiCont.maxIntLum:
329 xVals.append (lumiCont.totalRecLum)
331 expectedVals.append (1)
332 predVals.append (options.pred)
336 if options.resetExpected:
337 slope = (yVals[-1] - yVals[0]) / (xVals[-1] - xVals[0])
339 for index, old
in enumerate (expectedVals):
340 expectedVals[index] = yVals[0] + \
341 slope * (xVals[index] - xVals[0])
345 if options.breakExpectedIntLum:
346 breakExpectedIntLum = []
347 for chunk
in options.breakExpectedIntLum:
348 pieces = sepRE.split (chunk)
351 breakExpectedIntLum.append(
float(piece) )
353 raise RuntimeError(
"'%s' from '%s' is not a valid float" \
355 breakExpectedIntLum.sort()
359 for index, xPos
in enumerate (xVals):
360 if xPos > breakExpectedIntLum[breakIndex]:
361 boundaries.append (index)
362 while breakIndex < len (breakExpectedIntLum):
364 if breakIndex >= len (breakExpectedIntLum):
370 if xPos <= breakExpectedIntLum[breakIndex]:
376 raise RuntimeError(
"No values of 'breakExpectedIntLum' are in current range.")
379 boundaries.insert (0, 0)
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:
388 slope = (yVals[upper] - yVals[lower]) / \
389 (xVals[upper] - xVals[lower])
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)
402 elif 'instLum' == options.edfMode
or 'instIntLum' == options.edfMode:
404 if not lumiCont.xingInfo:
405 raise RuntimeError(
"Luminosity Xing information missing.")
406 for key, eventList
in sorted( eventsDict.iteritems() ):
409 instLum = lumi.aveInstLum
410 fracAXIL = lumi.fracAXILrecorded
411 totalAXIL = lumi.totalAXILrecorded
413 raise RuntimeError(
"key %s not found in lumi information" \
415 for event
in eventList:
416 eventTupList.append( (instLum, fracAXIL, totalAXIL, key,
417 event[0], event[1], ) )
419 for eventTup
in eventTupList:
420 weight += eventTup[5]
421 factor = weight / totalWeight
422 if 'instLum' == options.edfMode:
423 xVals.append (eventTup[0])
425 xVals.append (eventTup[2])
426 yVals.append (factor)
427 expectedVals.append (eventTup[1])
428 predVals.append (eventTup[1] * options.pred)
430 raise RuntimeError(
"It looks like Charles screwed up if you are seeing this.")
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]),
438 denom = xVals[index] - xVals[index - step]
439 numer = yVals[index] - yVals[index - step]
441 print " %8f" % (numer / denom),
442 if 0 == index % step:
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)
462 print "average weight per event:", weight / ( size - 1)
463 maxDistance = ROOT.TMath.KolmogorovTest (size, yArray,
466 prob = ROOT.TMath.KolmogorovProb( maxDistance * math.sqrt( size ) )
469 ROOT.gROOT.SetStyle(
'Plain')
470 ROOT.gROOT.SetBatch()
472 graph.GetXaxis().SetRangeUser (min (xVals), max (xVals))
473 minValue = min (
min(yVals),
min(expected))
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:
483 if 'instLum' == options.edfMode:
484 graph.GetXaxis().SetTitle (
"Average Xing Inst. Luminosity (1/ub/s)")
485 graph.GetXaxis().SetRangeUser (0., lumiCont.max(
'aveInstLum'))
487 if 'instIntLum' == options.edfMode:
488 graph.GetXaxis().SetTitle (
"Integrated Luminosity - Inst. Lum. Ordered (1/%s)" \
491 graph.GetXaxis().SetTitle (
"Integrated Luminosity (1/%s)" \
493 graph.GetYaxis().SetTitle (
"Fraction of Events Seen")
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),
502 expectedGraph.SetLineWidth (3)
503 if options.noDataPoints:
504 expectedGraph.SetLineStyle (2)
506 expectedGraph.SetLineColor (ROOT.kBlue)
508 expectedGraph.SetLineColor (ROOT.kRed)
509 expectedGraph.Draw(
"L")
510 expectedGraphs.append (expectedGraph)
511 exptectedGraph = expectedGraphs[0]
513 expectedGraph.Draw (
"L")
516 predArray = array.array (
'd', predVals)
517 green = ROOT.TGraph (size, xArray, predArray)
518 green.SetLineWidth (3)
519 green.SetLineColor (8)
521 legend = ROOT.TLegend(0.15, 0.65, 0.50, 0.85)
522 legend.SetFillStyle (0)
523 legend.SetLineColor(ROOT.kWhite)
524 observed =
'Observed' 526 observed +=
' (weighted)' 527 legend.AddEntry(graph, observed,
"PL")
528 if options.resetExpected:
529 legend.AddEntry(expectedGraph,
"Expected from partial yield",
"L")
531 legend.AddEntry(expectedGraph,
"Expected from total yield",
"L")
533 legend.AddEntry(green, options.predLabel,
"L")
534 legend.AddEntry(
"",
"D_{stat}=%.3f, N=%d" % (maxDistance, size),
"")
535 legend.AddEntry(
"",
"P_{KS}=%.3f" % prob,
"")
539 c1.Print (outputFile)
550 if __name__ ==
'__main__':
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',
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',
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',
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',
588 help =
'Ignore (with a warning) events that do not have a lumi section')
589 inputGroup.add_option (
'--noWarnings', dest=
'noWarnings',
591 help =
'Do not print warnings about missing luminosity information')
592 inputGroup.add_option (
'--runEventLumi', dest=
'relOrder',
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',
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()
611 if options.edfMode
not in allowedEDF:
612 raise RuntimeError(
"edfMode (currently '%s') must be one of %s" \
613 % (options.edfMode, allowedEDF))
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")
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
632 if options.runsWithLumis:
634 for line
in options.runsWithLumis:
635 pieces = sepRE.split (line)
638 recLumValue = float (piece)
640 raise RuntimeError(
"'%s' in '%s' is not a float" % \
643 raise RuntimeError(
"You must provide positive values for -runsWithLumis ('%f' given)" % recLumValue)
644 recLumis.append (recLumValue)
646 raise RuntimeError(
"What did Charles do now?")
649 recLumValue = recLumis [recLumIndex]
652 for key, lumi
in cont.iteritems():
653 if prevRecLumi >= recLumValue
and recLumValue < lumi.totalRecorded:
655 print "%s contains total recorded lumi %f" % \
656 (key.__str__(), recLumValue)
659 if recLumIndex == len (recLumis):
662 recLumValue = recLumis [recLumIndex]
663 if prevRecLumi >= recLumValue
and recLumValue < lumi.totalRecorded:
665 print "%s contains total recorded lumi %f" % \
666 (key.__str__(), recLumValue)
671 prevRecLumi = lumi.totalRecorded
672 if recLumIndex < len (recLumis):
673 print "Theses lumis not found: %s" % recLumis[recLumIndex:]
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)
def _integrateContainer(self)
def __init__(self, filename, kwargs)
def loadEvents(filename, cont, options)
General Functions
invunits
Now that everything is setup, switch integrated ## luminosity to more reasonable units.
def makeEDFplot(lumiCont, eventsDict, totalWeight, outputFile, options)
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