2 warnings
.filterwarnings("ignore")
5 from datetime
import datetime
6 from scipy
import spatial
8 from random
import randint
12 Sorting a dictionary depending on the time number in seconds from January 1, 1970
14 :param data: dictionary of granules where each granule has a time_num key
15 :return: an array of dictionaries ordered by time_num key (seconds from January 1, 1970)
17 Developed in Python 2.7.15 :: Anaconda 4.5.10, on MACINTOSH.
18 Angel Farguell (angel.farguell@gmail.com), 2018-09-20
20 return sorted(data
.iteritems(), key
=lambda x
: x
[1]['time_num'])
22 def nearest_euclidean(lon
,lat
,lons
,lats
,bounds
):
24 Returns the longitude and latitude arrays interpolated using Euclidean distance
26 :param lon: 2D array of longitudes to look the nearest neighbours
27 :param lat: 2D array of latitudes to look the nearest neighbours
28 :param lons: 2D array of longitudes interpolating to
29 :param lats: 2D array of latitudes interpolating to
30 :param bounds: array of 4 bounding boundaries where to interpolate: [minlon maxlon minlat maxlat]
31 :return ret: tuple with a 2D array of longitudes and 2D array of latitudes interpolated from (lon,lat) to (lons,lats)
33 Developed in Python 2.7.15 :: Anaconda 4.5.10, on MACINTOSH.
34 Angel Farguell (angel.farguell@gmail.com), 2018-09-20
36 vlon
=np
.reshape(lon
,np
.prod(lon
.shape
))
37 vlat
=np
.reshape(lat
,np
.prod(lat
.shape
))
38 rlon
=np
.zeros(vlon
.shape
)
39 rlat
=np
.zeros(vlat
.shape
)
40 for k
in range(0,len(vlon
)):
41 if (vlon
[k
]>bounds
[0]) and (vlon
[k
]<bounds
[1]) and (vlat
[k
]>bounds
[2]) and (vlat
[k
]<bounds
[3]):
42 dist
=np
.square(lons
-vlon
[k
])+np
.square(lats
-vlat
[k
])
43 ii
,jj
= np
.unravel_index(dist
.argmin(),dist
.shape
)
49 ret
=(np
.reshape(rlon
,lon
.shape
),np
.reshape(rlat
,lat
.shape
))
53 def nearest_scipy(lon
,lat
,stree
,bounds
):
55 Returns the coordinates interpolated from (lon,lat) to (lons,lats) and the value of the indices where NaN values
57 :param lon: 2D array of longitudes to look the nearest neighbours
58 :param lat: 2D array of latitudes to look the nearest neighbours
59 :param lons: 2D array of longitudes interpolating to
60 :param lats: 2D array of latitudes interpolating to
61 :param dub: optional, distance upper bound to look for the nearest neighbours
62 :return ret: A tuple with a 2D array of coordinates interpolated from (lon,lat) to (lons,lats) and the value of the indices where NaN values
64 Developed in Python 2.7.15 :: Anaconda 4.5.10, on MACINTOSH.
65 Angel Farguell (angel.farguell@gmail.com), 2018-09-20
67 vlon
=np
.reshape(lon
,np
.prod(lon
.shape
))
68 vlat
=np
.reshape(lat
,np
.prod(lat
.shape
))
69 vlonlat
=np
.column_stack((vlon
,vlat
))
70 M
=(vlon
>bounds
[0])*(vlon
<bounds
[1])*(vlat
>bounds
[2])*(vlat
<bounds
[3])
72 inds
=np
.array(stree
.query(vlonlat
)[1])
76 def distance_upper_bound(dx
,dy
):
78 Computes the distance upper bound
80 :param dx: array of two elements with fire mesh grid resolutions
81 :param dy: array of two elements with satellite grid resolutions
82 :return d: distance upper bound to look for the nearest neighbours
84 Developed in Python 2.7.15 :: Anaconda 4.5.10, on MACINTOSH.
85 Angel Farguell (angel.farguell@gmail.com), 2018-09-20
87 rx
=np
.sqrt(dx
[0]**2+dx
[1]**2)
88 ry
=np
.sqrt(dy
[0]**2+dy
[1]**2)
92 def neighbor_indices(indices
,shape
,d
=2):
94 Computes all the neighbor indices from an indice list
96 :param indices: list of coordinates in a 1D array
97 :param shape: array of two elements with satellite grid size
98 :param d: optional, distance of the neighbours
99 :return ind: Returns a numpy array with the indices and the neighbor indices in 1D array
101 Developed in Python 2.7.15 :: Anaconda 4.5.10, on MACINTOSH.
102 Angel Farguell (angel.farguell@gmail.com), 2018-09-20
104 # Width and Length of the 2D grid
107 # 2D indices of the 1D indices
108 I
=[[np
.mod(ind
,w
),ind
/w
] for ind
in indices
]
109 # All the combinations (x,y) for all the neighbor points from x-d to x+d and y-d to y+d
110 N
=np
.concatenate([np
.array(list(itertools
.product(range(max(i
[0]-d
,0),min(i
[0]+d
+1,w
)),range(max(i
[1]-d
,0),min(i
[1]+d
+1,l
))))) for i
in I
])
111 # Recompute the 1D indices of the 2D coordinates inside the 2D domain
112 ret
=np
.array([x
[0]+w
*x
[1] for x
in N
])
113 # Sort them and take each indice once
114 ind
=sorted(np
.unique(ret
))
117 def neighbor_indices_pixel(lons
,lats
,lon
,lat
,scan
,track
):
119 Computes all the neighbor indices depending on the size of the pixel
121 :param lons: one dimensional array of the fire mesh longitud coordinates
122 :param lats: one dimensional array of the fire mesh latitude coordinates
123 :param lon: one dimensional array of the fire detection longitud coordinates
124 :param lat: one dimensional array of the fire detection latitude coordinates
125 :param scan: one dimensional array of the fire detection along-scan sizes
126 :param track: one dimensional array of the fire detection along-track sizes
127 :return ll: returns a one dimensional logical array with the indices in the fire mesh including pixel neighbours
129 Developed in Python 2.7.15 :: Anaconda 4.5.10, on MACINTOSH.
130 Angel Farguell (angel.farguell@gmail.com), 2018-10-16
132 R
=6378 # Earth radius
133 km_lat
=180/(np
.pi
*R
) # 1km in degrees latitude
134 km_lon
=km_lat
/np
.cos(lat
*np
.pi
/180) # 1 km in longitude
135 # pixel sizes in degrees
138 # creating bounds for each fire detection (pixel vertexs)
139 bounds
=[[lon
[k
]-sqlon
[k
],lon
[k
]+sqlon
[k
],lat
[k
]-sqlat
[k
],lat
[k
]+sqlat
[k
]] for k
in range(len(lat
))]
140 # creating a logical array of indices in the fire mesh with the intersection of all the cases
141 ll
=np
.sum([np
.array(np
.logical_and(np
.logical_and(np
.logical_and(lons
>b
[0],lons
<b
[1]),lats
>b
[2]),lats
<b
[3])) for b
in bounds
],axis
=0).astype(bool)
144 def neighbor_indices_ellipse(lons
,lats
,lon
,lat
,scan
,track
,mm
=1):
146 Computes all the neighbor indices in an ellipse of radius the size of the pixel
148 :param lons: one dimensional array of the fire mesh longitud coordinates
149 :param lats: one dimensional array of the fire mesh latitude coordinates
150 :param lon: one dimensional array of the fire detection longitud coordinates
151 :param lat: one dimensional array of the fire detection latitude coordinates
152 :param scan: one dimensional array of the fire detection along-scan sizes
153 :param track: one dimensional array of the fire detection along-track sizes
154 :param mm: constant of magnitude of the ellipse, default mm=1 (ellipse inscribed in the pixel)
155 :return ll: returns a one dimensional logical array with the indices in the fire mesh including pixel neighbours
157 Developed in Python 2.7.15 :: Anaconda 4.5.10, on MACINTOSH.
158 Angel Farguell (angel.farguell@gmail.com), 2018-10-18
160 R
=6378 # Earth radius
161 km_lat
=180/(np
.pi
*R
) # 1km in degrees latitude
162 km_lon
=km_lat
/np
.cos(lat
*np
.pi
/180) # 1 km in longitude
163 # pixel sizes in degrees
166 # creating the coordinates in the center of the ellipse
167 C
=[[(np
.array(lons
)-lon
[k
])/sqlon
[k
],(np
.array(lats
)-lat
[k
])/sqlat
[k
]] for k
in range(len(lat
))]
168 # creating a logical array of indices in the fire mesh with the intersection of all the cases
169 ll
=np
.sum([np
.array((np
.square(c
[0])+np
.square(c
[1]))<=mm
) for c
in C
],axis
=0).astype(bool)
172 def neighbor_indices_ball(tree
,indices
,shape
,d
=2):
174 Computes all the neighbor indices from an indice list in a grid of indices defined through a cKDTree
176 :param indices: list of coordinates in a 1D array
177 :param shape: array of two elements with satellite grid size
178 :param d: optional, distance of the neighbours computed as: sqrt(2*d**2)
179 :return ind: returns a numpy array with the indices and the neighbor indices in 1D array respect to the grid used in the tree
181 Developed in Python 2.7.15 :: Anaconda 4.5.10, on MACINTOSH.
182 Angel Farguell (angel.farguell@gmail.com), 2018-09-20
184 # Width of the 2D grid
186 # 2D indices of the 1D indices
187 I
=[[np
.mod(ind
,w
),ind
/w
] for ind
in indices
]
189 radius
=np
.sqrt(2*d
**2)
190 # Request all the neighbors in a radius "radius"
191 N
=tree
.query_ball_point(I
,r
=radius
)
192 # Return an unique and sorted array of 1D indices (indices pointing to the grid used for the tree)
193 ind
=sorted(np
.unique(np
.concatenate(N
)))
196 if __name__
== "__main__":
198 # Initialization of grids
203 lons
=np
.repeat(x
[np
.newaxis
,:],x
.shape
[0], axis
=0)
205 lats
=np
.repeat(x
[np
.newaxis
,:],x
.shape
[0], axis
=0).T
206 bounds
=[lons
.min(),lons
.max(),lats
.min(),lats
.max()]
209 print 'dim_mesh=(%d,%d)' % lons
.shape
210 y
=np
.arange(-N
*1.432,2.432*N
,dy1
)
211 lon
=np
.repeat(y
[np
.newaxis
,:],y
.shape
[0], axis
=0)
212 y
=np
.arange(-N
*1.432,2.432*N
,dy2
)
213 lat
=np
.repeat(y
[np
.newaxis
,:],y
.shape
[0], axis
=0)
214 print 'dim_data=(%d,%d)' % (lon
.shape
[0], lat
.shape
[0])
216 # Result by Euclidean distance
217 print '>>Euclidean approax<<'
218 (rlon
,rlat
)=nearest_euclidean(lon
,lat
,lons
,lats
,bounds
)
219 rlon
=np
.reshape(rlon
,np
.prod(lon
.shape
))
220 rlat
=np
.reshape(rlat
,np
.prod(lat
.shape
))
221 vlonlatm
=np
.column_stack((rlon
,rlat
))
224 print 'Elapsed time: %ss.' % str(t_final
-t_init
)
226 # Result by scipy.spatial.cKDTree function
227 vlons
=np
.reshape(lons
,np
.prod(lons
.shape
))
228 vlats
=np
.reshape(lats
,np
.prod(lats
.shape
))
229 vlonlats
=np
.column_stack((vlons
,vlats
))
231 stree
=spatial
.cKDTree(vlonlats
)
232 (inds
,K
)=nearest_scipy(lon
,lat
,stree
,bounds
)
233 vlonlatm2
=np
.empty((np
.prod(lon
.shape
),2))
235 vlons
=np
.reshape(lons
,np
.prod(lons
.shape
))
236 vlats
=np
.reshape(lats
,np
.prod(lats
.shape
))
237 vlonlats
=np
.column_stack((vlons
,vlats
))
238 vlonlatm2
[K
]=vlonlats
[inds
]
242 print 'Elapsed time: %ss.' % str(t_ffinal
-t_final
)
245 print 'Same results?'
246 print (np
.isclose(vlonlatm
,vlonlatm2
) | np
.isnan(vlonlatm
) | np
.isnan(vlonlatm2
)).all()
248 # Testing neighbor indices
251 ind
=sorted(np
.unique([randint(0,np
.prod(shape
)-1) for i
in range(0,N
)]))
252 #ind=[0,3,shape[0]/2+shape[1]/2*shape[0],np.prod(shape)-1]
254 ne
=neighbor_indices(ind
,shape
,d
=8)
256 print '1D neighbors:'
257 print 'elapsed time: %ss.' % str(t_final
-t_init
)
258 grid
=np
.array(list(itertools
.product(np
.array(range(0,shape
[0])),np
.array(range(0,shape
[1])))))
259 tree
=spatial
.cKDTree(grid
)
261 kk
=neighbor_indices_ball(tree
,ind
,shape
,d
=8)
263 nse
=[x
[0]+x
[1]*shape
[0] for x
in grid
[kk
]]
264 print '1D neighbors scipy:'
265 print 'elapsed time: %ss.' % str(t_final
-t_init
)
267 print np
.setdiff1d(ne
,nse
)
268 print np
.setdiff1d(nse
,ne
)