Чтение файла формата sl2
Мне необходимо прочесть файл формата sl2 и вытащить из него данные, в виде строк, и одно значение в виде матрицы. ссылка на файл который мне нужно прочесть.
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 #
# Загрузить файл
#sl2file = input('загрузить файл.sl2') почему то input долго выполняется( очень долго )
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)})
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) # список смещений
# Используя размер блока, прочтитать остальные данные из каждого блока.
# https://wiki.openstreetmap.org/wiki/SL2 по этой ссылке есть структура файла
sl2blocks_dtype = np.dtype(dict(
names=['channel','data_size','frame_index','lower_limit','sonar_frequency','water_depth','speed_gps','temperature', 'longitude', 'latitude',' Bitmask','Dscat'],
# номер канала, глубина, частота , глубина дна, скорость , температура, долгота и широта, данные которые нужно извлечь из канала =0
# data_size = 3072
# frame_index = n для канала = 0 # для файла small.sl2 n=4017
# Dscat должна быть матрица размерами 3072 на n
offsets=[32, 34, 36, 44, 53, 60, 100, 104, 108, 112, 128, 140], # отсчитывается от начала блока в байтах
# формат значений
formats=['uint16','uint16','uint32','float32', 'uint8', 'float32', 'float32','float32', 'float32', 'float32','uint16','uint8'],
)) # файл 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][7]
lon = data_array[0][8]
lat = data_array[0][9]
bitmask = data_array[0][10]
Dscat = data_array[0][11] # Dscat( данные которые мне нужно получить )
# перевод глубины в метры
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.append(block)
# Чтение определенного канала
j=1 # цикл для канала
if channel = 0 # и по идее на этом этапе цикла должны накладаваться bitmask,
# но я не совсем понимаю как это работает
# if channel = 0 && bitmask=2
data_size1(j) = data_size
frame_index1(j) = frame_index
lowlim1(j) = lowlim # lower_limit
frequency1(j) = frequency # sonar_frequency
depth1(j) = depth #
speedgps1(j) = speedgps # speed_gps
temperature1(j) = temperature
lon1(j) = lon
lat1(j) = lat
j=j+1
myfile.close() # закрывает файл
print('Данные расшифрованы и создан блок данных')
print('Вывод глубины( должно быть n значений) :',depth1)
Питон ругается на J=1. Пожалуйста подскажите, что делать