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__":