optimize_data_process

desktop
esea_info 3 years ago
parent 8d58729f21
commit 3e60a77696
  1. 6
      app.py
  2. 198
      awrams.py
  3. 1
      config.yml
  4. 1
      configuration.py
  5. 237
      dataplot.py
  6. 107
      mypanel.py
  7. 126
      mythread.py
  8. 2
      retrieve.yml
  9. 100
      uiconfig/ui_plot_setting.py
  10. 182
      yiwinframe.py

@ -16,7 +16,7 @@ from myconfig import VERSION,LASTDATE,COMPANY
class YiwinApp(wx.App):
def OnInit(self):
self.myframe = YiwinFrame( u'Handheld Offline Software', parent=None)
self.myframe = YiwinFrame( u'AWRAMS Offline Software', parent=None)
self.myframe.statusBar.SetStatusText( u" 版权所有 " + COMPANY
+" Version "+ VERSION
+ " "+ LASTDATE, 1 ) #给状态栏设文字
@ -24,7 +24,7 @@ class YiwinApp(wx.App):
return True
if __name__ == "__main__":
log.info(f"******** Shanghai Yiwin Instrument@Equipment Company *********", __name__, "", "")
log.info(f"******** Handheld Software for Dealing RAMSES Raw data *********", __name__, "", "")
log.info(f"******** Shanghai Yiwin Instrument&Equipment Company *********", __name__, "", "")
log.info(f"******** AWRAMS Software for Dealing RAMSES Raw data *********", __name__, "", "")
app = YiwinApp( )
app.MainLoop()

@ -14,6 +14,7 @@ import time
import locale
import struct
import numpy as np
from pubsub import pub
from pathlib import PurePath,Path
from myconfig import CURRENT_DIR,DATA_DIR,OUTPUT_DIR,NEWLINE,ROWFACTOR,SAVE_EXT_NAME,TOKEN
from myconfig import DeviceType,RamsesSURFACE,RamsesAWRAMS,RamsesPROFILE
@ -349,6 +350,10 @@ class AWRAMS(object):
def __init__(self, ):
"""
@description : 手持数据初始化
处理入口 dealAllMeasurements()
每个文件调用 dealOneMeasurement()
读取buf :decode_sensor_buf() 数值截取 转光强
dealOneGroup()平均 插值 追加保存
"""
self.device_type = DeviceType.AWRAMS.name
self.device_enum = None
@ -384,6 +389,7 @@ class AWRAMS(object):
self.ramses = Ramses()
self.info_dict = {}
self.res = {} # 最终结果{lsky: esky: lwater: Lw: Rs:}
self.msg ={}
# 方法
self.setDeviceEnum()
@ -407,6 +413,12 @@ class AWRAMS(object):
if self.device_type == DeviceType.PROFILE.name:
self.device_enum = RamsesPROFILE
def __set_msg(self, flag, d):
self.msg = {}
self.msg.update( {"flag":flag} )
self.msg.update( {"data":d} )
pass
def getDataFileList(self, ):
self.hhp.getDataFileList()
self.filelist = self.hhp.getFilelist()
@ -434,7 +446,7 @@ class AWRAMS(object):
pass
try: # awrams每次只有一组数据
self.dealOneMeasurement(self.sensor_path_fname )
self.dealOneMeasurement( self.sensor_path_fname )
# self.measurement_interval = int(self.info_dict['Measure_Interval'])
# self.measurement_repeat = int(self.info_dict['Measure_Repeat'])
# self.dealOneHandheldMeasurement(self.sensor_path_fname )
@ -442,14 +454,16 @@ class AWRAMS(object):
log.error( "处理传感器文件" + self.sensor_path_fname.name + " 出现错误",__name__,"dealAllMeasurements")
raise MyException( "处理传感器文件" + self.sensor_path_fname.name + " 出现错误" )
pass
self.__set_msg('notice', '处理文件完成')
pub.sendMessage('update' , msg=self.msg)
log.info(f"Finished !! ", __name__, "dealAllMeasurements")
return True,self.error_result
# return True,self.error_result
pass
def dealOneHandheldMeasurement(self, fpath:Path):
def dealOneMeasurement(self, fpath:Path):
'''handheld一次测量包含多组数据'''
# 调用handheldbuf 处理,将一组数据提交出来
log.info(f" 手持个文件,多组测量数据", __name__, "dealOneHandheldMeasurement")
log.info(f"dealOneMeasurement: 一组测量数据", __name__, "dealOneMeasurement")
if len(self.filelist)<1:
pass
@ -464,87 +478,35 @@ class AWRAMS(object):
+ str(self.info_dict['minute']) + '_' \
+ str(self.info_dict['second'])
self.output_path = self.output_path.joinpath( self.ymdhms )
log.debug(f"current_measure_time: {self.current_measure_time}", __name__, "dealOneHandheldMeasurement")
log.debug(f"current_measure_time: {self.current_measure_time}", __name__, "dealOneMeasurement")
# 读取buf
self.hhb.readFile2Buf(fpath)
log.debug(f"buf: {self.hhb.get_buf_size()}", __name__, "dealOneHandheldMeasurement")
# 将buf 处理成光强值 self.intensity_before_avg
self.decode_sensor_buf()
# 解析Buf, 对buf分组,获得[{lsky: esky : lwater} .... ]
len_total = len(self.intensity_before_avg)
if len_total%self.measurement_repeat != 0:
self.res = {}
return # 返回退出
group_num = int(len_total/self.measurement_repeat)
log.info(f"group_num...: {group_num}", __name__, "dealOneHandheldMeasurement")
self.real_wavelength = self.getWavelenthDict()
if group_num == 1:
self.dealOneGroup() # self.intensity_before_avg
return
self.dealMultiGroup(group_num)
def dealMultiGroup(self, group_num:int ):
log.info(f"group_num: {group_num}", __name__, "dealMultiGroup")
# 分组进行处理
for i in range(group_num):
self.current_group_num = i
# 重设当前测量时间
self.current_measure_time = ""
self.res = {}
tmp_before_avg = []
for j in range( self.measurement_repeat ):
tmp_before_avg.append( self.intensity_before_avg[j+i*self.measurement_repeat] )
pass
self.getAvg(tmp_before_avg)
self.__do_sensor_dict_interpo()
self.appendSave( )
def dealOneGroup(self, ):
# 分组,并获得平均值, 255个未插值结果 (依据 measurement_interval measurement_repeat)
self.getAvg( self.intensity_before_avg )
# 插值
self.real_wavelength = self.getWavelenthDict()
self.__do_sensor_dict_interpo()
self.ymdhms = "20"+ str(self.info_dict['year']) + '_' \
+ str(self.info_dict['month']) + '_' \
+ str(self.info_dict['day']) + '_' \
+ str(self.info_dict['hour']) + '_' \
+ str(self.info_dict['minute']) + '_' \
+ str(self.info_dict['second'])
self.output_path = self.output_path.joinpath( self.ymdhms )
self.appendSave()
def dealOneMeasurement(self, fpath:Path):
'''handheld一次测量包含多组数据'''
# 调用handheldbuf 处理,将一组数据提交出来
log.info(f"dealOneMeasurement: 一组测量数据", __name__, "dealOneMeasurement")
if len(self.filelist)<1:
pass
# 当前文件名
self.output_path = OUTPUT_DIR
self.current_filepath = fpath
self.current_measure_time = self.hhp.getCurrentMeasureTimeFromPath(fpath)
# 获得真实波长 self.real_wavelength
self.getRealWavelenthDict()
# 多组数据平均 self.intensity_after_avg
self.getAvg( self.intensity_before_avg )
# 波长插值 self.res esky lsky lw
self.__do_sensor_dict_interpo()
# 获得输出目录路径 self.ymdhms self.output_path
self.get_ymdhms()
# 追加保存
self.appendSave()
# 通知ui
self.__set_msg("data", {"tm":self.ymdhms, "res":self.res} )
pub.sendMessage("update" , msg=self.msg)
def get_ymdhms(self, ):
self.ymdhms = "20"+ str(self.info_dict['year']) + '_' \
+ str(self.info_dict['month']) + '_' \
+ str(self.info_dict['day']) + '_' \
+ str(self.info_dict['hour']) + '_' \
+ str(self.info_dict['minute']) + '_' \
+ str(self.info_dict['second'])
self.output_path = self.output_path.joinpath( self.ymdhms )
log.debug(f"current_measure_time: {self.current_measure_time}", __name__, "dealOneHandheldMeasurement")
self.hhb.readFile2Buf(fpath)
self.decode_sensor_buf()
self.real_wavelength = self.getWavelenthDict()
self.dealOneGroup()
# self.output_path = self.output_path.joinpath( self.ymdhms )
# print(self.output_path)
# time.sleep(30)
def decode_sensor_buf(self,) :
# 处理Buf,对多组数据取平均
@ -597,6 +559,61 @@ class AWRAMS(object):
log.debug(f"getAvg: {self.intensity_after_avg}", __name__, "getAvg")
pass
# def dealOneHandheldMeasurement(self, fpath:Path):
# '''handheld一次测量包含多组数据'''
# # 调用handheldbuf 处理,将一组数据提交出来
# log.info(f" 手持一个文件,多组测量数据", __name__, "dealOneHandheldMeasurement")
# if len(self.filelist)<1:
# pass
# # 当前文件名
# self.output_path = OUTPUT_DIR
# self.current_filepath = fpath
# self.current_measure_time = self.hhp.getCurrentMeasureTimeFromPath(fpath)
# self.ymdhms = "20"+ str(self.info_dict['year']) + '_' \
# + str(self.info_dict['month']) + '_' \
# + str(self.info_dict['day']) + '_' \
# + str(self.info_dict['hour']) + '_' \
# + str(self.info_dict['minute']) + '_' \
# + str(self.info_dict['second'])
# self.output_path = self.output_path.joinpath( self.ymdhms )
# log.debug(f"current_measure_time: {self.current_measure_time}", __name__, "dealOneHandheldMeasurement")
# self.hhb.readFile2Buf(fpath)
# log.debug(f"buf: {self.hhb.get_buf_size()}", __name__, "dealOneHandheldMeasurement")
# self.decode_sensor_buf()
# # 解析Buf, 对buf分组,获得[{lsky: esky : lwater} .... ]
# len_total = len(self.intensity_before_avg)
# if len_total%self.measurement_repeat != 0:
# self.res = {}
# return # 返回退出
# group_num = int(len_total/self.measurement_repeat)
# log.info(f"group_num...: {group_num}", __name__, "dealOneHandheldMeasurement")
# self.real_wavelength = self.getWavelenthDict()
# if group_num == 1:
# self.dealOneGroup() # self.intensity_before_avg
# return
# self.dealMultiGroup(group_num)
# def dealMultiGroup(self, group_num:int ):
# log.info(f"group_num: {group_num}", __name__, "dealMultiGroup")
# # 分组进行处理
# for i in range(group_num):
# self.current_group_num = i
# # 重设当前测量时间
# self.current_measure_time = ""
# self.res = {}
# tmp_before_avg = []
# for j in range( self.measurement_repeat ):
# tmp_before_avg.append( self.intensity_before_avg[j+i*self.measurement_repeat] )
# pass
# self.getAvg(tmp_before_avg)
# self.__do_sensor_dict_interpo()
# self.appendSave( )
def getRetDict(self,) :
ret_dict = { }
ret_dict.update( {self.device_enum(1).name:np.array([])} )
@ -613,7 +630,7 @@ class AWRAMS(object):
self.res.update( { k : tmp } )
def getCfgByDid(self, func:str) :
cfg_id:dict = self.cfg.get(int(self.device_id))
cfg_id:dict = self.syscfg.get(int(self.device_id))
cfg_sensor = cfg_id.get( func)
return cfg_sensor
pass
@ -835,6 +852,14 @@ class AWRAMS(object):
ret_dict.update({ k : tmp })
return ret_dict
def getRealWavelenthDict( self, ) -> dict:
ret_dict = self.getRetDict()
cfg_id:dict = self.syscfg.get( int(self.device_id))
for k in ret_dict.keys():
tmp = self.getWavelength( cfg_id.get(k) )
ret_dict.update({ k : tmp })
self.real_wavelength = ret_dict
def getWavelength(self,ramsesdict:dict) -> np.ndarray:
ret = []
for i in range(1,256):
@ -904,3 +929,20 @@ if __name__ == "__main__":
pass
# def dealOneGroup(self, ):
# # 分组,并获得平均值, 255个未插值结果 (依据 measurement_interval measurement_repeat)
# self.getAvg( self.intensity_before_avg )
# # 插值
# self.real_wavelength = self.getWavelenthDict()
# self.__do_sensor_dict_interpo()
# self.ymdhms = "20"+ str(self.info_dict['year']) + '_' \
# + str(self.info_dict['month']) + '_' \
# + str(self.info_dict['day']) + '_' \
# + str(self.info_dict['hour']) + '_' \
# + str(self.info_dict['minute']) + '_' \
# + str(self.info_dict['second'])
# self.output_path = self.output_path.joinpath( self.ymdhms )
# self.appendSave()

@ -18,3 +18,4 @@
3:
FUNC: Lwater
SN: 852F

@ -32,6 +32,7 @@ class Configuration:
self.cal_configuration =None
for k,v in self.configuration.items():
print(f" ==== {v } ")
if v["SN"] == "" or v['FUNC']=="":
pass

@ -0,0 +1,237 @@
# import numpy as np
from pathlib import Path
class DataPlot():
'''
从文件读取数据出来成待显示数据
'''
# def __init__(self, mypanel, ):
def __init__(self, ):
# self.mypanel = mypanel
# self.__eventManager = eventManger
# self.dataSaveFile = DATA_FNAME_WITHOUT_WATER
# self.axes_title = "Water Attenuation Coefficient"
# self.axes_xlabel = "Wavelength (nm)"
# self.axes_ylabel = "Attenuation Coefficient m(-1)"
# self.axes_title = "Attenuation Coefficient Demo"
self.demo_time = ''
self.demo_wl = [] # 纯水
self.demo_data = [] # 纯水
self.wavelength = None
self.data_one = None
self.data_multi = None
# self.mode = "one" # multi
# self.begin_line = None
# self.line_interval = None
self.fpath :Path = Path()
self.total_lines = 0
self.token = ";"
# self.MPL = myPanel.MPL_Panel(self) # 调用自己建立的 panel 类
# self.Figure = self.MPL.Figure
# self.axes = self.MPL.axes
# self.FigureCanvas = self.MPL.FigureCanvas
def set_file_path( self, fpath:Path ):
self.fpath = fpath
pass
def set_wavelength(self):
pass
# def set_mode(self, mode ="one"):
# self.mode = mode
# pass
def set_token(self, token =";"):
self.token = token
pass
def set_begin_line( self, lineno = 0 ):
self.begin_line = lineno
pass
def set_line_interval( self, line_interval = 0 ):
self.line_interval = line_interval
pass
def get_total_lines( self, ):
''' 大文件 '''
count = 0
thefile = open( self.fpath, 'rb')
while True:
buffer = thefile.read(8192*1024)
if not buffer:
break
count += buffer.count(b'\n')
self.total_lines = count + 1
def get_wavelength_from_file( self, ):
tmp = self.get_first_line()
self.wavelength = tmp.split(self.token)[1:]
pass
def get_reverse_x_lineno( self, x ):
line = self.__get_reverse_x_lineno(x)
line = line.split(self.token)
return line[0], line[1:]
pass
def get_multi_by_x_m_n( self, x,m,n ):
# res_time = []
# res_lines = []
lines = self.__get_reverse_x_m_n_line(x,m,n)
# print(f'+++++ {lines}')
# for i in range(len(lines)):
# ln =
# res_time.append( lines[i] [0] )
# res_lines.append( lines[i][1:] )
# return res_time, res_lines
return lines
pass
def __get_reverse_x_lineno(self, x):
"""
获得倒数第x行
"""
try:
# filesize = os.path.getsize(self.fpath)
filesize = self.fpath.stat().st_size
if filesize == 0:
return None
else:
with open(self.fpath, 'rb') as fp: # to use seek from end, must use mode 'rb'
offset = -8 # initialize offset
while -offset < filesize: # offset cannot exceed file size
fp.seek(offset, 2) # read # offset chars from eof(represent by number '2')
lines = fp.readlines() # read from fp to eof
if len(lines) >= x+1: # if contains at least 2 lines
return lines[-1*x] # then last line is totally included
else:
offset *= 2 # enlarge offset
fp.seek(0)
lines = fp.readlines()
if len(lines) < x:
raise Exception("行数有误,请重试")
return lines[-1*x]
except FileNotFoundError:
print(self.fpath.name + ' not found!')
return None
def __get_reverse_x_m_n_line(self, x, m=1, n=1):
"""
获得倒数第x行, 间隔m行, 共取n个行
"""
print(f'__get_reverse_x_m_n_line {x} {self.fpath}')
min_lines = x + m*n
res_lines = []
try:
# filesize = os.path.getsize(self.fpath)
filesize = self.fpath.stat().st_size
if filesize == 0:
return None
else:
with open(self.fpath, 'rb') as fp: # to use seek from end, must use mode 'rb'x
offset = -8 # initialize offset
while -offset < filesize: # offset cannot exceed file size
fp.seek( offset, 2 ) # read # offset chars from eof(represent by number '2')
lines = fp.readlines() # read from fp to eof
if len(lines) >= min_lines+1 :
for i in range(n):
res_lines.append( lines[-1*(x+m*i)].decode())
return res_lines
else:
offset *= 2 # enlarge offset
fp.seek( 0 )
lines = fp.readlines( )
if len(lines) < min_lines:
raise Exception("行数有误,请重试")
for i in range(n):
res_lines.append( lines[-1*(x+m*i)].decode())
return res_lines
print(res_lines)
except FileNotFoundError:
print(self.fpath.name + ' not found!')
return None
def get_first_line(self, ):
firstline = ''
with open(self.fpath, 'rb') as fp: # to use seek from end, must use mode 'rb'x
firstline = fp.readline()
return firstline.decode()
def get_last_line(self,filename:Path):
"""
获得最后一行
:param filename: file name
:return: last line or None for empty file
"""
try:
filesize = filename.stat().st_size
if filesize == 0:
return None
else:
with open(filename, 'rb') as fp: # to use seek from end, must use mode 'rb'
offset = -8 # initialize offset
while -offset < filesize: # offset cannot exceed file size
fp.seek(offset, 2) # read # offset chars from eof(represent by number '2')
lines = fp.readlines() # read from fp to eof
if len(lines) >= 2: # if contains at least 2 lines
return lines[-1] # then last line is totally included
else:
offset *= 2 # enlarge offset
fp.seek(0)
lines = fp.readlines()
return lines[-1]
except FileNotFoundError:
print(filename + ' not found!')
return None
def tail(file, taillines=500, return_str=True, avg_line_length=None):
"""
大文件的尾行小文件会导致报错
taillines : 读取尾部多少行
avg_line_length:每行字符平均数,
return_str:返回类型默认为字符串False为列表
offset:每次循环相对文件末尾指针偏移数
f.tell() 当前指针位置
f.seek(a,b) a 偏移量 b:0 1 2 文件头 当前位置 文件尾部
"""
with open(file, errors='ignore') as f:
if not avg_line_length:
f.seek(0, 2)
f.seek(f.tell() - 3000)
avg_line_length = int(3000 / len(f.readlines())) + 10
f.seek(0, 2)
end_pointer = f.tell()
offset = taillines * avg_line_length
if offset > end_pointer:
f.seek(0, 0)
lines = f.readlines()[-taillines:]
return "".join(lines) if return_str else lines
offset_init = offset
i = 1
while len(f.readlines()) < taillines:
location = f.tell() - offset
f.seek(location)
i += 1
offset = i * offset_init
if f.tell() - offset < 0:
f.seek(0, 0)
break
else:
f.seek(end_pointer - offset)
lines = f.readlines()
if len(lines) >= taillines:
lines = lines[-taillines:]
return "".join(lines) if return_str else lines
if __name__ == "__main__":
d = DataPlot()

@ -1,4 +1,111 @@
import wx
import numpy as np
from enum import Enum
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas #FigureCanvasWxAgg
# from matplotlib.backends.backend_wx import NavigationToolbar2Wx as NavigationToolbar # FIgure 导航
from matplotlib.figure import Figure
class LineColor(Enum):
RED = 0
ORANGE = 1
YELLOW = 2
GREEN = 3
CYAN = 4
BLUE = 5
PURPLE = 6
class Plot(wx.Panel):
'''
# 需要在 Frame 实例化一个实例
# 改变需要对实例化后的进行操作
'''
'''
Matplotlib Panel 单独拿出来画图
可以 __do_layout
可以 __add_widgets
可以 button事件
可以鼠标事件
'''
def __init__(self,parent):
'''
* panel 初始化后的样子
'''
super(Plot,self).__init__(parent)
# 本地化语言
self.locale = wx.Locale(wx.LANGUAGE_CHINESE_SIMPLIFIED)
self.Figure = Figure(figsize=(4,3)) # 4,3 为英寸
self.axes = self.Figure.add_axes([0.1,0.1,0.8,0.8],facecolor="lightgray") # 坐标系起始位置
self.FigureCanvas = FigureCanvas(self,-1,self.Figure)
#继承鼠标移动显示鼠标处坐标的事件
# self.FigureCanvas.mpl_connect('motion_notify_event',self.MPLOnMouseMove)
# self.NavigationToolbar = NavigationToolbar(self.FigureCanvas)
# self.StaticText = wx.StaticText(self,-1,label=u'坐标信息')
# self.SubBoxSizer = wx.BoxSizer(wx.HORIZONTAL)
# self.SubBoxSizer.Add(self.NavigationToolbar,proportion =0, border = 2,flag = wx.ALL | wx.EXPAND)
# self.SubBoxSizer.Add(self.StaticText,proportion =-1, border = 2,flag = wx.ALL | wx.EXPAND)
self.TopBoxSizer = wx.BoxSizer(wx.VERTICAL)
# self.TopBoxSizer.Add(self.SubBoxSizer,proportion =-1, border = 2,flag = wx.ALL | wx.EXPAND)
self.TopBoxSizer.Add(self.FigureCanvas,proportion =-10, border = 2,flag = wx.ALL | wx.EXPAND)
self.SetSizer(self.TopBoxSizer)
self.purewater_legend = (" Rs"
,"Wavelength (nm)"
," Rs " )
self.measure_legend = (" Rs"
,"Wavelength (nm)"
," Rs" )
def set_axes_title(self,title):
self.axes.set_title(title)
def set_axes_xlabel(self,x):
self.axes.set_xlabel(x)
def set_axes_ylable(self,y):
self.axes.set_ylabel(y)
def set_title_x_y(self,title, x, y):
self.axes.set_title(title)
self.axes.set_xlabel(x)
self.axes.set_ylabel(y)
def plot_one( self, time_, wavelength:np.ndarray, data:np.ndarray, color="green" ):
self.axes.plot(wavelength, data, color=color, linewidth=0.5 , label=time_ )
self.axes.legend( )
self.axes.grid( True )
self.FigureCanvas.draw()
def plot_multi( self, tm, wavelength:np.ndarray, data:np.ndarray ):
len_ = len(data)
for i in range(len_):
self.axes.plot(wavelength, data[i], color=LineColor(i).name.lower(), linewidth=0.5 , label=tm[i] )
self.axes.legend( )
self.axes.grid(True)
self.FigureCanvas.draw()
def clear_past( self, ):
self.axes.clear()
# def MPLOnMouseMove(self,event):
# '''
# * 显示坐标值
# '''
# ex=event.xdata#这个数据类型是numpy.float64
# ey=event.ydata#这个数据类型是numpy.float64
# if ex and ey :
# #可以将numpy.float64类型转化为float类型,否则格式字符串可能会出错
# self.StaticText.SetLabel('%10.5f,%10.5f' % (float(ex),float(ey)))
class MyPanel(wx.Panel):
"""docstring for MyPanel."""

@ -0,0 +1,126 @@
import threading
import time
class Mythead(threading.Thread):
'''线程守护'''
def __init__(self ):
super(Mythead, self).__init__()
pass
def set_task(self, func, *args):
self.func = func
self.args = args
def run(self):
# print(f" --- {len(self.args)}")
if len(self.args) > 0:
self.func(self.args)
else:
self.func( )
class Multithread(threading.Thread):
'''
多线程
子线程.join() -> ( 设置在start之后, 等所有阻塞线程运行完, 再运行主线程 )
子线程.setDaemon(True) -> 设置子线程A为守护线程, 主线程所在的进程内所有非守护线程统统运行完毕,
无论子线程A有没有结束, 程序都结束
Method:
'''
def __init__(self):
super(Multithread, self).__init__()
self.__tasks = []
self.act = []
# self.__block = False
pass
# def set_task( self, tasks ):
# self.__tasks = tasks
def add_task(self, func, daemon=False, join=True,args=()):
tmp_dict = {}
tmp_dict.update( {"func" : func})
if daemon == True:
tmp_dict.update( {"daemon" : True})
else:
tmp_dict.update( {"daemon" : False})
if join == True:
tmp_dict.update( {"join" : True})
else:
tmp_dict.update( {"join" : False})
if args == ():
tmp_dict.update( {"args" : ()})
else:
tmp_dict.update( {"args" : args})
self.__tasks.append( tmp_dict )
def remove_tasks(self, ):
self.__tasks = []
self.act = []
def add_task_2_act(self, task):
t = threading.Thread( target = task['func'], args = task['args'] )
self.act.append(t)
t.start()
def execute_one_act(self,i):
if self.__tasks[i]['join']:
self.act[i].join() # 子线程阻塞完毕再运行主线程
pass
def prepare_tasks(self):
self.act = []
for task in self.__tasks:
self.add_task_2_act(task)
def execute_tasks(self):
try:
for i in range( len(self.act) ):
self.execute_one_act( i )
pass
except Exception as e:
print(e)
def prepare_tasks(self):
self.act = []
for task in self.__tasks:
t = threading.Thread( target = task['func'], args = task['args'] )
self.act.append(t)
t.start()
def simultaneously_execute_tasks(self):
self.prepare_tasks()
self.execute_tasks()
def sequently_execute_tasks(self):
for task in self.__tasks:
t = threading.Thread( target = task['func'], args = task['args'] )
t.start()
t.join()
def t1(self):
print("thread1...")
time.sleep(10)
print("thread1... after sleep...")
def t2(self):
print("thread2...")
time.sleep(5)
print("thread2... after sleep...")
def t3(self):
print("thread3...")
time.sleep(3)
print("thread3... after sleep...")
if __name__ == '__main__':
mt = Multithread()
mt.add_task(mt.t1)
mt.add_task(mt.t2)
mt.add_task(mt.t3)
# mt.prepare_tasks() # 线程同步运行
# mt.execute_tasks()
# mt.simultaneously_execute_tasks()
mt.sequently_execute_tasks()

@ -1,3 +1,5 @@
LineBegin: 1
LineInterval: 1
beginWL: 350
endWL: 950
interval: 1

@ -0,0 +1,100 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import wx
# from configobj import ConfigObj
from myconfig import MyConfig
from myconfig import YAML_FILE_NAME
class UI_Plot_Setting(wx.Dialog):
"""
@description : 绘图 配置
"""
def __init__(self, parent, id):
# 串口页面配置
super(UI_Plot_Setting, self).__init__( parent ,id = id )
self.config = MyConfig()
self.InitUI()
self.SetSize((400, 400))
self.SetTitle(" 绘图 序列号 ")
def InitUI(self):
self.config_yml = self.config.read_rtv_yaml()
self.panel = wx.Panel(self)
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.sb = wx.StaticBox(self.panel, label='指定绘图设置 ')
self.sbs = wx.StaticBoxSizer(self.sb, orient=wx.VERTICAL)
self.hbox1 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText1 = wx.StaticText(self.panel, label='起始行号 ',size=(60, -1), style=wx.ALIGN_CENTRE_VERTICAL )
self.textCtrl1 = wx.TextCtrl(self.panel, value="",size=(250,25) )
tmp = self.get_str_from_config( "LineBegin" )
if tmp is not None:
self.textCtrl1.SetValue(tmp)
self.hbox1.Add(self.staticText1, flag=wx.TOP|wx.LEFT, border=5)
self.hbox1.Add(self.textCtrl1, flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add(self.hbox1, flag=wx.TOP|wx.LEFT, border= 5)
self.hbox2 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText2 = wx.StaticText(self.panel, label='间隔行号: ' ,size=(60, -1))
# self.staticText2_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1))
self.textCtrl2 = wx.TextCtrl(self.panel, value="",size=(250,25))
tmp = self.get_str_from_config( "LineInterval" )
if tmp is not None:
self.textCtrl2.SetValue(tmp)
self.hbox2.Add(self.staticText2, flag=wx.TOP|wx.LEFT, border=5)
self.hbox2.Add(self.textCtrl2,flag=wx.TOP|wx.LEFT, border=5)
# self.hbox2.Add(self.staticText2_1, flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add(self.hbox2, flag=wx.TOP|wx.LEFT, border=5)
self.panel.SetSizer(self.sbs)
self.hbox_0 = wx.BoxSizer(wx.HORIZONTAL)
self.okButton = wx.Button(self, label=u'保存配置')
self.closeButton = wx.Button(self, label='Close')
self.hbox_0.Add(self.okButton)
self.hbox_0.Add(self.closeButton, flag = wx.LEFT, border=5)
# 添加 vbox 到panel
self.vbox.Add(self.panel, proportion=1,
flag=wx.ALL | wx.EXPAND, border=5)
self.vbox.Add(self.hbox_0, flag=wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, border=10)
self.SetSizer(self.vbox)
self.okButton.Bind(wx.EVT_BUTTON, self.OnSave)
self.closeButton.Bind(wx.EVT_BUTTON, self.OnClose)
def get_str_from_config( self, key ):
return str(self.config_yml[key])
pass
def set_config_by_key_val( self, key, val ):
# print(f" {key} current type {type( self.config_yml[section][key] )}")
if type( self.config_yml [key] ) == int:
self.config_yml [key] = int(val)
elif type( self.config_yml [key] ) == float:
self.config_yml [key] = float(val)
else:
self.config_yml[key] = val
pass
def saveData(self, e):
pass
def OnClose(self, e):
self.Destroy()
def OnSave(self, e):
success = True
# 赋值字典,写入文件
self.set_config_by_key_val( "LineBegin",self.textCtrl1.GetValue( ))
self.set_config_by_key_val( "LineInterval",self.textCtrl2.GetValue( ))
self.config.write_rtv_yaml(self.config_yml)
del self.config
if success:
self.EndModal(wx.ID_OK)

@ -2,20 +2,23 @@ import wx
import os
import time
import threading
from pathlib import *
from pathlib import PurePath,Path
from pubsub import pub
# from configobj import ConfigObj
from listctrl import Listctrl
from mypanel import MyPanel
from mypanel import MyPanel,Plot,LineColor
from uiconfig.uisensor import UISensor
# from uiconfig.uilogging import UILogging
from uiconfig.uiabout import About
from uiconfig.uihelp import Help
from uiconfig.ui_plot_setting import UI_Plot_Setting
from myconfig import TOKEN,DeviceType,YAML_FILE_NAME,RETRIEVE_CFG_FILE
from myconfig import MyConfig
from myconfig import TOKEN,DeviceType,YAML_FILE_NAME,RETRIEVE_CFG_FILE
from myconfig import MyConfig,RamsesFunc
from mythread import Mythead
from configuration import Configuration
from awrams import AWRAMS,HandHeldBuf
@ -29,10 +32,14 @@ ID_SENSOR_SETTING = 11
ID_LOGGING_SETTING = 12
ID_CAL_INFO = 13
ID_PLOT_LAST = 15
ID_PLOT_LAST_7 = 16
ID_PLOT_7 = 17
ID_PLOT_SETTING = 18
ID_HELP = 21
ID_ABOUT = 22
class YiwinFrame(wx.Frame):
'''将buf类传进来'''
def __init__(self, title, parent, size=(900, 750)):
@ -66,7 +73,12 @@ class YiwinFrame(wx.Frame):
self.BoxSizer.Add( self.mypanel, proportion =-10, border = 0, flag = wx.ALL | wx.EXPAND)
self.static_text = self.mypanel.staticText1
# 隐藏 等待show
self.mypanel.Show()
self.mypanel.Hide()
self.plotpanel = Plot( self ) # 调用自己建立的 Listctrl panel 类
self.BoxSizer.Add( self.plotpanel, proportion =-10, border = 0, flag = wx.ALL | wx.EXPAND)
self.plotpanel.set_title_x_y(*self.plotpanel.purewater_legend)
self.plotpanel.Show()
self.statusBar = self.CreateStatusBar() # 创建状态栏
self.statusBar.SetFieldsCount(2) # 状态栏分成3个区域
@ -80,10 +92,10 @@ class YiwinFrame(wx.Frame):
self.__setTimer()
log.info(f"system init....",__name__, "__init__")
self.mycfg = MyConfig()
self.hh = AWRAMS()
self.awrams = AWRAMS()
self.mythread = Mythead()
# self.hhb = HandHeldBuf()
pub.subscribe( self.updateDisplay, "update")
pass
def __set_menu(self):
@ -102,6 +114,16 @@ class YiwinFrame(wx.Frame):
# settingMenu.Append(ID_LOGGING_SETTING, u'&采集设置', ' ')
self.menubar.Append(settingMenu, u'&系统 ')
plotMenu = wx.Menu()
plotMenu.Append(ID_PLOT_LAST, u'&最后一条', '...')
plotMenu.AppendSeparator()
plotMenu.Append(ID_PLOT_LAST_7, u'&最后七条', ' ')
plotMenu.AppendSeparator()
plotMenu.Append(ID_PLOT_7, u'&指定七条', ' ')
plotMenu.AppendSeparator()
plotMenu.Append(ID_PLOT_SETTING, u'&指定设置', ' ')
self.menubar.Append(plotMenu, u'&绘图 ')
aboutMenu = wx.Menu()
aboutMenu.Append(ID_HELP, u'&帮助', 'help...')
aboutMenu.AppendSeparator()
@ -126,6 +148,11 @@ class YiwinFrame(wx.Frame):
self.Bind(wx.EVT_MENU, self.OnDealData, id=ID_MEASURE)
# self.Bind(wx.EVT_MENU, self.OnLoggingSetting, id=ID_LOGGING_SETTING)
self.Bind(wx.EVT_MENU, self.OnPlotLast, id=ID_PLOT_LAST )
self.Bind(wx.EVT_MENU, self.OnPlotLast7, id=ID_PLOT_LAST_7 )
self.Bind(wx.EVT_MENU, self.OnPlot7, id=ID_PLOT_7)
self.Bind(wx.EVT_MENU, self.OnPlotSetting, id=ID_PLOT_SETTING)
self.Bind(wx.EVT_MENU, self.OnHelpConfig, id=ID_HELP)
self.Bind(wx.EVT_MENU, self.OnAboutConfig, id=ID_ABOUT)
pass
@ -135,6 +162,35 @@ class YiwinFrame(wx.Frame):
self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer) #绑定一个定时器事件
pass
def updateDisplay(self, msg):
log.warning(f" updateDisplay 。。 {msg['data']}")
if msg['flag'] == "notice":
self.__update_notice(msg['data'])
pass
if msg['flag'] == "data":
# log.info(f" ... update .{msg['data']}........... " )
self.__update_data(msg['data'])
pass
pass
def __update_notice(self,msg):
log.info(f" .......{msg}... ",__name__,'__update_notice')
self.alterStatus_0( msg)
self.popDialog( msg )
pass
def __update_data(self,data ):
log.info(f" .......... ",__name__,'__update_data')
self.plotpanel.set_axes_title( data['tm'])
res = data['res']
x = self.awrams.wavelength.tolist()
length = len(data)
self.plotpanel.clear_past()
for display in RamsesFunc:
self.plotpanel.plot_one(display.name, x, res[display.name],color= LineColor(display.value).name )
pass
pass
def OnStart( self, event ):
log.info(f"OnStart....interval: {self.interval} min, port: {self.port}")
# self.m = SerialThread()
@ -171,20 +227,31 @@ class YiwinFrame(wx.Frame):
self.statusBar.SetStatusText("Pls get the cal info, and try again",0)
pass
self.hh.getDataFileList()
self.hh.setDeviceID(self.device_id)
self.hh.setRetrieve(self.retrieve)
self.awrams.getDataFileList()
self.awrams.setDeviceID(self.device_id)
self.awrams.setRetrieve(self.retrieve)
if self.syscfg != {}:
self.hh.setSyscfg(self.syscfg)
self.awrams.setSyscfg(self.syscfg)
else:
log.warning(f"Pls get the cal info, and try again", __name__, "OnDealData","setCfg")
MyException( f"System Configuration is empty." )
pass
# 处理数据
self.alterStatus_0(" 正在处理数据...." )
try:
self.mythread.set_task( self.awrams.dealAllMeasurements )
self.mythread.start()
except Exception as e:
log.error(e)
pass
# if self.awrams.dealAllMeasurements( ):
# self.onNotify("正在处理数据" )
# self.statusBar.SetStatusText(u" 数据处理完成......", 0)
# self.onNotify("处理数据已经结束" )
if self.hh.dealAllMeasurements( ):
self.onNotify("正在处理数据" )
self.statusBar.SetStatusText(u" 数据处理完成......", 0)
self.onNotify("处理数据已经结束" )
pass
def OnCalInfo(self,e):
@ -235,7 +302,28 @@ class YiwinFrame(wx.Frame):
def popDialog(self, msg, msg_type=u"错误提示"):
with wx.MessageDialog( self, msg, msg_type, wx.OK )as dlg:
dlg.ShowModal()
def OnPlotLast(self,e):
pass
def OnPlotLast7(self,e):
pass
def OnPlot7(self,e):
pass
def OnPlotSetting(self,e):
with UI_Plot_Setting(
self,
-1 ) as Dialog_Sensor_Setting:
Dialog_Sensor_Setting.CenterOnParent()
resultLog = Dialog_Sensor_Setting.ShowModal()
if resultLog == wx.ID_OK:
log.info( " Plot config dialog confirm, call back " )
self.__read_config()
pass
def OnSensorSetting(self,e):
with UISensor(
self,
@ -277,61 +365,3 @@ class YiwinFrame(wx.Frame):
self.Close()
# class SerialThread(threading.Thread):
# """进度条类 """
# def __init__(self, parent):
# """
# :param parent: 主线程UI
# """
# super(SerialThread, self).__init__() # 继承
# self.parent = parent
# # log.info(f"SerialThread ... {self.parent.kh}")
# self.start()
# self.join()
# # self.setDaemon(True) # 设置为守护线程, 即子线程是守护进程,主线程结束子线程也随之结束。
# def stop(self):
# self.parent.kh.disconnect()
# log.info(" Serial stop.... ")
# pass
# def run(self):
# log.info(" Serial run.... ")
# wx.CallAfter(self.parent.OnRcv)
# wx.CallAfter(self.parent.update_process_bar, count) # 调用parent的函数
# wx.CallAfter(self.parent.close_process_bar) # destroy进度条
# def OnSerialThreadStart(self):
# self.m = SerialThread(self)
# pass
# def OnSerialThreadStop(self):
# self.m.stop()
# pass
# def OnDisplaySave(self):
# '''
# 保存数据 self.result
# '''
# log.info(f"OnDisplaySave ....")
# # self.m = SerialThread(self)
# # self.kh.flush()
# self.OnSerialThreadStart()
# def OnRcv( self ):
# log.info(f"OnRcv....")
# self.kh.setPort(self.port)
# if not self.OnDetectPort:
# MyException(f"Can not find port : {self.port}")
# log.info(f"{self.port} ok!")
# # if not self.kh:
# # self.kh = KH3000(self.port)
# # self.result = self.kh.OneMeasure()
# log.info( f"OnRcv success {self.result}", __class__.__name__ )
# self.OnSave()
# self.OnDisplay()
# pass
Loading…
Cancel
Save