计算卫星数据中u和v风分量的卷曲 - Python

时间:2015-09-21 18:13:31

标签: python numpy vector signal-processing weather

我不确定如何在卫星数据中采用u和v分量的导数。我以为我可以用这种方式使用numpy.gradient:

    from netCDF4 import Dataset      
    import numpy as np      
    import matplotlib.pyplot as plt 

    GridSat = Dataset('analysis_20040713_v11l30flk.nc4','r',format='NETCDF4')
    missing_data = -9999.0
    lat = GridSat.variables['lat']   
    lat = lat[:]     
    lat[np.where(lat==missing_data)] = np.nan  
    lat[np.where(lat > 90.0)] = np.nan     

    lon = GridSat.variables['lon']   
    lon = lon[:]                
    lon[np.where(lon==missing_data)] = np.nan


    uwind_data = GridSat.variables['uwnd']  
    uwind = GridSat.variables['uwnd'][:]
    uwind_sf = uwind_data.scale_factor   
    uwind_ao = uwind_data.add_offset
    miss_uwind = uwind_data.missing_value

    uwind[np.where(uwind==miss_uwind)] = np.nan    


    vwind_data = GridSat.variables['vwnd']  
    vwind = GridSat.variables['vwnd'][:]
    vwind_sf = vwind_data.scale_factor    
    vwind_ao = vwind_data.add_offset
    miss_vwind = vwind_data.missing_value

    vwind[np.where(vwind==miss_vwind)] = np.nan  


    uwind = uwind[2,:,:]
    vwind = vwind[2,:,:]  

    dx = 28400.0 # meters calculated from the 0.25 degree spatial gridding 
    dy = 28400.0 # meters calculated from the 0.25 degree spatial gridding 

    dv_dx, dv_dy = np.gradient(vwind, [dx,dy])
    du_dx, du_dy = np.gradient(uwind, [dx,dy])


    File "<ipython-input-229-c6a5d5b09224>", line 1, in <module>
     np.gradient(vwind, [dx,dy])

    File "/Users/anaconda/lib/python2.7/site-packages/nump/lib/function_base.py", line 1040, in gradient
out /= dx[axis]

    ValueError: operands could not be broadcast together with shapes (628,1440) (2,) (628,1440) 

老实说,我不知道如何计算(0.25x0.25)度间距的卫星数据的中心差异。我不认为我的dx和dy也是正确的。如果有人对接近卫星数据中的这些类型的计算有一个好主意,我将非常感激。谢谢!!

3 个答案:

答案 0 :(得分:1)

@moarningsun评论时,更改您致电np.gradient的方式应更正ValueError

dv_dx, dv_dy = np.gradient(vwind, dx,dy)
du_dx, du_dy = np.gradient(uwind, dx,dy)

如何从文件中获取vwind并不是特别重要,尤其是因为我们无法访问该文件。虽然我们可以从错误消息中猜出,但vwind的形状本来是有用的。错误中对(2,)数组的引用是[dx,dy]。当您收到broadcasting错误时,请检查各种参数的形状。

np.gradient代码是直截了当的,只是因为它可以处理1,2,3d和更高的数据。基本上它做了像

这样的计算
(z[:,2:]-z[:,:-2])/2
(z[2:,:]-z[:-2,:])/2

表示内部值,1表示步骤表示边界值。

我将从渐变(或不是)中获得curl的问题留给其他人。

答案 1 :(得分:0)

如上所述,存在必须实现某种离散卷曲运算符的问题。这可能是大气物理学中常见的问题所以你可以查看一本教科书。

另一种方法可能是将样条拟合到数据,以便您可以使用连续操作。例如

bspl = scipy.interpolate.SmoothBivariateSpline(x,y,z,s=0)

s这是一个你应该玩的平滑因素;如果数据非常精确s=0会得到最好的结果;如果他们有大量的分散,你会想要一些平滑。现在你可以直接计算卷曲:

curl = bspl.integral(x0,x1,y0,y1) / ((x1-x0)*(y1-y0))

编辑: 上面的表达式没有给出卷曲,但基本的想法是合理的。

答案 2 :(得分:-1)

下面的代码可以在Matlab wind数据集上运行,文件wind.mat位于

http://bioinformatics.intec.ugent.be/MotifSuite/INCLUSive_for_users/CPU_64/Matlab_Compiler_Runtime/v79/toolbox/matlab/demos/

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
import scipy.io as sio

def curl(x,y,z,u,v,w):
    dx = x[0,:,0]
    dy = y[:,0,0]
    dz = z[0,0,:]

    dummy, dFx_dy, dFx_dz = np.gradient (u, dx, dy, dz, axis=[1,0,2])
    dFy_dx, dummy, dFy_dz = np.gradient (v, dx, dy, dz, axis=[1,0,2])
    dFz_dx, dFz_dy, dummy = np.gradient (w, dx, dy, dz, axis=[1,0,2])

    rot_x = dFz_dy - dFy_dz
    rot_y = dFx_dz - dFz_dx
    rot_z = dFy_dx - dFx_dy

    l = np.sqrt(np.power(u,2.0) + np.power(v,2.0) + np.power(w,2.0));

    m1 = np.multiply(rot_x,u)
    m2 = np.multiply(rot_y,v)
    m3 = np.multiply(rot_z,w)

    tmp1 = (m1 + m2 + m3)
    tmp2 = np.multiply(l,2.0)

    av = np.divide(tmp1, tmp2)

    return rot_x, rot_y, rot_z, av

mat = sio.loadmat('wind.mat')
x = mat['x']; y = mat['y']; z = mat['z']
u = mat['u']; v = mat['v']; w = mat['w']

rot_x, rot_y, rot_z, av = curl(x,y,z,u,v,w)


# plot a small area of the wind
i=5;j=7;k=8;S = 3
x1 = x[i-S:i+S, j-S:j+S, k-S:k+S]; 
y1 = y[i-S:i+S, j-S:j+S, k-S:k+S]; 
z1 = z[i-S:i+S, j-S:j+S, k-S:k+S];
u1 = u[i-S:i+S, j-S:j+S, k-S:k+S]; 
v1 = v[i-S:i+S, j-S:j+S, k-S:k+S]; 
w1 = w[i-S:i+S, j-S:j+S, k-S:k+S];

fig = plt.figure()
ax = fig.gca(projection='3d')
ax.view_init(elev=47, azim=-145)

ax.quiver(x1, y1, z1, u1, v1, w1, length=0.05, color = 'black')

i=5;j=7;k=8;
x0=x[i,j,k]
y0=y[i,j,k]
z0=z[i,j,k]
cx0=rot_x[i,j,k]
cy0=rot_y[i,j,k]
cz0=rot_z[i,j,k]
ax.quiver(x0, y0, z0, 0, cy0, cz0, length=1.0, color = 'blue')

plt.show()
相关问题