4 Minimal python module for CTP fragment access/modification 
    6 For C++ implementation see: 
    7 https://gitlab.cern.ch/atlas-tdaq-software/CTPfragment 
   14 cppyy.load_library(
'libTrigByteStreamToolsDict')
 
   15 cppyy.load_library(
'libCTPfragment')
 
   16 from ROOT 
import CTPdataformat
 
   17 from ROOT 
import CTPfragment 
as _CTPfragment
 
   18 from ROOT.CTPfragment 
import getFolderUpdates  
 
   21 FolderEntry = _CTPfragment.FolderEntry
 
   22 ExtraPayload = _CTPfragment.ExtraPayload
 
   25    """Helper to return versioned members of CTPdataformat""" 
   29       attr = 
'%s_v%d' % (name, v)
 
   33    return getattr(obj,attr) 
 
   36    """Set value in bitset using mask and shifting n bits to the left""" 
   37    v = bitset & (0xffffffff ^ (mask << shift))
 
   38    v = v | (value << shift)
 
   42    """Return list of bits [0,1,1,0,...] from list of 32-bit trigger words""" 
   55    """Return list of trigger words from list of bits""" 
   58       words[bit//32] |= 1<<(bit%32)
 
   62    """Get CTP fragment format version""" 
   63    v = (rob.rod_minor_version() >> CTPdataformat.CTPFormatVersionShift) & CTPdataformat.CTPFormatVersionMask
 
   67    """Set CTP fragment format version""" 
   68    V = 
_setBits32(rob.rod_minor_version(), version,
 
   69                   CTPdataformat.CTPFormatVersionShift, CTPdataformat.CTPFormatVersionMask)
 
   70    rob.rod_minor_version(V)
 
   75    return (rob.rod_detev_type() >> 
_versioned(CTPdataformat,
'HltCounterShift',v) & 
_versioned(CTPdataformat,
'HltCounterMask',v))
 
   84    return (rob.rod_detev_type() >> CTPdataformat.LumiBlockShift & CTPdataformat.LumiBlockMask)
 
   87    lbits = 
_setBits32(rob.rod_detev_type(), lb, CTPdataformat.LumiBlockShift, CTPdataformat.LumiBlockMask)
 
   88    rob.rod_detev_type(lbits)
 
   91    """Number extra payload words (this includes the time since last L1A)""" 
   96       return ((rob.rod_minor_version() >> 
_versioned(CTPdataformat,
'ProgrammableExtraWordsShift',v)
 
   97                & 
_versioned(CTPdataformat,
'ProgrammableExtraWordsMask',v)))
 
  100    """Number extra payload words (this does NOT include the time since last L1A)""" 
  111    """Return CTPfragment::ExtraPayload object created from CTP ROB""" 
  112    v = cppyy.gbl.std.vector(
'unsigned int')()
 
  116    x = _CTPfragment.ExtraPayload(v)
 
  122    wrob = eformat.write.ROBFragment(rob)
 
  124    data = [d 
for d 
in wrob.rod_data()]
 
  133    data.extend(extraWords)
 
  140    V = 
_setBits32(wrob.rod_minor_version(), len(extraWords)+ctp_extras,
 
  141                   _versioned(CTPdataformat,
'ProgrammableExtraWordsShift',v),
 
  142                   _versioned(CTPdataformat,
'ProgrammableExtraWordsMask',v))
 
  143    wrob.rod_minor_version(V)
 
  145    return wrob.readonly()
 
  148    """Get position of LVL1-Accept Bunch from ROD Fragment""" 
  151    shift = 
_versioned(CTPdataformat,
'L1APositionShift',v)
 
  153       return (rob.rod_detev_type() >> shift) & CTPdataformat.L1APositionMask
 
  155       return (rob.rod_minor_version() >> shift) & CTPdataformat.L1APositionMask
 
  158    """Get trigger words""" 
  165    if v>4 
and rob.source_id().module_id()==1:
 
  170    l1abunch = 0 
if rob.source_id().module_id()==1 
else lvl1AcceptBunch(rob)
 
  172    data = [d 
for d 
in rob.rod_data()]
 
  173    pos = l1abunch*
_versioned(CTPdataformat,
'DAQwordsPerBunch',v) + pos
 
  174    return data[pos:pos+words]
 
  181    from optparse 
import OptionParser
 
  184    parser = OptionParser(usage=
'%prog FILE')
 
  185    parser.add_option(
'-m', 
'--moduleid', type=
'int', action=
'store', default=0,
 
  186                      help=
'Module ID of CTP fragment [%default]')
 
  188    (opt, args) = parser.parse_args()  
 
  193    for event 
in eformat.istream(args[0]):
 
  194       ctp_robs = [rob 
for rob 
in event.children()
 
  195                   if rob.source_id().subdetector_id() == eformat.helper.SubDetector.TDAQ_CTP
 
  196                   and rob.source_id().module_id() == opt.moduleid]
 
  199          print(
"Cannot find CTP ROB with module ID %d" % opt.moduleid)
 
  203       fe = _CTPfragment.FolderEntry()
 
  207       fe2 = _CTPfragment.FolderEntry()
 
  212       x = _CTPfragment.ExtraPayload()
 
  217       new_event = eformat.write.FullEventFragment()
 
  218       new_event.copy_header(event)
 
  219       for r 
in event.children():
 
  220          if r.source_id().subdetector_id() != eformat.helper.SubDetector.TDAQ_CTP:
 
  221             new_event.append(eformat.write.ROBFragment(r))
 
  223       new_event.append(eformat.write.ROBFragment(new_ctp_rob))
 
  225       event = new_event.readonly()
 
  231       folderUpdates = _CTPfragment.getFolderUpdates(x)
 
  233       for f 
in folderUpdates:
 
  234          upd += (
'[%d,%d]' % (f.second.folderIndex,f.second.lumiBlock))
 
  236       print(
"L1ID %10d, LB %4d, Version %d, Bunch %d, HLT counter: %3d, Payload #%d %s L1PSK %d BGK %d COOLUPD %s" % (
 
  249 if __name__ == 
"__main__":