Побайтовое чтение файла и вывод данных в матрицу
Программа для побайтового чтения файла выдаёт значения в виде строк. Ссылка на файл который читается здесь 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))?