2222from ..eddy_feature import Amplitude , Contours
2323from .. import VAR_DESCR
2424from ..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
2626
2727logger = logging .getLogger ("pet" )
2828
@@ -117,6 +117,33 @@ def _fit_circle_path(vertice):
117117 return centlon_e , centlat_e , eddy_radius_e , aerr
118118
119119
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+
120147@njit (cache = True , fastmath = True )
121148def coordinates_to_local (lon , lat , lon0 , lat0 ):
122149 D2R = pi / 180.
@@ -216,6 +243,7 @@ class GridDataset(object):
216243 GRAVITY = 9.807
217244 EARTH_RADIUS = 6370997.
218245 # EARTH_RADIUS = 6378136.3
246+ # indice margin (if put to 0, raise warning that i don't understand)
219247 N = 1
220248
221249 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):
235263 self .filename = filename
236264 self .coordinates = x_name , y_name
237265 self .vars = dict ()
238- self .indexs = None if indexs is None else indexs
266+ self .indexs = dict () if indexs is None else indexs
239267 self .interpolators = dict ()
240268 if centered is None :
241269 logger .warning ('We assume the position of grid is the center'
@@ -793,18 +821,12 @@ def bbox_indice(self, vertices):
793821 dist , idx = self .index_interp .query (vertices , k = 1 )
794822 i_y = idx % self .x_c .shape [1 ]
795823 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 )
797826
798827 def get_pixels_in (self , contour ):
799828 (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 )
808830
809831 def normalize_x_indice (self , indices ):
810832 """Not do"""
@@ -903,25 +925,18 @@ def init_pos_interpolator(self):
903925 self .yinterp = arange (self .y_bounds .shape [0 ])
904926
905927 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 ,
907929 self .N , self .is_circular (), self .x_size )
908930
909931 def get_pixels_in (self , contour ):
910932 (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 )
918934
919935 def normalize_x_indice (self , indices ):
920936 return indices % self .x_size
921937
922938 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 )
925940
926941 @property
927942 def xstep (self ):
@@ -1066,7 +1081,7 @@ def convolve_filter_with_dynamic_kernel(self, grid, kernel_func, lat_max=85, ext
10661081 t0 = datetime .now ()
10671082 if debug_active and len (dt ) > 0 :
10681083 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 " )
10701085
10711086
10721087 # 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):
14521467 lon , lat = vertices [:, 0 ], vertices [:, 1 ]
14531468 lon_min , lon_max = lon .min (), lon .max ()
14541469 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 )
14571472 if circular :
14581473 slice_x = (i_x0 - N ) % x_size , (i_x1 + N + 1 ) % x_size
14591474 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
14611476 slice_y = i_y0 - N , i_y1 + N + 1
14621477 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