@@ -125,62 +125,45 @@ def _parse_header(self):
125125 channel_number_dict ,
126126 ) = read_rhd (self .filename , self .file_format )
127127
128- # memmap raw data with the complicated structured dtype
128+ # memmap the raw data for each format type
129129 # if header-attached there is one giant memory-map
130130 if self .file_format == "header-attached" :
131131 self ._raw_data = np .memmap (self .filename , dtype = data_dtype , mode = "r" , offset = header_size )
132- else :
132+
133+ # for 'one-file-per-signal' we have one memory map / neo stream
134+ elif self .file_format == "one-file-per-signal" :
133135 self ._raw_data = {}
134136 for stream_index , (stream_index_key , stream_datatype ) in enumerate (data_dtype .items ()):
135- # for 'one-file-per-signal' we have one memory map / neo stream
136- if self .file_format == "one-file-per-signal" :
137- n_chans = channel_number_dict [stream_index_key ]
138- if stream_index_key == 4 or stream_index_key == 5 :
139- n_samples = int (os .path .getsize (raw_file_paths_dict [stream_index_key ]) / 2 ) # uint16 2 bytes
140- else :
141- n_samples = int (
142- os .path .getsize (raw_file_paths_dict [stream_index_key ]) / (n_chans * 2 )
143- ) # unit16 2 bytes
144- if stream_index_key != 6 :
145- self ._raw_data [stream_index ] = np .memmap (
146- raw_file_paths_dict [stream_index_key ],
147- dtype = stream_datatype ,
148- shape = (n_chans , n_samples ),
149- mode = "r" ,
150- ).T
151- else :
152- self ._raw_data [stream_index ] = np .memmap (
153- raw_file_paths_dict [stream_index_key ], dtype = stream_datatype , mode = "r"
154- )
155- # for one-file-per-channel we have one memory map / channel stored as a list / neo stream
156- else :
157- self ._raw_data [stream_index ] = []
158- for channel_index , channel_datatype in enumerate (stream_datatype ):
159- if stream_index_key != 6 :
160- self ._raw_data [stream_index ].append (
161- np .memmap (
162- raw_file_paths_dict [stream_index_key ][channel_index ],
163- dtype = channel_datatype ,
164- mode = "r" ,
165- )
166- )
167- else :
168- self ._raw_data [stream_index ].append (
169- np .memmap (
170- raw_file_paths_dict [stream_index_key ][channel_index ],
171- dtype = [channel_datatype ],
172- mode = "r" ,
173- )
174- )
137+ num_channels = channel_number_dict [stream_index_key ]
138+ file_path = raw_file_paths_dict [stream_index_key ]
139+ size_in_bytes = file_path .stat ().st_size
140+ dtype_size = np .dtype (stream_datatype ).itemsize
141+ n_samples = size_in_bytes // (dtype_size * num_channels )
142+ signal_stream_memmap = np .memmap (file_path , dtype = stream_datatype , mode = "r" , shape = (num_channels , n_samples )).T
143+ self ._raw_data [stream_index ] = signal_stream_memmap
144+
145+ # for one-file-per-channel we have one memory map / channel stored as a list / neo stream
146+ elif self .file_format == "one-file-per-channel" :
147+ self ._raw_data = {}
148+ for stream_index , (stream_index_key , stream_datatype ) in enumerate (data_dtype .items ()):
149+ self ._raw_data [stream_index ] = []
150+ num_channels = channel_number_dict [stream_index_key ]
151+ for channel_index in range (num_channels ):
152+ file_path = raw_file_paths_dict [stream_index_key ][channel_index ]
153+ channel_memmap = np .memmap (file_path , dtype = stream_datatype , mode = "r" )
154+ self ._raw_data [stream_index ].append (channel_memmap )
155+
175156
176157 # check timestamp continuity
177158 if self .file_format == "header-attached" :
178159 timestamp = self ._raw_data ["timestamp" ].flatten ()
179160 # timestamps are always the last stream
180161 elif self .file_format == "one-file-per-signal" :
181- timestamp = self ._raw_data [max (self ._raw_data .keys ())]["timestamp" ].flatten ()
182- else :
183- timestamp = self ._raw_data [max (self ._raw_data .keys ())][0 ]["timestamp" ].flatten ()
162+ time_stream_index = max (self ._raw_data .keys ())
163+ timestamp = self ._raw_data [time_stream_index ]
164+ elif self .file_format == "one-file-per-channel" :
165+ time_stream_index = max (self ._raw_data .keys ())
166+ timestamp = self ._raw_data [time_stream_index ][0 ]
184167
185168 assert np .all (np .diff (timestamp ) == 1 ), (
186169 "Timestamp have gaps, this could be due " "to a corrupted file or an inappropriate file merge"
@@ -346,6 +329,7 @@ def _get_analogsignal_chunk_header_attached(self, i_start, i_stop, stream_index,
346329
347330 return sigs_chunk
348331
332+
349333 def _get_analogsignal_chunk_one_file_per_channel (self , i_start , i_stop , stream_index , channel_indexes ):
350334
351335 signal_data_memmap_list = self ._raw_data [stream_index ]
@@ -368,6 +352,7 @@ def _get_analogsignal_chunk_one_file_per_channel(self, i_start, i_stop, stream_i
368352
369353 return sigs_chunk
370354
355+
371356 def _get_analogsignal_chunk_one_file_per_signal (self , i_start , i_stop , stream_index , channel_indexes ):
372357
373358 # One memmap per stream case
@@ -697,23 +682,13 @@ def read_rhd(filename, file_format: str):
697682 if file_format == "header-attached" :
698683 data_dtype = [("timestamp" , "int32" , BLOCK_SIZE )]
699684 else :
700- data_dtype [6 ] = [
701- (
702- "timestamp" ,
703- "int32" ,
704- )
705- ]
685+ data_dtype [6 ] = "int32"
706686 channel_number_dict [6 ] = 1
707687 else :
708688 if file_format == "header-attached" :
709689 data_dtype = [("timestamp" , "uint32" , BLOCK_SIZE )]
710690 else :
711- data_dtype [6 ] = [
712- (
713- "timestamp" ,
714- "uint32" ,
715- )
716- ]
691+ data_dtype [6 ] = "uint32"
717692 channel_number_dict [6 ] = 1
718693
719694 # 0: RHD2000 amplifier channel
@@ -727,12 +702,12 @@ def read_rhd(filename, file_format: str):
727702 else :
728703 chan_info ["offset" ] = 0.0
729704 ordered_channels .append (chan_info )
705+
730706 if file_format == "header-attached" :
731707 data_dtype += [(name , "uint16" , BLOCK_SIZE )]
732- elif file_format == "one-file-per-signal" :
733- data_dtype [0 ] = "int16"
734708 else :
735- data_dtype [0 ] += ["int16" ]
709+ data_dtype [0 ] = "int16"
710+
736711
737712 # 1: RHD2000 auxiliary input channel
738713 for chan_info in channels_by_type [1 ]:
@@ -744,10 +719,9 @@ def read_rhd(filename, file_format: str):
744719 ordered_channels .append (chan_info )
745720 if file_format == "header-attached" :
746721 data_dtype += [(name , "uint16" , BLOCK_SIZE // 4 )]
747- elif file_format == "one-file-per-signal" :
748- data_dtype [1 ] = "uint16"
749722 else :
750- data_dtype [1 ] += ["uint16" ]
723+ data_dtype [1 ] = "uint16"
724+
751725
752726 # 2: RHD2000 supply voltage channel
753727 for chan_info in channels_by_type [2 ]:
@@ -759,10 +733,8 @@ def read_rhd(filename, file_format: str):
759733 ordered_channels .append (chan_info )
760734 if file_format == "header-attached" :
761735 data_dtype += [(name , "uint16" )]
762- elif file_format == "one-file-per-signal" :
736+ else :
763737 data_dtype [2 ] = "uint16"
764- else :
765- data_dtype [2 ] += ["uint16" ]
766738
767739 # temperature is not an official channel in the header
768740 for i in range (global_info ["num_temp_sensor_channels" ]):
@@ -792,10 +764,8 @@ def read_rhd(filename, file_format: str):
792764 ordered_channels .append (chan_info )
793765 if file_format == "header-attached" :
794766 data_dtype += [(name , "uint16" , BLOCK_SIZE )]
795- elif file_format == "one-file-per-signal" :
796- data_dtype [3 ] = "uint16"
797767 else :
798- data_dtype [3 ] += [ "uint16" ]
768+ data_dtype [3 ] = "uint16"
799769
800770 # 4: USB board digital input channel
801771 # 5: USB board digital output channel
@@ -817,10 +787,9 @@ def read_rhd(filename, file_format: str):
817787 ordered_channels .append (chan_info )
818788 if file_format == "header-attached" :
819789 data_dtype += [(name , "uint16" , BLOCK_SIZE )]
820- elif file_format == "one-file-per-signal" :
821- data_dtype [sig_type ] = "uint16"
822790 else :
823- data_dtype [sig_type ] += ["uint16" ]
791+ data_dtype [sig_type ] = "uint16"
792+
824793
825794 if global_info ["notch_filter_mode" ] == 2 and version >= V ("3.0" ):
826795 global_info ["notch_filter" ] = "60Hz"
0 commit comments