@@ -202,6 +202,7 @@ class GridDataset(object):
202
202
203
203
GRAVITY = 9.807
204
204
EARTH_RADIUS = 6370997.
205
+ # EARTH_RADIUS = 6378136.3
205
206
N = 1
206
207
207
208
def __init__ (self , filename , x_name , y_name , centered = None ):
@@ -374,7 +375,6 @@ def copy(self, grid_in, grid_out):
374
375
)
375
376
self .vars [grid_out ] = self .grid (grid_in ).copy ()
376
377
377
-
378
378
def grid (self , varname ):
379
379
"""give grid required
380
380
"""
@@ -1068,6 +1068,7 @@ def spectrum_lonlat(self, grid_name, area=None, ref=None, **kwargs):
1068
1068
def add_uv (self , grid_height ):
1069
1069
"""Compute a u and v grid
1070
1070
"""
1071
+ data = self .grid (grid_height )
1071
1072
h_dict = self .variables_description [grid_height ]
1072
1073
for variable in ('u' , 'v' ):
1073
1074
self .variables_description [variable ] = dict (
@@ -1076,44 +1077,67 @@ def add_uv(self, grid_height):
1076
1077
args = tuple ((variable , * h_dict ['args' ][1 :])),
1077
1078
kwargs = h_dict ['kwargs' ].copy (),
1078
1079
)
1080
+
1079
1081
self .variables_description [variable ]['attrs' ]['units' ] += '/s'
1080
- data = self .grid (grid_height )
1081
- gof = sin (deg2rad (self .y_c )) * ones ((self .x_c .shape [0 ], 1 )) * 4. * pi / 86400.
1082
- # gof = sin(deg2rad(self.y_c))* ones((self.x_c.shape[0], 1)) * 4. * pi / (23 * 3600 + 56 *60 +4.1 )
1082
+ # Divide by sideral day
1083
+ gof = sin (deg2rad (self .y_c )) * ones ((self .x_c .shape [0 ], 1 )) * 4. * pi / (23 * 3600 + 56 * 60 + 4.1 )
1083
1084
with errstate (divide = 'ignore' ):
1084
1085
gof = self .GRAVITY / (gof * ones ((self .x_c .shape [0 ], 1 )))
1085
1086
1086
- m_y = array ((1 , 0 , - 1 ))
1087
- m_x = array ((1 , 0 , - 1 ))
1088
- d_hy = convolve (
1089
- data ,
1090
- weights = m_y .reshape ((- 1 , 1 )).T
1091
- )
1092
- mask = convolve (
1093
- int8 (data .mask ),
1094
- weights = ones (m_y .shape ).reshape ((1 , - 1 ))
1095
- )
1096
- d_hy = ma .array (d_hy , mask = mask != 0 )
1087
+ w = [
1088
+ array ((3 , - 32 , 168 , - 672 , 0 , 672 , - 168 , 32 , - 3 )) / 840. ,
1089
+ array ((- 1 , 9 , - 45 , 0 , 45 , - 9 , 1 )) / 60. ,
1090
+ array ((1 , - 8 , 0 , 8 , - 1 )) / 12. ,
1091
+ array ((- 1 , 0 , 1 )) / 2. ,
1092
+ array ((- 1 , 1 )), # array((0, -1, 1))
1093
+ (1 , array ((- 1 , 1 ))), # array((-1, 1, 0))
1094
+ ]
1095
+
1096
+ # Compute v
1097
+ self .vars ['v' ] = None
1098
+ mode = 'wrap' if self .is_circular () else 'reflect'
1099
+ for m_x in w :
1100
+ if isinstance (m_x , tuple ):
1101
+ shift , m_x = m_x
1102
+ data_ = data .copy ()
1103
+ data_ [shift :] = data [:- shift ]
1104
+ data_ [:shift ] = data [- shift :]
1105
+ else :
1106
+ data_ = data
1107
+ d_hx = convolve (data_ , weights = m_x .reshape ((- 1 , 1 )), mode = mode )
1108
+ mask = convolve (int8 (data_ .mask ), weights = ones (m_x .shape ).reshape ((- 1 , 1 )), mode = mode )
1109
+ d_hx = ma .array (d_hx , mask = mask != 0 )
1110
+
1111
+ d_x_degrees = convolve (self .x_c , m_x , mode = mode ).reshape ((- 1 , 1 ))
1112
+ d_x_degrees = (d_x_degrees + 180 ) % 360 - 180
1113
+ d_x = self .EARTH_RADIUS * 2 * pi / 360 * d_x_degrees * cos (deg2rad (self .y_c ))
1114
+ v = d_hx / d_x * gof
1115
+ if self .vars ['v' ] is None :
1116
+ self .vars ['v' ] = v
1117
+ else :
1118
+ self .vars ['v' ][self .vars ['v' ].mask ] = v [self .vars ['v' ].mask ]
1119
+
1120
+ # Compute u
1121
+ self .vars ['u' ] = None
1122
+ for m_y in w :
1123
+ if isinstance (m_y , tuple ):
1124
+ shift , m_y = m_y
1125
+ data_ = data .copy ()
1126
+ data_ [:, shift :] = data [:, :- 1 ]
1127
+ else :
1128
+ data_ = data
1097
1129
1098
- d_y = self .EARTH_RADIUS * 2 * pi / 360 * convolve (self .y_c , m_y )
1130
+ d_hy = convolve (data_ , weights = m_y .reshape ((- 1 , 1 )).T )
1131
+ mask = convolve (int8 (data_ .mask ), weights = ones (m_y .shape ).reshape ((1 , - 1 )))
1132
+ d_hy = ma .array (d_hy , mask = mask != 0 )
1099
1133
1100
- self .vars ['u' ] = - d_hy / d_y * gof
1101
- mode = 'wrap' if self .is_circular () else 'reflect'
1102
- d_hx = convolve (
1103
- data ,
1104
- weights = m_x .reshape ((- 1 , 1 )),
1105
- mode = mode ,
1106
- )
1107
- mask = convolve (
1108
- int8 (data .mask ),
1109
- weights = ones (m_x .shape ).reshape ((- 1 , 1 )),
1110
- mode = mode ,
1111
- )
1112
- d_hx = ma .array (d_hx , mask = mask != 0 )
1113
- d_x_degrees = convolve (self .x_c , m_x , mode = mode ).reshape ((- 1 , 1 ))
1114
- d_x_degrees = (d_x_degrees + 180 ) % 360 - 180
1115
- d_x = self .EARTH_RADIUS * 2 * pi / 360 * d_x_degrees * cos (deg2rad (self .y_c ))
1116
- self .vars ['v' ] = d_hx / d_x * gof
1134
+ d_y = self .EARTH_RADIUS * 2 * pi / 360 * convolve (self .y_c , m_y )
1135
+
1136
+ u = - d_hy / d_y * gof
1137
+ if self .vars ['u' ] is None :
1138
+ self .vars ['u' ] = u
1139
+ else :
1140
+ self .vars ['u' ][self .vars ['u' ].mask ] = u [self .vars ['u' ].mask ]
1117
1141
1118
1142
def speed_coef_mean (self , contour ):
1119
1143
"""some nan can be compute over contour if we are near border,
@@ -1226,8 +1250,9 @@ def bbox_indice_regular(vertices, x0, y0, xstep, ystep, N, circular, x_size):
1226
1250
lat_min , lat_max = lat .min (), lat .max ()
1227
1251
i_x0 , i_y0 = int32 (((lon_min - x0 ) % 360 ) // xstep ), int32 ((lat_min - y0 ) // ystep )
1228
1252
i_x1 , i_y1 = int32 (((lon_max - x0 ) % 360 ) // xstep ), int32 ((lat_max - y0 ) // ystep )
1229
-
1230
1253
if circular :
1231
1254
slice_x = (i_x0 - N ) % x_size , (i_x1 + N + 1 ) % x_size
1255
+ else :
1256
+ slice_x = min (i_x0 - N , 0 ), i_x1 + N + 1
1232
1257
slice_y = i_y0 - N , i_y1 + N + 1
1233
1258
return slice_x , slice_y
0 commit comments