def get_voronoi(self, uid): rlat, rlon = self.latlons[uid] nbrs = [gid for gid in self.nbrs[uid] if gid != -1] latlon_nbrs = [self.latlons[self.uids[gid]] for gid in nbrs] x0, y0 = latlon2xyp(rlat,rlon,rlat,rlon)[1] xy_nbrs = [latlon2xyp(lat,lon,rlat,rlon)[1] for lat,lon in latlon_nbrs] #------------------------------------------ # Generate a Voronoi diagram vor = Voronoi([(x0,y0)]+xy_nbrs) #------------------------------------------ # Remove non-neighbor points ridge_pts = [sorted(pair) for pair in vor.ridge_points] xy_nbrs2 = [xy_nbrs[i] for i in xrange(len(nbrs)) \ if [0,i+1] in ridge_pts] if len(xy_nbrs2) < len(nbrs): vor = Voronoi([(x0,y0)]+xy_nbrs2) #for nbr, xy in zip(nbrs, xy_nbrs2): # print nbr, self.gq_indices[nbr], xy #------------------------------------------ # Sort the vertices ridge_pts = [sorted(pair) for pair in vor.ridge_points] vidxs = list() for inb in xrange(1,len(xy_nbrs2)+1): seq = ridge_pts.index([0,inb]) v1, v2 = vor.ridge_vertices[seq] if inb == 1: vidxs.append([v1,v2]) elif inb == 2: vidx0 = np.intersect1d(vidxs[0], [v1,v2])[0] vidx1 = v1 if vidx0 == v2 else v2 vidxs[0] = vidx0 vidxs.append(vidx1) else: vidx = v1 if vidxs[-1] == v2 else v2 vidxs.append(vidx) xy_vertices = vor.vertices[vidxs] return xy_vertices, vor
def make_dsw_dict_ll2cs(self): cs_obj = self.cs_obj ll_obj = self.ll_obj dsw_dict = dict() # {dst:[(s,w),(s,w),...],...} for dst, (rlat,rlon) in enumerate(cs_obj.latlons): #print dst dst_xy_vertices, vor_obj = cs_obj.get_voronoi(dst) dst_poly = Polygon(dst_xy_vertices) idx1, idx2, idx3, idx4 = ll_obj.get_surround_idxs(rlat, rlon) candidates = set([idx1, idx2, idx3, idx4]) if -1 in candidates: candidates.remove(-1) used_srcs = set() dsw_dict[dst] = list() while len(candidates) > 0: #print '\t', used_srcs src = candidates.pop() ll_vertices = ll_obj.get_voronoi(src) src_xy_vertices = [latlon2xyp(lat,lon,rlat,rlon)[1] \ for lat,lon in ll_vertices] src_poly = Polygon(src_xy_vertices) ipoly = dst_poly.intersection(src_poly) area_ratio = ipoly.area/dst_poly.area if area_ratio > 1e-10: dsw_dict[dst].append( (src, area_ratio) ) used_srcs.add(src) nbrs = set(ll_obj.get_neighbors(src)) candidates.update(nbrs - used_srcs) return dsw_dict
def make_dsw_dict_ll2cs_mpi(self): from mpi4py import MPI comm = MPI.COMM_WORLD nproc = comm.Get_size() myrank = comm.Get_rank() cs_obj = self.cs_obj ll_obj = self.ll_obj chunk_size = cs_obj.up_size//nproc//10 dsw_dict = dict() # {dst:[(s,w),(s,w),...],...} if myrank == 0: start = 0 while start < cs_obj.up_size: rank = comm.recv(source=MPI.ANY_SOURCE, tag=0) comm.send(start, dest=rank, tag=10) start += chunk_size for i in xrange(nproc-1): rank = comm.recv(source=MPI.ANY_SOURCE, tag=0) comm.send('quit', dest=rank, tag=10) slave_dsw_dict = comm.recv(source=rank, tag=20) dsw_dict.update(slave_dsw_dict) return dsw_dict else: while True: comm.send(myrank, dest=0, tag=0) msg = comm.recv(source=0, tag=10) if msg == 'quit': print 'Slave rank %d quit.'%(myrank) comm.send(dsw_dict, dest=0, tag=20) return dsw_dict start = msg end = start + chunk_size end = cs_obj.up_size if end > cs_obj.up_size else end print 'rank %d: %d ~ %d'%(myrank, start, end) for dst in xrange(start,end): rlat, rlon = cs_obj.latlons[dst] dst_xy_vertices, vor_obj = cs_obj.get_voronoi(dst) dst_poly = Polygon(dst_xy_vertices) idx1, idx2, idx3, idx4 = ll_obj.get_surround_idxs(rlat, rlon) candidates = set([idx1, idx2, idx3, idx4]) if -1 in candidates: candidates.remove(-1) used_srcs = set() dsw_dict[dst] = list() while len(candidates) > 0: src = candidates.pop() ll_vertices = ll_obj.get_voronoi(src) src_xy_vertices = [latlon2xyp(lat,lon,rlat,rlon)[1] \ for lat,lon in ll_vertices] src_poly = Polygon(src_xy_vertices) ipoly = dst_poly.intersection(src_poly) area_ratio = ipoly.area/dst_poly.area if area_ratio > 1e-10: dsw_dict[dst].append( (src, area_ratio) ) used_srcs.add(src) nbrs = set(ll_obj.get_neighbors(src)) candidates.update(nbrs - used_srcs)