First commit after changed file framework
这个提交包含在:
+168
@@ -0,0 +1,168 @@
|
||||
import unicodedata
|
||||
import numpy as np
|
||||
from pyat.ProfileDataType import Profile
|
||||
from scipy.interpolate import interp1d
|
||||
from scipy.signal import butter, filtfilt
|
||||
from pyat.DataBase import DataBase
|
||||
|
||||
'''
|
||||
************************************************************
|
||||
该模块用读取实测的声速剖面
|
||||
************************************************************
|
||||
'''
|
||||
|
||||
def is_number(s):
|
||||
'''
|
||||
判断是否为数字
|
||||
'''
|
||||
try:
|
||||
float(s)
|
||||
return True
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
try:
|
||||
unicodedata.numeric(s)
|
||||
return True
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
|
||||
return False
|
||||
|
||||
def readRawProfile(fname):
|
||||
# 读取经纬度, 海深等信息
|
||||
f = open(fname)
|
||||
line = f.readline()
|
||||
line = line.split(',')
|
||||
if is_number(line[1]):
|
||||
lat = float(line[1])
|
||||
else:
|
||||
lat = None
|
||||
if is_number(line[3]):
|
||||
lon = float(line[3])
|
||||
else:
|
||||
lon = None
|
||||
if is_number(line[5]):
|
||||
botDep = float(line[5])
|
||||
else:
|
||||
botDep = None
|
||||
f.close()
|
||||
# 读取数据
|
||||
data = np.loadtxt(fname, skiprows=2,delimiter=',')
|
||||
# 剖面赋值
|
||||
velPf = Profile()
|
||||
velPf.set_data(data[:, 0], data[:, 1])
|
||||
velPf.set_coord(lat, lon)
|
||||
velPf.set_bottomDepth(botDep)
|
||||
return velPf
|
||||
|
||||
|
||||
def removeHead(velPf):
|
||||
'''
|
||||
去掉剖面头部异常数据, 刚入水的
|
||||
'''
|
||||
lat = velPf.lat
|
||||
lon = velPf.lon
|
||||
botDep = velPf.botDep
|
||||
dep = velPf.x
|
||||
vel = velPf.y
|
||||
# 梯度阈值
|
||||
gradc = 1.0
|
||||
# 去掉前面一段(刚入水)变化计较剧烈的区域
|
||||
for i in range(dep.size-1):
|
||||
grad = np.abs((vel[i+1]-vel[i])/(dep[i+1]-dep[i]))
|
||||
if grad < gradc:
|
||||
break
|
||||
dep = dep[i+1:]
|
||||
vel = vel[i+1:]
|
||||
# 剖面赋值
|
||||
velPf = Profile()
|
||||
velPf.set_data(dep, vel)
|
||||
velPf.set_coord(lat, lon)
|
||||
velPf.set_bottomDepth(botDep)
|
||||
return velPf
|
||||
|
||||
|
||||
def removeTail(velPf, ETOPO1Path, STPath):
|
||||
'''
|
||||
去掉剖面尾部异常数据, 触底后的
|
||||
'''
|
||||
lat = velPf.lat
|
||||
lon = velPf.lon
|
||||
botDep = velPf.botDep
|
||||
dep = velPf.x
|
||||
vel = velPf.y
|
||||
# 如果没有给定深度,则直接从数据库中提取
|
||||
if botDep == None:
|
||||
data = DataBase(ETOPO1Path, STPath)
|
||||
data.set_coord(lat, lon)
|
||||
botDep = data.get_bottomDepth()
|
||||
# 过滤掉触底后的曲线
|
||||
temp = dep < botDep
|
||||
dep = dep[temp]
|
||||
vel = vel[temp]
|
||||
# 剖面赋值
|
||||
velPf = Profile()
|
||||
velPf.set_data(dep, vel)
|
||||
velPf.set_coord(lat, lon)
|
||||
velPf.set_bottomDepth(botDep)
|
||||
return velPf
|
||||
|
||||
|
||||
def resampleProfile(velPf):
|
||||
'''
|
||||
重采样剖面, 间隔1m采样
|
||||
'''
|
||||
lat = velPf.lat
|
||||
lon = velPf.lon
|
||||
botDep = velPf.botDep
|
||||
dep = velPf.x
|
||||
vel = velPf.y
|
||||
# 得到等间距的采样曲线
|
||||
depInterp = np.arange(0, dep[-1])
|
||||
f = interp1d(dep, vel, fill_value='extrapolate')
|
||||
velInterp = f(depInterp)
|
||||
# 剖面赋值
|
||||
velPf = Profile()
|
||||
velPf.set_data(depInterp, velInterp)
|
||||
velPf.set_coord(lat, lon)
|
||||
velPf.set_bottomDepth(botDep)
|
||||
return velPf
|
||||
|
||||
|
||||
def lowPassFilter(velPf):
|
||||
'''
|
||||
低通滤波器, 使曲线平滑
|
||||
'''
|
||||
lat = velPf.lat
|
||||
lon = velPf.lon
|
||||
botDep = velPf.botDep
|
||||
dep = velPf.x
|
||||
vel = velPf.y
|
||||
# 设计数字滤波器
|
||||
freqc = 0.05
|
||||
order = 2
|
||||
b, a = butter(order, freqc)
|
||||
# 对曲线进行滤波
|
||||
vel = filtfilt(b, a, vel)
|
||||
# 剖面赋值
|
||||
velPf = Profile()
|
||||
velPf.set_data(dep, vel)
|
||||
velPf.set_coord(lat, lon)
|
||||
velPf.set_bottomDepth(botDep)
|
||||
return velPf
|
||||
|
||||
|
||||
def processProfile(velRawPf, ETOPO1Path, STPath):
|
||||
'''
|
||||
对原始剖面数据进行处理, 得到处理后的剖面
|
||||
'''
|
||||
# 去掉刚入水,剧烈变化部分
|
||||
velPf = removeHead(velRawPf)
|
||||
# 去掉触底后,无效部分
|
||||
velPf = removeTail(velPf, ETOPO1Path, STPath)
|
||||
# 等间距重采样
|
||||
velPf = resampleProfile(velPf)
|
||||
# 低通滤波
|
||||
velPf = lowPassFilter(velPf)
|
||||
return velPf
|
||||
在新工单中引用
屏蔽一个用户