5353from pathlib import Path
5454import os
5555import re
56+ from warnings import warn
5657
5758import numpy as np
5859
@@ -109,6 +110,12 @@ def __init__(self, dirname="", load_sync_channel=False, load_channel_location=Fa
109110 BaseRawWithBufferApiIO .__init__ (self )
110111 self .dirname = dirname
111112 self .load_sync_channel = load_sync_channel
113+ if load_sync_channel :
114+ warn (
115+ "The load_sync_channel=True option is deprecated and will be removed in version 0.15. "
116+ "Use load_sync_channel=False instead, which will add sync channels as separate streams." ,
117+ DeprecationWarning , stacklevel = 2
118+ )
112119 self .load_channel_location = load_channel_location
113120
114121 def _source_name (self ):
@@ -152,6 +159,8 @@ def _parse_header(self):
152159 signal_buffers = []
153160 signal_streams = []
154161 signal_channels = []
162+ sync_stream_id_to_buffer_id = {}
163+
155164 for stream_name in stream_names :
156165 # take first segment
157166 info = self .signals_info_dict [0 , stream_name ]
@@ -168,6 +177,16 @@ def _parse_header(self):
168177 for local_chan in range (info ["num_chan" ]):
169178 chan_name = info ["channel_names" ][local_chan ]
170179 chan_id = f"{ stream_name } #{ chan_name } "
180+
181+ # Sync channel
182+ if "nidq" not in stream_name and "SY0" in chan_name and not self .load_sync_channel and local_chan == info ["num_chan" ] - 1 :
183+ # This is a sync channel and should be added as its own stream
184+ sync_stream_id = f"{ stream_name } -SYNC"
185+ sync_stream_id_to_buffer_id [sync_stream_id ] = buffer_id
186+ stream_id_for_chan = sync_stream_id
187+ else :
188+ stream_id_for_chan = stream_id
189+
171190 signal_channels .append (
172191 (
173192 chan_name ,
@@ -177,25 +196,33 @@ def _parse_header(self):
177196 info ["units" ],
178197 info ["channel_gains" ][local_chan ],
179198 info ["channel_offsets" ][local_chan ],
180- stream_id ,
199+ stream_id_for_chan ,
181200 buffer_id ,
182201 )
183202 )
184203
185- # all channel by dafult unless load_sync_channel=False
204+ # all channel by default unless load_sync_channel=False
186205 self ._stream_buffer_slice [stream_id ] = None
206+
187207 # check sync channel validity
188208 if "nidq" not in stream_name :
189209 if not self .load_sync_channel and info ["has_sync_trace" ]:
190- # the last channel is remove from the stream but not from the buffer
191- last_chan = signal_channels [- 1 ]
192- last_chan = last_chan [:- 2 ] + ("" , buffer_id )
193- signal_channels = signal_channels [:- 1 ] + [last_chan ]
210+ # the last channel is removed from the stream but not from the buffer
194211 self ._stream_buffer_slice [stream_id ] = slice (0 , - 1 )
212+
213+ # Add a buffer slice for the sync channel
214+ sync_stream_id = f"{ stream_name } -SYNC"
215+ self ._stream_buffer_slice [sync_stream_id ] = slice (- 1 , None )
216+
195217 if self .load_sync_channel and not info ["has_sync_trace" ]:
196218 raise ValueError ("SYNC channel is not present in the recording. " "Set load_sync_channel to False" )
197219
198220 signal_buffers = np .array (signal_buffers , dtype = _signal_buffer_dtype )
221+
222+ # Add sync channels as their own streams
223+ for sync_stream_id , buffer_id in sync_stream_id_to_buffer_id .items ():
224+ signal_streams .append ((sync_stream_id , sync_stream_id , buffer_id ))
225+
199226 signal_streams = np .array (signal_streams , dtype = _signal_stream_dtype )
200227 signal_channels = np .array (signal_channels , dtype = _signal_channel_dtype )
201228
@@ -237,6 +264,14 @@ def _parse_header(self):
237264 t_start = frame_start / sampling_frequency
238265
239266 self ._t_starts [stream_name ][seg_index ] = t_start
267+
268+ # This need special logic because sync not present in stream_names
269+ if f"{ stream_name } -SYNC" in signal_streams ["name" ]:
270+ sync_stream_name = f"{ stream_name } -SYNC"
271+ if sync_stream_name not in self ._t_starts :
272+ self ._t_starts [sync_stream_name ] = {}
273+ self ._t_starts [sync_stream_name ][seg_index ] = t_start
274+
240275 t_stop = info ["sample_length" ] / info ["sampling_rate" ]
241276 self ._t_stops [seg_index ] = max (self ._t_stops [seg_index ], t_stop )
242277
@@ -265,7 +300,11 @@ def _parse_header(self):
265300 if self .load_channel_location :
266301 # need probeinterface to be installed
267302 import probeinterface
268-
303+
304+ # Skip for sync streams
305+ if "SYNC" in stream_name :
306+ continue
307+
269308 info = self .signals_info_dict [seg_index , stream_name ]
270309 if "imroTbl" in info ["meta" ] and info ["stream_kind" ] == "ap" :
271310 # only for ap channel
0 commit comments