剖模, server desktop分支
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
profiler/profiler.py

823 lines
91 KiB

from dataclasses import dataclass,field
from pathlib import Path
from typing import Any,List,Callable
from enum import Enum
import numpy as np
import struct
import time
from scipy.optimize import leastsq
from datetime import datetime, timedelta
from myRamses import RamsesFactoryHandle,AirWater
from tools.mylogger import log
from myconfig import TOKEN,NEWLINE,DATA_DIR,SAVE_EXT_NAME,CAL_DIR
from myconfig import RamsesPROFILE
from pubsub import pub
TIME_STR = "2022-06-10 16:16:16"
STD_TIME_STR_FMT = "%Y-%m-%d %H:%M:%S" # 小写y是两位年份
CUR_TIME_STR_FMT = "%Y-%m-%d %H:%M:%S"
@dataclass
class InfoFrame(object):
""" 剖面, 深度Depth: offset"""
infoBytes:bytes = None
time_str:str= None
time_stamp:int= None
year:str= None
month:str= None
day:str= None
hour:str= None
minute:str= None
second:str= None
Roll: int= None
Pitch:int= None
Yaw:int= None
Hx:int= None
Hy:int= None
lon:int= None
lat:int= None
satelite_num:int= None
PDOP:int= None
HDOP:int= None
VDOP:int= None
Temperature:int= None
Humidity:int = None
Battery:int= None
ErrorCode:int= None
Azimuth:int= None
RunAngle:int= None
MeasureGroupNum:int= None
Tiltx:int= None
Tilty:int= None
Depth:int= None
SN1:str= None
SN2:str= None
SN3:str= None
MeasureInterval :int= None
MeasureRepeat: int= None
ip_bytes = b''
def output_info_frame(self, ):
ret = ""
ret = ret + "time : " + self.time_stamp
ret = ret + NEWLINE + "time_stamp : " + self.time_stamp
ret = ret + NEWLINE + "year : " + self.year
ret = ret + NEWLINE + "month : " + self.month
ret = ret + NEWLINE + "day : " + self.day
ret = ret + NEWLINE + "hour : " + self.hour
ret = ret + NEWLINE + "minute : " + self.minute
ret = ret + NEWLINE + "second : " + self.second
ret = ret + NEWLINE + "Roll : " + self.Roll
ret = ret + NEWLINE + "Pitch : " + self.Pitch
ret = ret + NEWLINE + "Yaw : " + self.Yaw
ret = ret + NEWLINE + "Hx : " + self.Hx
ret = ret + NEWLINE + "Hy : " + self.Hy
ret = ret + NEWLINE + "Hz : " + self.Hz
ret = ret + NEWLINE + "lon : " + self.lon
ret = ret + NEWLINE + "lat : " + self.lat
ret = ret + NEWLINE + "PDOP : " + self.PDOP
ret = ret + NEWLINE + "HDOP : " + self.HDOP
ret = ret + NEWLINE + "VDOP : " + self.VDOP
ret = ret + NEWLINE + "Temperature : " + self.Temperature
ret = ret + NEWLINE + "Humidity : " + self.Humidity
ret = ret + NEWLINE + "Battery : " + self.Battery
ret = ret + NEWLINE + "ErrorCode : " + self.ErrorCode
ret = ret + NEWLINE + "Azimuth : " + self.Azimuth
ret = ret + NEWLINE + "RunAngle : " + self.RunAngle
ret = ret + NEWLINE + "MeasureGroupNum : " + self.MeasureGroupNum
ret = ret + NEWLINE + "Tiltx : " + self.Tiltx
ret = ret + NEWLINE + "Tilty : " + self.Tilty
ret = ret + NEWLINE + "Depth : " + self.Depth
ret = ret + NEWLINE + "SN1 : " + self.SN1
ret = ret + NEWLINE + "SN2 : " + self.SN2
ret = ret + NEWLINE + "SN3 : " + self.SN3
ret = ret + NEWLINE + "MeasureInterval : " + self.MeasureInterval
ret = ret + NEWLINE + "MeasureRepeat : " + self.MeasureRepeat
return ret
pass
def set_info_frame(self, info:bytes):
# log.info( f" {info}", __name__, "set_info_frame")
ret = {}
try:
temp = struct.unpack("<BBBBBBHHHHHHIIHHHHHBBBHHIfff \
HHHBHBHHHHH \
HHHHHHBBBBBBBBBBBBBB",
info)
except Exception as e:
log.info( "decode info 有误, 收到info frame 字节有误",__name__,"set_info_frame","" )
return ret
temp = list(temp) # tuple to list
time_ = "20" + f"{str(temp[0])}" + "-" + f"{str(temp[1])}" + "-" + f"{str(temp[2])}" + " " \
+ f"{str(temp[3])}" + ":" + f"{str(temp[4])}" + ":" + f"{str(temp[5])}"
self.time_str = time_
self.time_stamp = 0
self.year:str = str(temp[0])
self.month:str = str(temp[1])
self.day:str = str(temp[2])
self.hour:str = str(temp[3])
self.minute:str = str(temp[4])
self.second:str = str(temp[5])
self.Roll: int = temp[6]
self.Pitch:int = temp[7]
self.Yaw:int = temp[8]
self.Hx:int = temp[9]
self.Hy:int = temp[10]
self.Hz:int = temp[11]
self.lon:int = temp[12]
self.lat:int = temp[13]
self.satelite_num:int = temp[14]
self.PDOP:int = temp[15]
self.HDOP:int = temp[16]
self.VDOP:int = temp[17]
self.Temperature:int = temp[18]
self.Humidity:int = temp[19]
self.Battery:int = temp[20]
self.ErrorCode:int = temp[21]
self.Azimuth:int = temp[22]
self.RunAngle:int = temp[23]
self.MeasureGroupNum:int = temp[24]
self.Tiltx:int = temp[25]
self.Tilty:int = temp[26]
self.Depth:int = temp[27]
self.SN1:str = hex(temp[28])[2:].upper()
self.SN2:str = hex(temp[29])[2:].upper()
self.SN3:str = hex(temp[30])[2:].upper()
self.MeasureInterval :int = temp[31]
self.MeasureRepeat: int = temp[32]
self.ip_bytes = info[-26:] # 提取ip_bytes
pass
@dataclass
class DataFrame(object):
''' AWRAMS 数据无需 remove_mask
多组 : 每组类似 26 + 576*3 = 1754, ?26+576*2= 1178
数据接收方式 AWRAMS格式, 从文件读取
'''
deviceID:int = None
measureId: int = None
mode:int = 3
dataBytes:bytes = None # 26 + 576*3 = 1754
data_ip: bytes = None # IP数据
data_ramses: List[bytes] = None # IP数据
wavelength: List = None
spectrum: List = None
def set_data_bytes(self, byt:bytes):
'''
不含 15 AA... , 26(*) +576(*)
TODO : 考虑只有两个传感器情况
'''
self.dataBytes = byt
self.data_ip = byt[:26]
self.data_ramses =[]
if self.mode == 3:
self.data_ramses.append( byt[26:26+576])
self.data_ramses.append( byt[26+576:26+576*2])
self.data_ramses.append( byt[26+576*2:26+576*3])
if self.mode == 2:
self.data_ramses.append( byt[26:26+576])
self.data_ramses.append( byt[26+576*2:26+576*3])
pass
def set_ramses_num(self, mode:int):
self.mode = mode
pass
def set_wavelength(self, wv:List):
self.wavelength = wv
pass
def set_spectrum(self, spectrum:List):
self.spectrum = spectrum
pass
def get_wavelength(self ):
return self.wavelength
pass
def get_spectrum(self ):
return self.spectrum
pass
@dataclass
class ProfilerData(object):
deviceid:int =None
configSensor:List[str] = None # 序列号 Ed Esky Lu
configFunc:List[str] = None # Ed Esky Lu
currentPath:Path =None
info_frame:InfoFrame = None
data_frame:DataFrame = None # 数据只到分组成byte结束
ramsesFactoryHandle:List[RamsesFactoryHandle] = None # 多个工厂,每个工厂有自己的 标定文件及参数,工厂标记序列哈,只处理相同序列号的产品数据
depth:float = None
tiltx:float = None
tilty:float = None
wavelength:List[List[float]] =None
spectrum:List[List[float]] =None
pass
def __post_init__(self):
assert self.deviceid != None , ">>>> AWRAMSData deviceid is empty"
pass
def build_datafactory_by_configSensor(self,calcfg:dict):
"""
@description : 调用工厂得到整数值
@param : 576字节数据, 数据id(第几个传感器,还是序列号)
@Returns : List[int]
"""
assert self.configSensor != None, ">>>> AWRAMSData configSensor is None"
self.ramsesFactoryHandle = [None,None,None]
for i in range(0, len( self.configSensor)):
# log.warning( self.configFunc[i], "build_datafactory_by_configSensor" )
cfg = calcfg[self.configFunc[i]]
tmp_ramses_factory_handle = RamsesFactoryHandle( sn= self.configSensor[i], cfg=cfg )
if self.configFunc[i] == RamsesPROFILE(1).name or self.configFunc[i] == RamsesPROFILE(3).name:
tmp_ramses_factory_handle.set_air_water(AirWater.Water)
self.ramsesFactoryHandle[i] = tmp_ramses_factory_handle
# 获得波长
def set_wavelength(self ):
self.wavelength = []
for i in range(0, len( self.configSensor)):
self.ramsesFactoryHandle[i].rf.get_wavelenth()
self.wavelength.append (self.ramsesFactoryHandle[i].rf.Wavelength)
def set_info_frame(self, info_frame:bytes):
self.info_frame = InfoFrame()
self.info_frame.set_info_frame(info_frame) #已经解析
pass
def set_data_frame( self, data_byte: bytes , pth: Path, func ):
"""
@description : 剖面数据, 处理某个深度的 1754字节数据
TODO : 依据数据数量进行处理
"""
log.debug( f" arg: data_byte: bytes ", __name__, "set_data_frame" )
self.data_frame = DataFrame()
# self.data_frame.set_ramses_num(3)
self.data_frame.set_data_bytes(data_byte )
# log.warning( f"data_byte: {data_byte} ", __name__, "set_data_frame" )
# 调用ramsesFactoryHandle 对字节数据进行处理
ip_buf = self.data_frame.data_ip
# self.wavelength = []
self.spectrum = []
for i in range(0, len( self.configSensor)):
self.ramsesFactoryHandle[i].deal_raw_data( self.data_frame.data_ramses[i], 0)
self.spectrum.append (self.ramsesFactoryHandle[i].rf.data_after_cal)
if self.configFunc[i] == RamsesPROFILE(1).name:
self.depth,self.tiltx,self.tilty = self.ramsesFactoryHandle[i].deal_raw_ip_buf(self.data_frame.data_ip)
pass
# 回调函数
func( self.wavelength, self.spectrum,self.depth,self.tiltx,self.tilty)
@dataclass
class Profiler(object):
deviceid:int = None
configSensor:List[str] =None # 序列号
configFunc:List[str] =None # 功能 Ed Esky Lu
calibrationCfg:dict =None
data : ProfilerData =None
depth : List[float] =None
wavelength:List[np.ndarray] =None
spectrum:List[np.ndarray] =None
immersion_factors:np.ndarray = None
beginWavelength: float = None
endWavelength: float = None
rowFactor:float = None
wvInterval: float = None
depth_offset = None
tiltx_range = 1.0
tilty_range = 1.0
newWavelength:np.ndarray= None
Ed:np.ndarray = None # 无需记录原始波长,记录插值后的波长
Esky:np.ndarray = None
Lu:np.ndarray = None
Kd:np.ndarray = None
Ed0:np.ndarray = None
Ku:np.ndarray = None
Lu0:np.ndarray = None
Lw:np.ndarray = None
Rs:np.ndarray = None
afterdeal = []
afterresult =[]
def __post_init__(self):
assert self.deviceid != None
self.data = ProfilerData(deviceid=self.deviceid )
pass
def set_cfg_calibration(self,calcfg:dict):
assert self.deviceid != None
# assert self.deviceid in calcfg.keys(), f">>>> No calibrations data for the current id {self.deviceid}"
self.calibrationCfg = calcfg
pass
def set_retrieve(self,rtv:dict):
log.debug(f" rtv {rtv}",__name__,"set_retrieve")
self.beginWavelength = float(rtv["beginWL"])
self.endWavelength = float(rtv["endWL"])
self.wvInterval = float(rtv["interval"])
self.n_t_square = float(rtv["n_t_square"])
# self.rowFactor = float(rtv["rowFactor"]) # TODO
self.newWavelength = np.arange(self.beginWavelength,self.endWavelength,self.wvInterval)
pass
def set_immersion_factors(self, ifs:np.ndarray):
wv = ifs[:, 0]
val = ifs[:, 1]
self.immersion_factors = np.interp(self.newWavelength,wv,val)
pass
def set_ramses_sensor_numbers(self, num:int = 3):
self.data.data_frame = DataFrame()
self.data.data_frame.set_ramses_num( num )
pass
def set_tilt_range( self, tilt_angle:float = 7 ):
self.tiltx_range = tilt_angle
self.tilty_range = tilt_angle
pass
def config_awrams(self, cfg:dict):
log.warning(f" sensor cfg : {cfg}",__name__,"config_awrams")
assert self.deviceid in cfg.keys(), f'>> Cannot get the configuration of device id : {self.deviceid}'
cfg = cfg.get(self.deviceid)
self.configSensor = [ None, None, None ]
self.configFunc = [ None, None, None ]
# Ed Esky Lu
# {1: {'FUNC': 'Ed', 'SN': '85B5'}, 2: {'FUNC': 'Esky', 'SN': '50ED'}, 3: {'FUNC': 'Lu', 'SN': '852F'}}
for k,v in cfg.items() :
# log.debug( f" {v} -- {RamsesPROFILE(1).name}")
if v["FUNC"] == RamsesPROFILE(1).name:
self.configSensor[0] = v["SN"]
self.configFunc[0] = v["FUNC"]
if v["FUNC"] == RamsesPROFILE(2).name:
self.configSensor[1] = v["SN"]
self.configFunc[1] = v["FUNC"]
if v["FUNC"] == RamsesPROFILE(3).name:
self.configSensor[2] = v["SN"]
self.configFunc[2] = v["FUNC"]
if RamsesPROFILE(1).name not in self.configFunc:
raise f" No Ed cal info"
if RamsesPROFILE(3).name not in self.configFunc:
raise f" No Lu cal info"
# 将传感器配置传给 AWRAMSDATA
self.data = ProfilerData( deviceid=self.deviceid, configSensor=self.configSensor, configFunc=self.configFunc )
# 将标定配置传给 AWRAMSData 建立工厂
self.data.build_datafactory_by_configSensor( self.calibrationCfg)
pass
def get_depth_offset(self,):
assert self.data.info_frame.ip_bytes != b'', ">>>> No Ip_bytes data,Pls check!"
ip_bytes = self.data.info_frame.ip_bytes
cal = self.calibrationCfg.get( RamsesPROFILE(1).name)
self.depth_offset,_,_ = self.decode_ip_buf(ip_bytes, cal)
self.depth = [] # depth None -> List
pass
def decode_ip_buf(self, buf, ip_cal:dict):
tmpbuf = buf
if len(tmpbuf) == 26 and tmpbuf[0] == 0x13:
tmpbuf = tmpbuf[2:]
Incl_Xgain = float(ip_cal['Incl_Xgain'] )
Incl_Xoffset = float(ip_cal['Incl_Xoffset'] )
Incl_Ygain = float(ip_cal['Incl_Ygain'] )
Incl_Yoffset = float(ip_cal['Incl_Yoffset'] )
Incl_Kref = float(ip_cal['Incl_Kref'] )
Press_Sens_mV_bar_1mA = float(ip_cal['Press_Sens_mV_bar_1mA'] )
Incl_KBG = float(ip_cal['Incl_KBG'] )
Press_Sens_mV_bar_4mA = float(ip_cal['Press_Sens_mV_bar_4mA'] )
Press_Gain = float(ip_cal['Press_Gain'] )
Press_Surface_bar = float(ip_cal['Press_Surface_bar'] )
ip_info = struct.unpack("<BBBBBBBBBBBBBBBBBBBBBBBB", tmpbuf)
byte11 = ip_info[11]
byte12 = ip_info[12]
byte13 = ip_info[13]
byte14 = ip_info[14]
byte15 = ip_info[15]
byte16 = ip_info[16]
byte17 = ip_info[17]
byte18 = ip_info[18]
byte19 = ip_info[19]
byte20 = ip_info[20]
byte21 = ip_info[21]
byte22 = ip_info[22]
X = (byte11 -Incl_Xoffset) / Incl_Xgain # 单位 度
Y = (byte12 - Incl_Yoffset ) / Incl_Ygain # 单位 度
npress = byte14 *256 + byte13
nbg = byte18 * 256 + byte17
nrefh = byte20 * 256 + byte19
nrefl = byte22 * 256 + byte21
noffset = nrefl - ( Incl_Kref * (nrefh-nrefl))
VPress = Incl_KBG * (npress-noffset) / (nbg- noffset) #电压值
press_sens = Press_Sens_mV_bar_4mA
if press_sens <= 0:
press_sens = 4* Press_Sens_mV_bar_1mA
p_bar = 1000 * VPress / (press_sens * Press_Gain )
press_delta = p_bar - 1.021
depth_m = press_delta * 10
return depth_m,X,Y
def callback( self, wavelength:list, spectrum:list ,*args):
''' 将数据保存到数据项 '''
log.info( f" call-back depth tiltx tilty : {args[0]} {args[1]} {args[2]} ", __name__,"" )
# 过滤倾斜值
# log.warning( f" call back tilt: {args[1]} {args[2]} ", __class__ )
if args[1] and abs(args[1]) > self.tiltx_range:
return None
if args[2] and abs(args[2]) > self.tilty_range:
return None
# 深度值
log.debug( f" call back depth offset: {self.depth_offset} ", __name__ )
self.depth.append( args[0] - self.depth_offset )
wv = wavelength
spctrm = spectrum
log.warning( f" call back wv : {wv} ", __class__ )
log.warning( f" call back spctrm : {spctrm} ", __class__ )
# 插值处理, 直接处理, 不按传感器功能处理了
tmp_Ed = np.interp( self.newWavelength, np.array(wv[0]), np.array(spctrm[0]) )
tmp_Lu = np.interp( self.newWavelength, np.array(wv[2]), np.array(spctrm[2]) )
if not self.Ed.size :
self.Ed = tmp_Ed
else:
self.Ed = np.vstack( (self.Ed, tmp_Ed) )
if not self.Lu.size :
self.Lu = tmp_Lu
else:
self.Lu = np.vstack( (self.Lu, tmp_Lu) )
def reset_profiler(self,):
log.info( " >> ",__name__,"reset_profiler" )
self.Ed = np.array([])
self.Esky = np.array([])
self.Lu = np.array([])
self.Kd = np.array([])
self.Ed0 = np.array([])
self.Ku = np.array([])
self.Lu0 = np.array([])
self.Lw = np.array([])
self.Rs = np.array([])
def process_profiler(self,n_t_square:float):
log.info( " >> ", __name__, "process_profiler" )
self.get_Ed0_kd()
self.get_Lu0_Ku()
self.get_Lw_Rs(n_t_square)
def get_Lw_Rs ( self, n_t_square:float):
''' Get Lw Rs '''
log.info( " >> ", __name__, "get_Lw_Rs" )
self.Lw = n_t_square * self.Lu0
self.Rs = self.Lw/ self.Ed0
def get_Lu0_Ku ( self, ):
'''' Get Lu0 Ku '''
log.info( " >> ", __name__, "get_Lu0_Ku" )
x = np.array(self.depth)
## 浸没因子处理 ##
tmp = self.deal_Lu_by_immersion_factors()
y = np.log(tmp) # ln_Lu
self.Ku,ln_Lu0 = self.leastsq_linear_fitting( x, y)
self.Lu0 = np.exp(ln_Lu0)
def get_Ed0_kd( self, ):
'''' Get Ed0 Kd '''
log.info( f" >> ",__name__,"get_Ed0_kd" )
# log.warning( f"depth: {self.depth}" )
x = np.array(self.depth)
y = np.log(self.Ed) # ln_Ed
self.Kd, ln_Ed0 = self.leastsq_linear_fitting( x, y)
self.Ed0 = np.exp(ln_Ed0)
# t = self.leastsq_linear_fitting( x, y)
# log.warning(self.Kd)
# log.warning(t)
# log.warning(self.Ed0)
def deal_Lu_by_immersion_factors ( self, ):
'''' ?????? 浸没因子处理 Lu ??? '''
ifs = self.immersion_factors
lu = self.Lu
return lu
def leastsq_linear_fitting( self, arr_depth:np.ndarray, arr_data:np.ndarray ):
'''最小二乘拟合
# arr_depth np一维数组
# arr_data np二维数组,需切片出来处理
'''
log.info(f" ->>>> {arr_depth} ", __name__, 'leastsq_linear_fitting (y=kx+b)')
log.info(f" ->>>> {arr_data}", __name__, 'leastsq_linear_fitting (y=kx+b)')
k = []
b = []
arr_x = arr_depth
arr_y = arr_data
# print(arr_x.shape)
# print(arr_y.shape)
for i in range( arr_y.shape[1] ) :
# 切出第一列
x_ = arr_x
y_ = arr_y[:,i]
# 拟合
p0 = [1,20] # [k,b]
para = leastsq( self.fitting_error, p0, args = ( x_, y_ ) )
k.append( para[0][0] )
b.append( para[0][1] )
return np.array(k), np.array(b)
# 需要拟合的函数 fitting_func
def fitting_func( self, p, x ):
k,b=p
return k*x+b
# 拟合的残差函数
def fitting_error(self,p,x,y):
return self.fitting_func(p,x)-y
def save(self, pth:Path, mode=0):
''' 保存在原文件所在目录 '''
log.info( " >> save ", __class__, "save" )
log.debug( f"Lw: {self.Lw}" )
# pth = self.data.currentPath
fname = "20"+self.data.info_frame.year+"_"+self.data.info_frame.month+"_" \
+self.data.info_frame.day+"_"+self.data.info_frame.hour+"_" \
+self.data.info_frame.minute+"_"+self.data.info_frame.second \
+".csv"
save_fpath = pth.joinpath(fname)
ret = ""
ret = ret + str(self.deviceid)+"_"+pth.parts[-1] + TOKEN + self.list2str(list(self.newWavelength))
ret = ret + NEWLINE + "Kd" + TOKEN + self.list2str( list(self.Kd) )
ret = ret + NEWLINE + "Ed0" + TOKEN + self.list2str( list(self.Ed0) )
ret = ret + NEWLINE + "ku" + TOKEN + self.list2str( list(self.Ku) )
ret = ret + NEWLINE + "Lu0" + TOKEN + self.list2str( list(self.Lu0) )
ret = ret + NEWLINE + "Lw" + TOKEN + self.list2str( list(self.Lw) )
ret = ret + NEWLINE + "Rs" + TOKEN + self.list2str( list(self.Rs) )
save_fpath.write_text( ret )
pass
def list2str( self, lst:list, token=";" ):
''' 保存在原文件所在目录 '''
ret = ""
for i in range(len(lst)):
if i == 0:
ret = ret + str(lst[i])
else:
ret = ret + TOKEN + str(lst[i])
return ret
pass
def registet_func(self, func:Callable):
self.afterdeal.append(func)
pass
def execute_func(self, ):
for f in self.afterdeal:
f()
pass
class ProfilerHandle(object):
def __init__(self, deviceid=2, cfg=None, calcfg=None, rtv=None):
self.sensor_cfg = cfg
self.calcfg = calcfg
self.retrieve = rtv
self.device_id = deviceid
self.profiler = Profiler( deviceid=self.device_id )
self.profiler.set_cfg_calibration( self.calcfg )
self.profiler.set_retrieve( self.retrieve)
self.profiler.config_awrams( self.sensor_cfg )
self.afterdeal = []
pass
def set_ramses_number( self, numbers:int =3 ):
self.profiler.set_ramses_sensor_numbers(numbers)
def set_tilt_range( self, tilt_angle:float =7.0 ):
self.profiler.set_tilt_range(tilt_angle)
def read_info_path(self,infopath: Path ):
assert infopath.exists(), f">>>> not find {infopath} "
ret_bytes = b''
with open(infopath, 'rb') as file:
ret_bytes = file.read()
# log.warning( f"{infopath} {ret_bytes}",__name__,"read_info_path")
self.profiler.data.set_info_frame( ret_bytes )
def read_sensor_path(self, sensorpath:Path):
assert sensorpath.exists(), f">>>> not find {sensorpath} "
with open(sensorpath, 'rb') as file:
ret_bytes = file.read()
assert len(ret_bytes) > 1754, f">>>> no data "
tmp_len = int(len(ret_bytes)/1754)
log.info( f"Total len : {len(ret_bytes)} num: {tmp_len} ", __name__, "read_sensor_path")
for i in range(tmp_len):
tmp_buf = ret_bytes[0+1754*i:1754+1754*i]
self.profiler.data.set_data_frame( tmp_buf, None, self.profiler.callback ) # tmp_buf包装成List
pass
def read_one_folder_awrams_online(self, pth:Path):
''' self.data 传数据 info_frame, data_frame'''
log.info(f" 读一个文件夹进行处理 {pth}" ,__name__,"read_one_folder_awrams_online")
bytes_list = []
bin_files = pth.glob('*.bin')
for bf in bin_files:
if bf.name != "info.bin":
bytes_list.append( self.read_bin(bf) )
self.profiler.data.set_data_frame( bytes_list, pth, self.profiler.callback ) # 目录也要传过去
pass
def read_folders_from_SD(self, pth:Path):
''' self.data 传数据 info_frame, data_frame'''
log.info(f" 读 SD文件夹进行处理 {pth}" ,__name__,"read_one_folder_awrams_online")
fs = None
filelist = []
fs = pth.glob( "*/*/info/*" )
msg = { "flag":"notice", "data": "开始处理数据 " }
pub.sendMessage('update' , msg=msg)
for f in fs:
if f.stat().st_size == 0:
continue
infopath = f
mypath = f.parent.parent
log.info( f">> {mypath}", __name__, "read_folders_from_SD", '')
sensorpath = mypath.joinpath( 'sensor', f.name )
if not sensorpath.exists() or sensorpath.stat().st_size == 0:
continue
savedir = DATA_DIR.joinpath("output")
# 处理SD 需要多处理info_frame
self.set_ramses_number(3)
self.set_tilt_range(21.0)
# self.profiler.data.set_info_frame( self.read_bin(f) )
self.read_info_path(infopath)
self.profiler.reset_profiler()
self.profiler.data.set_wavelength( ) # 设置波长
2 years ago
self.profiler.set_immersion_factors( self.read_immersion_factors( ) ) # 设置浸没因子
# log.warning( f" {self.profiler.data.wavelength}" )
self.profiler.get_depth_offset()
self.read_sensor_path(sensorpath)
self.profiler.get_Ed0_kd()
self.profiler.get_Lu0_Ku()
self.profiler.get_Lw_Rs(self.retrieve["n_t_square"])
self.profiler.save(savedir)
# # 按单次测量的处理
# self.deal_sensor_bin( sensor_path)
msg = {"flag":"notice", "data": "完成数据处理 " }
pub.sendMessage('update' , msg=msg)
pass
def read_immersion_factors(self,)->np.ndarray:
assert fpath.exists(), f">>>> not find {fpath} "
fname = "immersion_factors_Lu.dat"
fpath = CAL_DIR.joinpath( "profiler" ,fname)
ret = np.loadtxt(fpath,skiprows=2)
return ret
pass
def read_bin(self,fpath: Path):
assert fpath.exists(), f">>>> not find {fpath} "
ret = b''
with open(fpath, 'rb') as file:
ret = file.read()
return ret
pass
pass
class ExternalFun(object):
def __init__(self, aw:Profiler=None):
pass
@staticmethod
def get_par_400_700( aw:Profiler ):
par_400_700 = 0.0
for i in range( 50, 350, 1 ):
par_400_700 = par_400_700 + aw.Esky
return par_400_700
pass
@staticmethod
def get_par_350_950( aw:Profiler):
par_350_950 = 0.0
for i in range( 0, 600, 1 ):
par_350_950 = par_350_950 + aw.Esky
return par_350_950
pass
@staticmethod
def get_chl( aw:Profiler ):
return 0.0
pass
pass
class ProfilerCfg:
cfg= {1: {'FUNC': 'Ed', 'SN': '50ED'}, 2: {'FUNC': 'Esky', 'SN': '85C2'}, 3: {'FUNC': 'Lu', 'SN': '852F'}}
calcfg= {'Esky': {'SN': '85C2', 'FUNC': 'Esky', 'TYPE': 'SAM', 'samsn': '85C2', 'inifile': 'SAM_85C2.ini', 'calfile': 'Cal_SAM_85C2.dat', 'calaqfile': 'CalAQ_SAM_85C2.dat', 'backfile': 'Back_SAM_85C2.dat', 'cal': ['+NAN', '+NAN', '+NAN', '+NAN', '0.63607834406219', '0.718127096538326', '0.812216798598817', '0.914442457893824', '1.03343454996493', '1.15933885373154', '1.29479643420084', '1.43677001665361', '1.56848190839848', '1.67447970580786', '1.73889146263122', '1.73244260903254', '1.69192414835577', '1.61622082709111', '1.5270353751059', '1.46047364317447', '1.41296265347303', '1.39311700938614', '1.39852760194912', '1.42554260762195', '1.4700968507055', '1.53635620441153', '1.62082921439482', '1.7237742274692', '1.84755749123585', '1.98432162640748', '2.12689147788928', '2.27366206436985', '2.41515311346652', '2.54267625633242', '2.65248757975216', '2.73468816910085', '2.77942967914337', '2.79565522877852', '2.77806955157777', '2.73891358506136', '2.69063680629234', '2.6282750012231', '2.56338981635672', '2.49687123158122', '2.4309933291301', '2.36993023507549', '2.32161558853422', '2.28314087424895', '2.25846162084215', '2.24994522727437', '2.25549954861938', '2.27668712518828', '2.30493256690767', '2.33255656715114', '2.35720768052834', '2.37757260164886', '2.40002374613635', '2.42905705371268', '2.4673307146952', '2.51294806887351', '2.56575613007937', '2.62193109349514', '2.67842958533042', '2.73753357518048', '2.7913329207665', '2.8423865946084', '2.89027340109411', '2.93157202353872', '2.96274906831744', '2.98346548286676', '2.98798866816702', '2.97297872291037', '2.93559195933884', '2.87662286787444', '2.80380712732453', '2.72275302648293', '2.6373282860483', '2.55448424591999', '2.47778601018081', '2.40377038673745', '2.33484934711808', '2.2698793292122', '2.20651375086021', '2.14704740380438', '2.08988763493926', '2.0346458333411', '1.98224825426305', '1.93452491480363', '1.89146397238956', '1.8653548650058', '1.84879059497611', '1.8371693859594', '1.83197484046632', '1.83105981302589', '1.83169544364263', '1.83369029033973', '1.82985806236537', '1.81684973319988', '1.7961872241934', '1.76710061502081', '1.73459539138238', '1.70421983997876', '1.67561137148482', '1.65483955955664', '1.64005456402998', '1.63103006074007', '1.62646109446179', '1.62483351776729', '1.61794627041935', '1.60638099649103', '1.59160518167625', '1.57856502215575', '1.56723770329055', '1.55884357172436', '1.55081356970191', '1.5440909800073', '1.53473504989623', '1.52335047710565', '1.51140772671503', '1.49628095199023', '1.48082183121466', '1.4668009209167', '1.45300293604089', '1.43913779397284', '1.42471804569399', '1.41116472805909', '1.39601546893463', '1.3795217760198', '1.36066889187826', '1.3395095955925', '1.31771535033317', '1.29387042583309', '1.26955248066416', '1.24679628762607', '1.22528340309588', '1.20486570624273', '1.18549206002717', '1.16756178865017', '1.15111957559202', '1.13469169498467', '1.11621030173639', '1.09569135455521', '1.07275908862679', '1.04573742076401', '1.01572627731635', '0.98381634710957', '0.950352559222019', '0.915760692099546', '0.881456713194727', '0.848044938315892', '0.816038892625263', '0.785024915273114', '0.754850603543375', '0.725690734641156', '0.697449171016547', '0.669846688269734', '0.643097402076866', '0.615807664216611', '0.589686777991522', '0.563134754809732', '0.537416951715189', '0.512092492411016', '0.487999533569422', '0.464888888064952', '0.442938789447448', '0.422687485052752', '0.403811887358409', '0.386602162003576', '0.370223420179536', '0.355850417036878', '0.342554004485098', '0.330263308885894', '0.318892349787717', '0.308390808825048', '0.29923285616278', '0.290049870831026', '0.280987628676386', '0.272166680353347', '0.263184326446838', '0.254328565772045', '0.245533707259442', '0.236284846332185', '0.227364007848682', '0.218575558150069', '0.209919539318749', '0.201723665364338', '0.193439417628863', '0.185095630044576', '0.176908759167827', '0.168492281717065', '0.15971620196905', '0.151519711134016', '0.143896290701505', '0.137256829327417', '0.13133376173
rtv = {"beginWL":350, "endWL":950,"interval":1, "n_t_square":0.543}
def profiler_demo():
device_id = 2
ph = ProfilerHandle( device_id, ProfilerCfg.cfg, ProfilerCfg.calcfg, ProfilerCfg.rtv)
fpath = Path.cwd()
infopath = fpath.joinpath('data','2','37','info.bin')
sensorpath = fpath.joinpath('data','2','37','sensor.bin')
savedir = fpath.joinpath('data','2','37' )
ph.set_ramses_number(3) # 设置传感器数量
ph.set_tilt_range(21.0) # 设置倾斜范围
ph.read_info_path(infopath)
ph.profiler.reset_profiler()
ph.profiler.data.set_wavelength( ) # 设置波长
ph.profiler.get_depth_offset()
ph.read_sensor_path(sensorpath)
ph.profiler.get_Ed0_kd()
ph.profiler.get_Lu0_Ku()
ph.profiler.get_Lw_Rs(ph.retrieve["n_t_square"])
ph.profiler.save(savedir)
# def read_immersion_factors( )->np.ndarray:
# fname = "immersion_factors_Lu.dat"
# fpath = CAL_DIR.joinpath( "profiler" ,fname)
# assert fpath.exists(), f">>>> not find {fpath} "
# ret = np.loadtxt(fpath,skiprows=2)
# return ret
# pass
if __name__ == '__main__':
# ret = read_immersion_factors()
# print(ret)
# print(ret[:,0])
# print(ret[:,1])
# device_id = 2
# ph = ProfilerHandle( device_id, ProfilerCfg.cfg, ProfilerCfg.calcfg, ProfilerCfg.rtv)
# fpath = Path.cwd()
# # t= ("data", "2","2002","8", "17","51", "info.bin")
# # t= ("data" )
# infopath = fpath.joinpath('data','2','37','info.bin')
# sensorpath = fpath.joinpath('data','2','37','sensor.bin')
# savedir = fpath.joinpath('data','2','37' )
# ph.set_ramses_number(3)
# ph.set_tilt_range(21.0)
# ph.read_info_path(infopath)
# ph.profiler.reset_profiler()
# ph.profiler.data.set_wavelength( ) # 设置波长
# ph.profiler.get_depth_offset()
# ph.read_sensor_path(sensorpath)
# # log.info( f" Ed: {ph.profiler.Ed} ")
# # log.info( f" Lu: {ph.profiler.Lu} ")
# ph.profiler.get_Ed0_kd()
# ph.profiler.get_Lu0_Ku()
# # log.info( f" Ed0: {ph.profiler.Ed0} ")
# # log.info( f" Lu0: {ph.profiler.Lu0} ")
# ph.profiler.get_Lw_Rs(ph.retrieve["n_t_square"])
# # log.info( f" Lw: {ph.profiler.Lw} ")
# # log.info( f" Rs: {ph.profiler.Rs} ")
# ph.profiler.save(savedir)
pass