@@ -72,6 +72,12 @@ def __init__(self, dirname="", load_sync_channel=False, experiment_names=None):
7272 experiment_names = [experiment_names ]
7373 self .experiment_names = experiment_names
7474 self .load_sync_channel = load_sync_channel
75+ if load_sync_channel :
76+ warn (
77+ "The load_sync_channel=True option is deprecated and will be removed in version 0.15. "
78+ "Use load_sync_channel=False instead, which will add sync channels as separate streams." ,
79+ DeprecationWarning , stacklevel = 2
80+ )
7581 self .folder_structure = None
7682 self ._use_direct_evt_timestamps = None
7783
@@ -123,7 +129,8 @@ def _parse_header(self):
123129 # signals zone
124130 # create signals channel map: several channel per stream
125131 signal_channels = []
126-
132+ sync_stream_id_to_buffer_id = {}
133+ normal_stream_id_to_sync_stream_id = {}
127134 for stream_index , stream_name in enumerate (sig_stream_names ):
128135 # stream_index is the index in vector stream names
129136 stream_id = str (stream_index )
@@ -134,21 +141,28 @@ def _parse_header(self):
134141 chan_id = chan_info ["channel_name" ]
135142
136143 units = chan_info ["units" ]
144+ channel_stream_id = stream_id
137145 if units == "" :
138146 # When units are not provided they are microvolts for neural channels and volts for ADC channels
139147 # See https://open-ephys.github.io/gui-docs/User-Manual/Recording-data/Binary-format.html#continuous
140148 units = "uV" if "ADC" not in chan_id else "V"
141149
142150 # Special cases for stream
143151 if "SYNC" in chan_id and not self .load_sync_channel :
144- # the channel is removed from stream but not the buffer
145- stream_id = ""
152+ # Every stream sync channel is added as its own stream
153+ sync_stream_id = f"{ stream_name } SYNC"
154+ sync_stream_id_to_buffer_id [sync_stream_id ] = buffer_id
155+
156+ # We save this mapping for the buffer description protocol
157+ normal_stream_id_to_sync_stream_id [stream_id ] = sync_stream_id
158+ # We then set the stream_id to the sync stream id
159+ channel_stream_id = sync_stream_id
146160
147161 if "ADC" in chan_id :
148162 # These are non-neural channels and their stream should be separated
149163 # We defined their stream_id as the stream_index of neural data plus the number of neural streams
150164 # This is to not break backwards compatbility with the stream_id numbering
151- stream_id = str (stream_index + len (sig_stream_names ))
165+ channel_stream_id = str (stream_index + len (sig_stream_names ))
152166
153167 gain = float (chan_info ["bit_volts" ])
154168 sampling_rate = float (info ["sample_rate" ])
@@ -162,7 +176,7 @@ def _parse_header(self):
162176 units ,
163177 gain ,
164178 offset ,
165- stream_id ,
179+ channel_stream_id ,
166180 buffer_id ,
167181 )
168182 )
@@ -174,12 +188,21 @@ def _parse_header(self):
174188 signal_buffers = []
175189
176190 unique_streams_ids = np .unique (signal_channels ["stream_id" ])
191+
192+ # This is getting too complicated, we probably should just have a table which would be easier to read
193+ # And for users to understand
177194 for stream_id in unique_streams_ids :
178- # Handle special case of Synch channel having stream_id empty
179- if stream_id == "" :
195+
196+ # Handle sync channel on a special way
197+ if "SYNC" in stream_id :
198+ # This is a sync channel and should not be added to the signal streams
199+ buffer_id = sync_stream_id_to_buffer_id [stream_id ]
200+ stream_name = stream_id
201+ signal_streams .append ((stream_name , stream_id , buffer_id ))
180202 continue
181- stream_index = int ( stream_id )
203+
182204 # Neural signal
205+ stream_index = int (stream_id )
183206 if stream_index < self ._num_of_signal_streams :
184207 stream_name = sig_stream_names [stream_index ]
185208 buffer_id = stream_id
@@ -254,7 +277,12 @@ def _parse_header(self):
254277
255278 if num_adc_channels == 0 :
256279 if has_sync_trace and not self .load_sync_channel :
280+ # Exclude the sync channel from the main stream
257281 self ._stream_buffer_slice [stream_id ] = slice (None , - 1 )
282+
283+ # Add a buffer slice for the sync channel
284+ sync_stream_id = normal_stream_id_to_sync_stream_id [stream_id ]
285+ self ._stream_buffer_slice [sync_stream_id ] = slice (- 1 , None )
258286 else :
259287 self ._stream_buffer_slice [stream_id ] = None
260288 else :
@@ -264,7 +292,12 @@ def _parse_header(self):
264292 self ._stream_buffer_slice [stream_id_neural ] = slice (0 , num_neural_channels )
265293
266294 if has_sync_trace and not self .load_sync_channel :
295+ # Exclude the sync channel from the non-neural stream
267296 self ._stream_buffer_slice [stream_id_non_neural ] = slice (num_neural_channels , - 1 )
297+
298+ # Add a buffer slice for the sync channel
299+ sync_stream_id = normal_stream_id_to_sync_stream_id [stream_id ]
300+ self ._stream_buffer_slice [sync_stream_id ] = slice (- 1 , None )
268301 else :
269302 self ._stream_buffer_slice [stream_id_non_neural ] = slice (num_neural_channels , None )
270303
0 commit comments