22
22
from ..eddy_feature import Amplitude , Contours
23
23
from .. import VAR_DESCR
24
24
from ..generic import distance , interp2d_geo , fit_circle , uniform_resample
25
- from ..poly import poly_contain_poly , winding_number_grid_in_poly
25
+ from ..poly import poly_contain_poly , winding_number_grid_in_poly , winding_number_poly
26
26
27
27
logger = logging .getLogger ("pet" )
28
28
@@ -117,6 +117,33 @@ def _fit_circle_path(vertice):
117
117
return centlon_e , centlat_e , eddy_radius_e , aerr
118
118
119
119
120
+ @njit (cache = True , fastmath = True )
121
+ def _get_pixel_in_regular (vertices , x_c , y_c , x_start , x_stop , y_start , y_stop ):
122
+ if x_stop < x_start :
123
+ x_ref = vertices [0 , 0 ]
124
+ x_array = (concatenate ((x_c [x_start :], x_c [:x_stop ])) - x_ref + 180 ) % 360 + x_ref - 180
125
+ return winding_number_grid_in_poly (x_array , y_c [y_start :y_stop ], x_start , x_stop , x_c .shape [0 ], y_start ,
126
+ vertices )
127
+ else :
128
+ return winding_number_grid_in_poly (x_c [x_start :x_stop ], y_c [y_start :y_stop ], x_start , x_stop , x_c .shape [0 ],
129
+ y_start , vertices )
130
+
131
+
132
+ @njit (cache = True , fastmath = True )
133
+ def _get_pixel_in_unregular (vertices , x_c , y_c , x_start , x_stop , y_start , y_stop ):
134
+ nb_x , nb_y = x_stop - x_start , y_stop - y_start
135
+ wn = empty ((nb_x , nb_y ), dtype = numba_types .bool_ )
136
+ for i in range (nb_x ):
137
+ for j in range (nb_y ):
138
+ x_pt = x_c [i + x_start , j + y_start ]
139
+ y_pt = y_c [i + x_start , j + y_start ]
140
+ wn [i , j ] = winding_number_poly (x_pt , y_pt , vertices )
141
+ i_x , i_y = where (wn )
142
+ i_x += x_start
143
+ i_y += y_start
144
+ return i_x , i_y
145
+
146
+
120
147
@njit (cache = True , fastmath = True )
121
148
def coordinates_to_local (lon , lat , lon0 , lat0 ):
122
149
D2R = pi / 180.
@@ -216,6 +243,7 @@ class GridDataset(object):
216
243
GRAVITY = 9.807
217
244
EARTH_RADIUS = 6370997.
218
245
# EARTH_RADIUS = 6378136.3
246
+ # indice margin (if put to 0, raise warning that i don't understand)
219
247
N = 1
220
248
221
249
def __init__ (self , filename , x_name , y_name , centered = None , indexs = None ):
@@ -235,7 +263,7 @@ def __init__(self, filename, x_name, y_name, centered=None, indexs=None):
235
263
self .filename = filename
236
264
self .coordinates = x_name , y_name
237
265
self .vars = dict ()
238
- self .indexs = None if indexs is None else indexs
266
+ self .indexs = dict () if indexs is None else indexs
239
267
self .interpolators = dict ()
240
268
if centered is None :
241
269
logger .warning ('We assume the position of grid is the center'
@@ -793,18 +821,12 @@ def bbox_indice(self, vertices):
793
821
dist , idx = self .index_interp .query (vertices , k = 1 )
794
822
i_y = idx % self .x_c .shape [1 ]
795
823
i_x = int_ ((idx - i_y ) / self .x_c .shape [1 ])
796
- return (i_x .min () - self .N , i_x .max () + self .N + 1 ), (i_y .min () - self .N , i_y .max () + self .N + 1 )
824
+ return (max (i_x .min () - self .N , 0 ), i_x .max () + self .N + 1 ), \
825
+ (max (i_y .min () - self .N , 0 ), i_y .max () + self .N + 1 )
797
826
798
827
def get_pixels_in (self , contour ):
799
828
(x_start , x_stop ), (y_start , y_stop ) = contour .bbox_slice
800
- pts = array ((self .x_c [x_start :x_stop , y_start :y_stop ].reshape (- 1 ),
801
- self .y_c [x_start :x_stop , y_start :y_stop ].reshape (- 1 ))).T
802
- x_stop = min (x_stop , self .x_c .shape [0 ])
803
- mask = contour .contains_points (pts ).reshape ((x_stop - x_start , - 1 ))
804
- i_x , i_y = where (mask )
805
- i_x += x_start
806
- i_y += y_start
807
- return i_x , i_y
829
+ return _get_pixel_in_unregular (contour .vertices , self .x_c , self .y_c , x_start , x_stop , y_start , y_stop )
808
830
809
831
def normalize_x_indice (self , indices ):
810
832
"""Not do"""
@@ -903,25 +925,18 @@ def init_pos_interpolator(self):
903
925
self .yinterp = arange (self .y_bounds .shape [0 ])
904
926
905
927
def bbox_indice (self , vertices ):
906
- return bbox_indice_regular (vertices , self .x_bounds [ 0 ] , self .y_bounds [ 0 ] , self .xstep , self .ystep ,
928
+ return bbox_indice_regular (vertices , self .x_bounds , self .y_bounds , self .xstep , self .ystep ,
907
929
self .N , self .is_circular (), self .x_size )
908
930
909
931
def get_pixels_in (self , contour ):
910
932
(x_start , x_stop ), (y_start , y_stop ) = contour .bbox_slice
911
- if x_stop < x_start :
912
- x_ref = contour .vertices [0 , 0 ]
913
- x_array = (concatenate ((self .x_c [x_start :], self .x_c [:x_stop ])) - x_ref + 180 ) % 360 + x_ref - 180
914
- else :
915
- x_array = self .x_c [x_start :x_stop ]
916
- return winding_number_grid_in_poly (x_array , self .y_c [y_start :y_stop ], x_start , x_stop , self .x_size , y_start ,
917
- contour .vertices )
933
+ return _get_pixel_in_regular (contour .vertices , self .x_c , self .y_c , x_start , x_stop , y_start , y_stop )
918
934
919
935
def normalize_x_indice (self , indices ):
920
936
return indices % self .x_size
921
937
922
938
def nearest_grd_indice (self , x , y ):
923
- return int32 (round_ (((x - self .x_bounds [0 ]) % 360 ) / self .xstep )), \
924
- int32 (round_ ((y - self .y_bounds [0 ]) / self .ystep ))
939
+ return _nearest_grd_indice (x ,y , self .x_bounds , self .y_bounds , self .xstep , self .ystep )
925
940
926
941
@property
927
942
def xstep (self ):
@@ -1066,7 +1081,7 @@ def convolve_filter_with_dynamic_kernel(self, grid, kernel_func, lat_max=85, ext
1066
1081
t0 = datetime .now ()
1067
1082
if debug_active and len (dt ) > 0 :
1068
1083
dt_mean = np_mean (dt ) * (nb_lines - i )
1069
- print ('Remain ' , dt_mean , 'ETA ' , t0 + dt_mean , 'current kernel size :' , k_shape , 'Step : %d/%d' % (i , nb_lines ), end = "\r " )
1084
+ print ('Remain ' , dt_mean , 'ETA ' , t0 + dt_mean , 'current kernel size :' , k_shape , 'Step : %d/%d ' % (i , nb_lines ), end = "\r " )
1070
1085
1071
1086
1072
1087
# Half size, k_shape must be always impair
@@ -1452,11 +1467,16 @@ def bbox_indice_regular(vertices, x0, y0, xstep, ystep, N, circular, x_size):
1452
1467
lon , lat = vertices [:, 0 ], vertices [:, 1 ]
1453
1468
lon_min , lon_max = lon .min (), lon .max ()
1454
1469
lat_min , lat_max = lat .min (), lat .max ()
1455
- i_x0 , i_y0 = int32 ((( lon_min - x0 ) % 360 ) // xstep ), int32 (( lat_min - y0 ) // ystep )
1456
- i_x1 , i_y1 = int32 ((( lon_max - x0 ) % 360 ) // xstep ), int32 (( lat_max - y0 ) // ystep )
1470
+ i_x0 , i_y0 = _nearest_grd_indice ( lon_min , lat_min , x0 , y0 , xstep , ystep )
1471
+ i_x1 , i_y1 = _nearest_grd_indice ( lon_max , lat_max , x0 , y0 , xstep , ystep )
1457
1472
if circular :
1458
1473
slice_x = (i_x0 - N ) % x_size , (i_x1 + N + 1 ) % x_size
1459
1474
else :
1460
- slice_x = min (i_x0 - N , 0 ), i_x1 + N + 1
1475
+ slice_x = max (i_x0 - N , 0 ), i_x1 + N + 1
1461
1476
slice_y = i_y0 - N , i_y1 + N + 1
1462
1477
return slice_x , slice_y
1478
+
1479
+
1480
+ @njit (cache = True , fastmath = True )
1481
+ def _nearest_grd_indice (x , y , x0 , y0 , xstep , ystep ):
1482
+ return numba_types .int32 (round (((x - x0 [0 ]) % 360. ) / xstep )), numba_types .int32 (round ((y - y0 [0 ]) / ystep ))
0 commit comments