acoused/Model/peacock_uvp/apf04_measures.py

141 lines
5.0 KiB
Python

#!/usr/bin/env python
# -*- coding: UTF_8 -*-
# @copyright this code is the property of Ubertone.
# You may use this code for your personal, informational, non-commercial purpose.
# You may not distribute, transmit, display, reproduce, publish, license, create derivative works from, transfer or sell any information, software, products or services based on this code.
# @author Marie Burckbuchler
# @date 20 Aout 2020
from array import *
from struct import calcsize, unpack
from math import sqrt, pi, pow
from Model.peacock_uvp.apf_timestamp import decode_timestamp
from Model.peacock_uvp.apf04_gain import _convert_code2dB_trunc, convert_code2dB_m, convert_code2dB, calc_gain
# @brief Utilise une frame pour récupérer un profil voulu (format UDT005)
# # une ligne de profil dans raw UDT005 contient
# le raw profile contient un header puis le profil codé
# ce header contient des scalaires qu'il faut aussi enregistrer
# @param _data : le bloc de données binaire
def extract_measures (data, config_hw) :
size = len(data)
data_dict = {
"velocity" : [],
"amplitude" : [],
"snr" : [],
"std" : []
}
# Attention, pas de ref à lire à ce stade
# Lecture du timestamp
data_dict["timestamp"], offset = decode_timestamp( data )
head_size = offset
scalars_size = calcsize('hhhhhhhh')
data_dict['pitch'], data_dict['roll'], data_dict['temp'], \
sound_speed, data_dict['gain_ca0'], data_dict['gain_ca1'], \
data_dict['noise_g_max'], data_dict['noise_g_mid'] \
= unpack('hhhhhhhh', data[head_size:head_size+scalars_size])
# A few acoustic parameters which are needed for the following calculations
n_vol = config_hw.n_vol
c_prf = config_hw.c_prf
n_avg = config_hw.n_avg
#r_dvol = to_dict(self.config_hw[self.current_config - 1].config_hw, sound_speed)['r_dvol']
#r_vol1 = to_dict(self.config_hw[self.current_config - 1].config_hw, sound_speed)['r_vol1']
blind_ca0 = config_hw.blind_ca0
blind_ca1 = config_hw.blind_ca1
if (size-(head_size+scalars_size))/4/2 != n_vol:
raise Exception('volume number', "expected %d volumes, but profile data contains %d"%(n_vol, ((size-(head_size+scalars_size))/4/2)))
tab_size = calcsize('h')
offset = head_size+scalars_size
for i in range(n_vol):
data_dict['velocity'].append(unpack('h', data[offset: offset + tab_size])[0])
offset += calcsize('h')
data_dict['std'].append(unpack('h', data[offset: offset + tab_size])[0])
offset += calcsize('h')
data_dict['amplitude'].append(unpack('h', data[offset: offset + tab_size])[0])
offset += calcsize('h')
data_dict['snr'].append(unpack('h', data[offset: offset + tab_size])[0])
offset += calcsize('h')
# conversion des valeurs codées:
# Note: il faut convertir les scalaires après pour avoir les gains tels que pour la conversion du profil d'echo
conversion_profile(data_dict, sound_speed, n_vol, n_avg, c_prf, data_dict['gain_ca0'], data_dict['gain_ca1'], blind_ca0, blind_ca1)
#conversion_scalar(scalars_dict)
#conversion_us_scalar(scalars_us_dict, n_avg, r_dvol, r_vol1)
return data_dict
def conversion_profile(data_dict, sound_speed, n_vol, n_avg, c_prf, gain_ca0, gain_ca1, blind_ca0, blind_ca1):
sat = array('f')
ny_jump = array('f')
v_ref = 1.25
fact_code2velocity = sound_speed / (c_prf * 65535.)
# print("factor code to velocity %f"%fact_code2velocity)
tab_gain = calc_gain(n_vol, gain_ca0, gain_ca1, blind_ca0, blind_ca1)
for i in range(n_vol):
# Velocity standard deviation
if data_dict['std'][i] == -32768:
data_dict['std'][i] = None
else:
if data_dict['std'][i] < 0:
ny_jump.append(True)
data_dict['std'][i] *= -1
else:
ny_jump.append(False)
data_dict['std'][i] = data_dict['std'][i]*fact_code2velocity
# Velocity
if data_dict['velocity'][i] == -32768:
data_dict['velocity'][i] = None
else:
data_dict['velocity'][i] *= fact_code2velocity
# SNR Doppler
if data_dict['snr'][i] == -32768:
data_dict['snr'][i] = None
else:
data_dict['snr'][i] /= 10.
# Echo amplitude
if data_dict['amplitude'][i] < 0:
sat.append(True)
data_dict['amplitude'][i] *= -1
else:
sat.append(False)
data_dict['amplitude'][i] *= ((v_ref*2)/4096) / sqrt(n_avg) / tab_gain[i]
def conversion_scalar(data_dict):
# convert temperature to Kelvin
data_dict["temp"] += 273.15
# convert angles to red
data_dict['pitch'] *= pi/180.
data_dict['roll'] *= pi/180.
def conversion_us_scalar(self, data_dict, n_avg, r_dvol, r_vol1):
# convert coded gain to dB and dB/m
data_dict["a1"] = convert_code2dB_m(data_dict["gain_ca1"], r_dvol)
del data_dict["gain_ca1"]
data_dict["a0"] = convert_code2dB(data_dict["gain_ca0"])-data_dict["a1"]*r_vol1
del data_dict["gain_ca0"]
# convert coded noise values to V
v_ref = 1.25
gain = pow(10, ((_convert_code2dB_trunc(1241)) / 20.)) # gain max
data_dict["noise_g_high"] = sqrt(data_dict["noise_g_max"]) * ((v_ref*2)/4096) / sqrt(n_avg) / gain
del data_dict["noise_g_max"]
gain = pow(10, ((_convert_code2dB_trunc(993)) / 20.)) # gain max - 10dB
data_dict["noise_g_low"] = sqrt(data_dict["noise_g_mid"]) * ((v_ref*2)/4096) / sqrt(n_avg) / gain
del data_dict["noise_g_mid"]