@@ -1577,7 +1577,9 @@ def __init__(self, *arg, **kwargs):
15771577 def _get_signal_size (self , block_index , seg_index , stream_index ):
15781578 buffer_id = self .header ["signal_streams" ][stream_index ]["buffer_id" ]
15791579 buffer_desc = self .get_analogsignal_buffer_description (block_index , seg_index , buffer_id )
1580- # some hdf5 revert teh buffer
1580+ # time_axis indicates which dimension is time:
1581+ # time_axis=0: shape is (time, channels)
1582+ # time_axis=1: shape is (channels, time)
15811583 time_axis = buffer_desc .get ("time_axis" , 0 )
15821584 return buffer_desc ["shape" ][time_axis ]
15831585
@@ -1598,34 +1600,67 @@ def _get_analogsignal_chunk(
15981600
15991601 buffer_desc = self .get_analogsignal_buffer_description (block_index , seg_index , buffer_id )
16001602
1603+ # Get time_axis to determine which dimension is time
1604+ time_axis = buffer_desc .get ("time_axis" , 0 )
1605+
16011606 i_start = i_start or 0
1602- i_stop = i_stop or buffer_desc ["shape" ][0 ]
1607+ i_stop = i_stop or buffer_desc ["shape" ][time_axis ]
16031608
16041609 if buffer_desc ["type" ] == "raw" :
16051610
1606- # open files on demand and keep reference to opened file
1607- if not hasattr (self , "_memmap_analogsignal_buffers" ):
1608- self ._memmap_analogsignal_buffers = {}
1609- if block_index not in self ._memmap_analogsignal_buffers :
1610- self ._memmap_analogsignal_buffers [block_index ] = {}
1611- if seg_index not in self ._memmap_analogsignal_buffers [block_index ]:
1612- self ._memmap_analogsignal_buffers [block_index ][seg_index ] = {}
1613- if buffer_id not in self ._memmap_analogsignal_buffers [block_index ][seg_index ]:
1614- fid = open (buffer_desc ["file_path" ], mode = "rb" )
1615- self ._memmap_analogsignal_buffers [block_index ][seg_index ][buffer_id ] = fid
1616- else :
1617- fid = self ._memmap_analogsignal_buffers [block_index ][seg_index ][buffer_id ]
1611+ if time_axis == 0 :
1612+ # MULTIPLEXED: time_axis=0 means (time, channels) layout
1613+ # open files on demand and keep reference to opened file
1614+ if not hasattr (self , "_memmap_analogsignal_buffers" ):
1615+ self ._memmap_analogsignal_buffers = {}
1616+ if block_index not in self ._memmap_analogsignal_buffers :
1617+ self ._memmap_analogsignal_buffers [block_index ] = {}
1618+ if seg_index not in self ._memmap_analogsignal_buffers [block_index ]:
1619+ self ._memmap_analogsignal_buffers [block_index ][seg_index ] = {}
1620+ if buffer_id not in self ._memmap_analogsignal_buffers [block_index ][seg_index ]:
1621+ fid = open (buffer_desc ["file_path" ], mode = "rb" )
1622+ self ._memmap_analogsignal_buffers [block_index ][seg_index ][buffer_id ] = fid
1623+ else :
1624+ fid = self ._memmap_analogsignal_buffers [block_index ][seg_index ][buffer_id ]
1625+
1626+ num_channels = buffer_desc ["shape" ][1 ]
1627+
1628+ raw_sigs = get_memmap_chunk_from_opened_file (
1629+ fid ,
1630+ num_channels ,
1631+ i_start ,
1632+ i_stop ,
1633+ np .dtype (buffer_desc ["dtype" ]),
1634+ file_offset = buffer_desc ["file_offset" ],
1635+ )
16181636
1619- num_channels = buffer_desc ["shape" ][1 ]
1637+ elif time_axis == 1 :
1638+ # VECTORIZED: time_axis=1 means shape is (channels, time)
1639+ # Data is stored as [all_samples_ch1, all_samples_ch2, ...]
1640+ dtype = np .dtype (buffer_desc ["dtype" ])
1641+ num_channels = buffer_desc ["shape" ][0 ] # shape is (channels, time)
1642+ num_samples = i_stop - i_start
1643+ total_samples_per_channel = buffer_desc ["shape" ][1 ] # shape is (channels, time)
1644+
1645+ # Determine which channels to read
1646+ if channel_indexes is None :
1647+ chan_indices = np .arange (num_channels )
1648+ else :
1649+ chan_indices = np .asarray (channel_indexes )
1650+
1651+ raw_sigs = np .empty ((num_samples , len (chan_indices )), dtype = dtype )
1652+
1653+ for i , chan_idx in enumerate (chan_indices ):
1654+ offset = buffer_desc ["file_offset" ] + chan_idx * total_samples_per_channel * dtype .itemsize
1655+ channel_data = np .memmap (buffer_desc ["file_path" ], dtype = dtype , mode = 'r' ,
1656+ offset = offset , shape = (total_samples_per_channel ,))
1657+ raw_sigs [:, i ] = channel_data [i_start :i_stop ]
1658+
1659+ # Channel slicing already done above, so skip later channel_indexes slicing
1660+ channel_indexes = None
16201661
1621- raw_sigs = get_memmap_chunk_from_opened_file (
1622- fid ,
1623- num_channels ,
1624- i_start ,
1625- i_stop ,
1626- np .dtype (buffer_desc ["dtype" ]),
1627- file_offset = buffer_desc ["file_offset" ],
1628- )
1662+ else :
1663+ raise ValueError (f"time_axis must be 0 or 1, got { time_axis } " )
16291664
16301665 elif buffer_desc ["type" ] == "hdf5" :
16311666
0 commit comments