@@ -900,8 +900,6 @@ def __read_nsx_header_variant_b(self, nsx_nb):
900900 # label of the sampling group (e.g., "1 kS/s" or "LFP low")
901901 ("label" , "S16" ),
902902 ("comment" , "S256" ),
903- # ("application_to_create_file", "S52"), # A 52-character string labeling the program which created the file. Trellis will also include its revision number in this label.
904- # ("processor_timestamp", "uint32"), # The processor timestamp (in 30 kHz clock cycles) at which the data in the file were collected.
905903 ("period" , "uint32" ),
906904 ("timestamp_resolution" , "uint32" ),
907905 # time origin: 2byte uint16 values for ...
@@ -921,7 +919,6 @@ def __read_nsx_header_variant_b(self, nsx_nb):
921919
922920 # extended header (type: CC)
923921 offset_dt0 = np .dtype (dt0 ).itemsize
924- shape = int (nsx_basic_header ["channel_count" ])
925922 dt1 = [
926923 ("type" , "S2" ),
927924 ("electrode_id" , "uint16" ),
@@ -946,7 +943,8 @@ def __read_nsx_header_variant_b(self, nsx_nb):
946943 ("lo_freq_type" , "uint16" ),
947944 ] # 0=None, 1=Butterworth, -2-Chebyshev
948945
949- nsx_ext_header = np .memmap (filename , shape = shape , offset = offset_dt0 , dtype = dt1 , mode = "r" )
946+ channel_count = int (nsx_basic_header ["channel_count" ])
947+ nsx_ext_header = np .memmap (filename , shape = channel_count , offset = offset_dt0 , dtype = dt1 , mode = "r" )
950948
951949 return nsx_basic_header , nsx_ext_header
952950
@@ -958,7 +956,7 @@ def __read_nsx_dataheader(self, nsx_nb, offset):
958956
959957 major_version = self .__nsx_basic_header [nsx_nb ]["ver_major" ]
960958 ts_size = "uint64" if major_version >= 3 else "uint32"
961- #ts_size = "uint64"
959+
962960 # dtypes data header, the header flag is always set to 1
963961 dt2 = [("header_flag" , "uint8" ), ("timestamp" , ts_size ), ("nb_data_points" , "uint32" )]
964962
@@ -998,21 +996,28 @@ def __read_nsx_dataheader_variant_b(
998996 while offset < filesize :
999997 packet_header = self .__read_nsx_dataheader (nsx_nb , offset )
1000998 header_flag = packet_header ["header_flag" ]
1001- # assert header_flag == 1, f"Invalid header flag: {header_flag}"
999+ # NSX data blocks must have header_flag = 1, other values indicate file corruption
1000+ if header_flag != 1 :
1001+ raise ValueError (
1002+ f"Invalid NSX data block header at offset { offset :#x} in ns{ nsx_nb } file. "
1003+ f"Expected header_flag=1, got { header_flag } . "
1004+ f"This may indicate file corruption or unsupported NSX format variant. "
1005+ f"Block index: { data_block_index } , File size: { filesize } bytes"
1006+ )
10021007 timestamp = packet_header ["timestamp" ]
10031008 offset_to_data_block_start = offset + packet_header .dtype .itemsize
10041009 num_data_points = int (packet_header ["nb_data_points" ])
1005-
1010+
10061011 data_header [data_block_index ] = {
10071012 "header" : header_flag ,
10081013 "timestamp" : timestamp ,
10091014 "nb_data_points" : num_data_points ,
10101015 "offset_to_data_block" : offset_to_data_block_start ,
10111016 }
10121017
1013- data_array_size = num_data_points * channel_count * np .dtype ("int16" ).itemsize
10141018 # Jump to the next data block
1015- offset = offset_to_data_block_start + data_array_size
1019+ data_block_size = num_data_points * channel_count * np .dtype ("int16" ).itemsize
1020+ offset = offset_to_data_block_start + data_block_size
10161021
10171022 data_block_index += 1
10181023
0 commit comments