文件
AcousticSO/pyat/ProfileRead.py
T

169 行
4.0 KiB
Python

import unicodedata
import numpy as np
from ProfileDataType import Profile
from scipy.interpolate import interp1d
from scipy.signal import butter, filtfilt
from 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