3 from itertools 
import groupby
 
    5 from AthenaCommon.Logging 
import logging
 
    6 from AthenaConfiguration.Enums 
import BeamType
 
    8 from .Limits 
import Limits
 
    9 from .L1MenuFlags 
import L1MenuFlags
 
   12 log = logging.getLogger(__name__)
 
   16     create BunchGroupSet for simulation 
   18     This BGS is independent from the menu, and contains only BG0 (BCRVeto) and BG1 (Paired) 
   28     sets default bunchgroups for all menus, needed for simulation. 
   30     if hasattr(L1MenuFlags, 
"BunchGroupNames"): 
 
   32         name = L1MenuFlags.MenuSetup().
partition(
'_')[0]
 
   36         if flags.Beam.Type 
is BeamType.Cosmics:
 
   39         bunchgroupnames = L1MenuFlags.BunchGroupNames()[:Limits.NumBunchgroups]
 
   40         bunchgroupnames += [
'NotUsed'] * (Limits.NumBunchgroups - len(bunchgroupnames))
 
   41         for i,bgname 
in enumerate(bunchgroupnames):
 
   42             bgs.bunchGroups[i].name = bgname
 
   52         nameUndefBG = 
"NotUsed" 
   53         def __init__(self, internalNumber, name = nameUndefBG, partition=0, bunches=None):
 
   55             if internalNumber<0 
or internalNumber >= Limits.NumBunchgroups:
 
   56                 raise RuntimeError(
'Cannot create bunchgroup with internal number %i (must be between 0 and %i)' % (internalNumber, Limits.NumBunchgroups-1))
 
   63             return "bunchgroup %s(%i) with %i bunches" % (self.
name, self.
internalNumber, len(self))
 
   76             """ turn list of bunches into trains """ 
   79             if any(map(
lambda bcid : bcid<0 
or bcid >= 3564, self.
bunches)):
 
   80                 raise RuntimeError(
"Found bcid outside range 0..3563 in bunchgroup %s" % self.
name)
 
   81             for k,g 
in groupby(enumerate(self.
bunches), 
lambda x : x[1]-x[0]):
 
   83                 self.
normalized += [ (train[0][1], len(train)) ]
 
   89                 "info":  f
"{len(self)} bunches, {len(self.normalized)} groups",
 
   90                 "bcids": [ {
"first": first, 
"length": length} 
for first, length 
in self.
normalized ]
 
  106         first = L1MenuFlags.BunchGroupPartitioning()
 
  107         last = first[1:] + [ Limits.NumBunchgroups ]
 
  108         partitioning = dict( zip([1,2,3],zip(first,last)) )
 
  121         doesExist = self.
bunchGroups[bunchGroup.internalNumber].name != BunchGroupSet.BunchGroup.nameUndefBG
 
  123             raise RuntimeError(
"Adding bunchgroup with internal number %i, which already exists" % bunchGroup.internalNumber)
 
  126         if hasattr(L1MenuFlags, 
"BunchGroupPartitioning"):
 
  127             for lowestBG 
in L1MenuFlags.BunchGroupPartitioning():
 
  128                 if bunchGroup.internalNumber >= lowestBG:
 
  130         bunchGroup.partition = partition
 
  131         self.
bunchGroups[bunchGroup.internalNumber] = bunchGroup
 
  136         confObj = {f
"BGRP{bg.internalNumber}": bg.json() 
for bg 
in self.
bunchGroups}
 
  139     def writeJSON(self, outputFile, destdir="./", pretty=True):
 
  140         outputFile = destdir.rstrip(
'/') + 
'/' + outputFile
 
  143             "filetype": 
"bunchgroupset",
 
  144             "bunchGroups": self.
json()
 
  146         with open( outputFile, mode=
"wt" ) 
as fh:
 
  148             json.dump(confObj, fh, indent = 4 
if pretty 
else None, separators=(
',', 
': '))
 
  149         log.info(
"Wrote %s", outputFile)