1
1
# -*- coding: utf-8 -*-
2
2
"""
3
3
"""
4
- from numpy import sin , pi , cos , arctan2 , empty , nan , absolute , floor , ones , linspace , interp
4
+ from numpy import (
5
+ sin ,
6
+ pi ,
7
+ cos ,
8
+ arctan2 ,
9
+ empty ,
10
+ nan ,
11
+ absolute ,
12
+ floor ,
13
+ ones ,
14
+ linspace ,
15
+ interp ,
16
+ where ,
17
+ )
5
18
from numba import njit , prange
6
19
from numpy .linalg import lstsq
7
20
@@ -21,7 +34,7 @@ def distance_grid(lon0, lat0, lon1, lat1):
21
34
nb_0 = lon0 .shape [0 ]
22
35
nb_1 = lon1 .shape [0 ]
23
36
dist = empty ((nb_0 , nb_1 ))
24
- D2R = pi / 180.
37
+ D2R = pi / 180.0
25
38
for i in prange (nb_0 ):
26
39
for j in prange (nb_1 ):
27
40
dlat = absolute (lat1 [j ] - lat0 [i ])
@@ -45,7 +58,7 @@ def distance_grid(lon0, lat0, lon1, lat1):
45
58
46
59
@njit (cache = True , fastmath = True )
47
60
def distance (lon0 , lat0 , lon1 , lat1 ):
48
- D2R = pi / 180.
61
+ D2R = pi / 180.0
49
62
sin_dlat = sin ((lat1 - lat0 ) * 0.5 * D2R )
50
63
sin_dlon = sin ((lon1 - lon0 ) * 0.5 * D2R )
51
64
cos_lat1 = cos (lat0 * D2R )
@@ -57,16 +70,21 @@ def distance(lon0, lat0, lon1, lat1):
57
70
@njit (cache = True )
58
71
def distance_vincenty (lon0 , lat0 , lon1 , lat1 ):
59
72
""" better than haversine but buggy ??"""
60
- D2R = pi / 180.
73
+ D2R = pi / 180.0
61
74
dlon = (lon1 - lon0 ) * D2R
62
75
cos_dlon = cos (dlon )
63
76
cos_lat1 = cos (lat0 * D2R )
64
77
cos_lat2 = cos (lat1 * D2R )
65
78
sin_lat1 = sin (lat0 * D2R )
66
79
sin_lat2 = sin (lat1 * D2R )
67
80
return 6370997.0 * arctan2 (
68
- ((cos_lat2 * sin (dlon ) ** 2 ) + (cos_lat1 * sin_lat2 - sin_lat1 * cos_lat2 * cos_dlon ) ** 2 ) ** .5 ,
69
- sin_lat1 * sin_lat2 + cos_lat1 * cos_lat2 * cos_dlon )
81
+ (
82
+ (cos_lat2 * sin (dlon ) ** 2 )
83
+ + (cos_lat1 * sin_lat2 - sin_lat1 * cos_lat2 * cos_dlon ) ** 2
84
+ )
85
+ ** 0.5 ,
86
+ sin_lat1 * sin_lat2 + cos_lat1 * cos_lat2 * cos_dlon ,
87
+ )
70
88
71
89
72
90
@njit (cache = True , fastmath = True )
@@ -86,25 +104,27 @@ def interp2d_geo(x_g, y_g, z_g, m_g, x, y):
86
104
y_ = (y [i ] - y_ref ) / y_step
87
105
i0 = int (floor (x_ ))
88
106
i1 = i0 + 1
89
- xd = ( x_ - i0 )
107
+ xd = x_ - i0
90
108
if is_circular :
91
109
i0 %= nb_x
92
110
i1 %= nb_x
93
111
j0 = int (floor (y_ ))
94
112
j1 = j0 + 1
95
- yd = ( y_ - j0 )
113
+ yd = y_ - j0
96
114
z00 = z_g [i0 , j0 ]
97
115
z01 = z_g [i0 , j1 ]
98
116
z10 = z_g [i1 , j0 ]
99
117
z11 = z_g [i1 , j1 ]
100
118
if m_g [i0 , j0 ] or m_g [i0 , j1 ] or m_g [i1 , j0 ] or m_g [i1 , j1 ]:
101
119
z [i ] = nan
102
120
else :
103
- z [i ] = (z00 * (1 - xd ) + (z10 * xd )) * (1 - yd ) + (z01 * (1 - xd ) + z11 * xd ) * yd
121
+ z [i ] = (z00 * (1 - xd ) + (z10 * xd )) * (1 - yd ) + (
122
+ z01 * (1 - xd ) + z11 * xd
123
+ ) * yd
104
124
return z
105
125
106
126
107
- @njit (cache = True , fastmath = True , parallel = True )
127
+ @njit (cache = True , fastmath = True , parallel = False )
108
128
def custom_convolution (data , mask , kernel ):
109
129
"""do sortin at high lattitude big part of value are masked"""
110
130
nb_x = kernel .shape [0 ]
@@ -113,9 +133,9 @@ def custom_convolution(data, mask, kernel):
113
133
out = empty (data .shape [0 ] - nb_x + 1 )
114
134
for i in prange (out .shape [0 ]):
115
135
if mask [i + demi_x , demi_y ] == 1 :
116
- w = (mask [i : i + nb_x ] * kernel ).sum ()
136
+ w = (mask [i : i + nb_x ] * kernel ).sum ()
117
137
if w != 0 :
118
- out [i ] = (data [i : i + nb_x ] * kernel ).sum () / w
138
+ out [i ] = (data [i : i + nb_x ] * kernel ).sum () / w
119
139
else :
120
140
out [i ] = nan
121
141
else :
@@ -135,19 +155,19 @@ def fit_circle(x_vec, y_vec):
135
155
136
156
norme = (x_vec [1 :] - x_mean ) ** 2 + (y_vec [1 :] - y_mean ) ** 2
137
157
norme_max = norme .max ()
138
- scale = norme_max ** .5
158
+ scale = norme_max ** 0 .5
139
159
140
160
# Form matrix equation and solve it
141
161
# Maybe put f4
142
162
datas = ones ((nb_elt - 1 , 3 ))
143
- datas [:, 0 ] = 2. * (x_vec [1 :] - x_mean ) / scale
144
- datas [:, 1 ] = 2. * (y_vec [1 :] - y_mean ) / scale
163
+ datas [:, 0 ] = 2.0 * (x_vec [1 :] - x_mean ) / scale
164
+ datas [:, 1 ] = 2.0 * (y_vec [1 :] - y_mean ) / scale
145
165
146
166
(center_x , center_y , radius ), residuals , rank , s = lstsq (datas , norme / norme_max )
147
167
148
168
# Unscale data and get circle variables
149
169
radius += center_x ** 2 + center_y ** 2
150
- radius **= .5
170
+ radius **= 0 .5
151
171
center_x *= scale
152
172
center_y *= scale
153
173
# radius of fitted circle
@@ -162,13 +182,16 @@ def fit_circle(x_vec, y_vec):
162
182
# Find distance between circle center and contour points_inside_poly
163
183
for i_elt in range (nb_elt ):
164
184
# Find distance between circle center and contour points_inside_poly
165
- dist_poly = ((x_vec [i_elt ] - center_x ) ** 2 + (y_vec [i_elt ] - center_y ) ** 2 ) ** .5
185
+ dist_poly = (
186
+ (x_vec [i_elt ] - center_x ) ** 2 + (y_vec [i_elt ] - center_y ) ** 2
187
+ ) ** 0.5
166
188
# Indices of polygon points outside circle
167
189
# p_inon_? : polygon x or y points inside & on the circle
168
190
if dist_poly > radius :
169
191
p_inon_y [i_elt ] = center_y + radius * (y_vec [i_elt ] - center_y ) / dist_poly
170
- p_inon_x [i_elt ] = center_x - (center_x - x_vec [i_elt ]) * (center_y - p_inon_y [i_elt ]) / (
171
- center_y - y_vec [i_elt ])
192
+ p_inon_x [i_elt ] = center_x - (center_x - x_vec [i_elt ]) * (
193
+ center_y - p_inon_y [i_elt ]
194
+ ) / (center_y - y_vec [i_elt ])
172
195
else :
173
196
p_inon_x [i_elt ] = x_vec [i_elt ]
174
197
p_inon_y [i_elt ] = y_vec [i_elt ]
@@ -179,14 +202,17 @@ def fit_circle(x_vec, y_vec):
179
202
for i_elt in range (nb_elt - 1 ):
180
203
# Indices of polygon points outside circle
181
204
# p_inon_? : polygon x or y points inside & on the circle
182
- p_area_incirc += p_inon_x [i_elt ] * p_inon_y [1 + i_elt ] - p_inon_x [i_elt + 1 ] * p_inon_y [i_elt ]
205
+ p_area_incirc += (
206
+ p_inon_x [i_elt ] * p_inon_y [1 + i_elt ]
207
+ - p_inon_x [i_elt + 1 ] * p_inon_y [i_elt ]
208
+ )
183
209
# Shape test
184
210
# Area and centroid of closed contour/polygon
185
211
p_area += x_vec [i_elt ] * y_vec [1 + i_elt ] - x_vec [1 + i_elt ] * y_vec [i_elt ]
186
- p_area = abs (p_area ) * .5
187
- p_area_incirc = abs (p_area_incirc ) * .5
212
+ p_area = abs (p_area ) * 0 .5
213
+ p_area_incirc = abs (p_area_incirc ) * 0 .5
188
214
189
- a_err = (c_area - 2 * p_area_incirc + p_area ) * 100. / c_area
215
+ a_err = (c_area - 2 * p_area_incirc + p_area ) * 100.0 / c_area
190
216
return center_x , center_y , radius , a_err
191
217
192
218
@@ -228,8 +254,36 @@ def flatten_line_matrix(l_matrix):
228
254
inc = 0
229
255
for i in range (nb_line ):
230
256
for j in range (sampling ):
231
- out [inc ] = l_matrix [i ,j ]
257
+ out [inc ] = l_matrix [i , j ]
232
258
inc += 1
233
259
out [inc ] = nan
234
260
inc += 1
235
261
return out
262
+
263
+
264
+ @njit (cache = True )
265
+ def split_line (x , y , i ):
266
+ """
267
+ Split x and y at each i change
268
+ Args:
269
+ x: array
270
+ y: array
271
+ i: array of int at each i change, we cut x, y
272
+
273
+ Returns: x and y separate by nan at each i jump
274
+ """
275
+ nb_jump = len (where (i [1 :] - i [0 ] != 0 )[0 ])
276
+ nb_value = x .shape [0 ]
277
+ final_size = (nb_jump - 1 ) + nb_value
278
+ new_x = empty (final_size , dtype = x .dtype )
279
+ new_y = empty (final_size , dtype = y .dtype )
280
+ new_j = 0
281
+ for j in range (nb_value ):
282
+ new_x [new_j ] = x [j ]
283
+ new_y [new_j ] = y [j ]
284
+ new_j += 1
285
+ if j < (nb_value - 1 ) and i [j ] != i [j + 1 ]:
286
+ new_x [new_j ] = nan
287
+ new_y [new_j ] = nan
288
+ new_j += 1
289
+ return new_x , new_y
0 commit comments