Побайтовое чтение файла и вывод данных в матрицу

Программа для побайтового чтения файла выдаёт значения в виде строк. Ссылка на файл который читается здесь https://disk.yandex.ru/d/CiLBuDH0qr2Lsg.


# Иморты 
import pandas as pd
import os
import math
import numpy as np
import csv

# для создания графика
import matplotlib
matplotlib.use('Agg') # без этого у меня не работает
from matplotlib import pyplot as plt

# Перевод ед.из.
rad_polar = 6356752.3142 # работа с координатами
max_uint4 = 4294967295 # работа с координатами
feet2m = 1/3.2808399  # перевод футов в метры

# Указываем путь sl2 файла
sl2file = ('C:/small.sl2')

# Открываем sl2 файл и начинаем чтение

with open(sl2file, "rb") as myfile:
    
    # Найти размер файла (в байтах)
    sl2file_size = os.path.getsize(sl2file)
    print('Размер файла (байты) :', sl2file_size)
    print('Расшифровка....(может занять несколько минут)')
    
    # Размеры блока dtype
    dt_block = np.dtype({'blockSize': ('<u2', 26)}) # 26- Block_Size в байтах
    
    block_offset = 10 # Заголовок файла 10 байт
    block_offset_list = [] # Пустой список для расположения блоков
    
    while block_offset < sl2file_size:
        myfile.seek(block_offset,0) # Начинать в начале каждого блока
        
        block_size = np.fromfile(myfile, dtype=dt_block, count=1) # Прочитать размер блока
        block_offset = block_offset + block_size[0][0] # Увеличить маркер позиции блока
        block_offset_list.append(block_offset) # Список смещений для использования позже

    # Используя размер блока, прочтите остальные данные из каждого блока.
    sl2blocks_dtype = np.dtype(dict(
      names=['channel','data_size','frame_index','lower_limit','sonar_frequency','water_depth','temperature', 'longitude', 'latitude','Dscat'],
      #names=['channel','data_size','frame_index','lower_limit','sonar_frequency','water_depth','speed_gps','temperature', 'longitude', 'latitude','Bitmask','Dscat'],
      offsets=[30, 32, 34, 46, 55, 62, 102, 106, 110,138], # отсчитывается от начала блока в байтах 
      # data_size = 32 байта и формат i2
      #offsets=[34, 36, 38, 46, 55, 64, 98, 106, 110, 112, 128, 142], # отсчитывается от начала блока в байтах 
      # номер канала, глубина, частота , глубина дна, скорость , температура, долгота и широта, данные которые нужно извлечь из канала =0
      # data_size = 3072     
      formats=['i2','i2','<u4','f4','f4','f4', 'f4', '<u4','<u4','i2'] 
      # последнее Dscat имеют формат int packetSize 140 Contains sounding/bounce data.
      #formats=['f4','f4','i4','f4','f4','f4', 'f4','f4', '<u4','<u4','u2','u2']
    )) # файл  Filesize %144 байта

    i=0 # Позиция в block_offset_list
    block_data = [] # Список для хранения данных
    
    
    for i in range(len(block_offset_list)-1): # Расчет до пред-последнего блока
        
        myfile.seek(block_offset_list[i],0) # Найти начало каждого блока
        data_array = np.fromfile(myfile, dtype=sl2blocks_dtype, count=1) # получить данные 
        
        # получить данные из массива
        channel = data_array[0][0]
        data_size = data_array[0][1]
        frame_index = data_array[0][2]
        lowlim = data_array[0][3] # lower_limit
        frequency = data_array[0][4]  # sonar_frequency ; просмотреть частоту (пока не нужна)
        depth = data_array[0][5] # 
        #speedgps = data_array[0][6] # speed_gps ; скорость пока не нужна
        temperature = data_array[0][6] 
        lon = data_array[0][7]  
        lat = data_array[0][8]  
        #bitmask = data_array[0][11]
        Dscat = data_array[0][9]  # Dscat(данные которые нужно получить) 
        # данные формата матрицы frame_index/data_size
             
        # Фильтр для нужного мне канала ( сейчас это канал Primary (обычный сонар))
        if channel==0: # & data_size !=3200 :  # канал настрое верно    
            #depthM = depth 
            # перевод глубины в метры
            
            depthM = (depth * feet2m)*-1
            # перевод координат согласно меркатору ловренс
            longitude = (lon - max_uint4) / rad_polar * (180/math.pi)
            latitude = ((2*math.atan(math.exp(lat/rad_polar)))-(math.pi/2)) * (180/math.pi)
        
           # файл с блоком данных
           #block = {'waterDepthM': depthM, 'longitude': longitude, 'latitude': latitude }
            block = {'data': Dscat}
           # block = {'data':frame_index}
           # block = {'data':data_size}
           # block = {'data_size':data_size, 'depthM': depthM,'temp':temperature,'lon':longitude,'lat':latitude,'lowlim':lowlim }
           # block_data.append(block)
            block_data.append(block)
        
       
myfile.close() # закрывает файл и завершает все циклы
print('Чтение завершенно. Номер последнего блока: ',len(block_data))
print(block_data[200]) # выводим для примера блок 200
#print(block_data)

Подскажите как мне стоит считать данные Dscat, что бы они были в формате матрицы (1:data_size/1:len(frame_index))?


Ответы (0 шт):