Beispiel #1
0
def make_netcdf_cube_voronoi(cs_obj, fpath):
    up_size = cs_obj.up_size

    # max number of voronoi vertices
    # 6 if nomal, 8 if ne6np4 
    corner_max_size = 6

    center_xyzs = np.zeros((up_size,3), 'f8')
    center_latlons = np.zeros((up_size,2), 'f8')
    corner_xyzs = np.zeros((up_size,corner_max_size,3), 'f8')
    corner_latlons = np.zeros((up_size,corner_max_size,2), 'f8')
    corner_sizes = np.zeros(up_size, 'i4')
    corner_areas = np.zeros(up_size, 'f8')

    for dst in range(up_size):
        center_xyzs[dst,:] = cs_obj.xyzs[dst]
        center_latlons[dst,:] = cs_obj.latlons[dst]

        voronoi_xyzs = cs_obj.get_voronoi(dst)
        for i, corner_xyz in enumerate(voronoi_xyzs):
            corner_xyzs[dst,i,:] = corner_xyz
            corner_latlons[dst,i,:] = xyz2latlon(*corner_xyz)

        corner_sizes[dst] = len(voronoi_xyzs)
        corner_areas[dst] = area_polygon(voronoi_xyzs)


    #------------------------------------------------------------
    # Save as NetCDF
    #------------------------------------------------------------
    ncf = nc.Dataset(fpath, 'w', format='NETCDF3_64BIT') # for pnetcdf
    ncf.description = 'Voronoi diagram on the Cubed-sphere'
    ncf.coordinates = 'cartesian'

    ncf.rotated = str(cs_obj.rotated).lower()
    ncf.ne = cs_obj.ne
    ncf.ngq = cs_obj.ngq
    ncf.ep_size = cs_obj.ep_size
    ncf.up_size = up_size

    ncf.createDimension('up_size', up_size)
    ncf.createDimension('corner_max_size', corner_max_size)
    ncf.createDimension('3', 3)
    ncf.createDimension('2', 2)

    vcenter_xyzs = ncf.createVariable('center_xyzs', 'f8', ('up_size','3'))
    vcenter_lls = ncf.createVariable('center_latlons', 'f8', ('up_size','2'))
    vcorner_xyzs = ncf.createVariable('corner_xyzs', 'f8', ('up_size','corner_max_size','3'))
    vcorner_lls = ncf.createVariable('corner_latlons', 'f8', ('up_size','corner_max_size','2'))
    vcorner_sizes = ncf.createVariable('corner_sizes', 'i4', ('up_size',))
    vcorner_areas = ncf.createVariable('corner_areas', 'f8', ('up_size',))

    vcenter_xyzs[:] = center_xyzs[:]
    vcenter_lls[:] = center_latlons[:]
    vcorner_xyzs[:] = corner_xyzs[:]
    vcorner_lls[:] = corner_latlons[:]
    vcorner_sizes[:] = corner_sizes[:]
    vcorner_areas[:] = corner_areas[:]

    ncf.close()
def test_ll_voronoi_area():
    """
    LatlonGridRemap.get_voronoi(): check the sphere area
    """
    from cube_remap import LatlonGridRemap
    from util.geometry.sphere import area_polygon
    from math import fsum, pi
    from util.convert_coord.cart_ll import latlon2xyz

    nlat, nlon = 90, 180
    # nlat, nlon = 180, 360
    # nlat, nlon = 360, 720
    # nlat, nlon = 720, 1440
    ll_obj = LatlonGridRemap(nlat, nlon)

    area_list = list()
    for idx in xrange(ll_obj.nsize):
        # latlons = ll_obj.get_voronoi(idx)
        # xyzs = [latlon2xyz(*latlon) for latlon in latlons]
        xyzs = ll_obj.get_voronoi(idx)
        area_list.append(area_polygon(xyzs))

    aa_equal(fsum(area_list), 4 * pi, 12)

    """
def test_cs_voronoi_area():
    """
    CubeGridRemap.get_voronoi(): check the sphere area, ne=3
    """
    from cube_remap import CubeGridRemap
    from util.geometry.sphere import area_polygon
    from math import fsum, pi
    from util.convert_coord.cart_cs import xyp2xyz

    ne, ngq = 3, 4
    rotated = False
    cube = CubeGridRemap(ne, ngq, rotated)

    area_list = list()
    for uid in xrange(cube.up_size):
        # xy_vts, vor_obj = cube.get_voronoi_scipy(uid)
        # xyzs = [xyp2xyz(x,y,1) for x,y in xy_vts]
        # area_list.append( area_polygon(xyzs) )

        xyzs = cube.get_voronoi(uid)
        area_list.append(area_polygon(xyzs))

    aa_equal(fsum(area_list), 4 * pi, 15)

    """
Beispiel #4
0
    def make_remap_matrix(self, debug=False):
        dst_obj = self.dst_obj
        src_obj = self.src_obj

        dsw_dict = dict()       # {dst:[(s,w),(s,w),...],...}
        if debug: ipoly_dict = dict()  # {dst:[(src,ipoly,iarea),...],..}
        
        for dst, (lat0,lon0) in enumerate(dst_obj.latlons):
            dst_poly = dst_obj.get_voronoi(dst)
            dst_area = area_polygon(dst_poly)
            inout = pt_in_polygon(dst_poly, latlon2xyz(lat0,lon0))
            if inout != 'in':
                print('dst',dst)
                print('latlon_in_poly?', inout)

            idx1, idx2, idx3, idx4 = src_obj.get_surround_idxs(lat0, lon0)
            candidates = set([idx1, idx2, idx3, idx4])
            if -1 in candidates: candidates.remove(-1)
            checked_srcs = set()

            dsw_dict[dst] = list()
            while len(candidates) > 0:
                #print('\t', checked_srcs)
                src = candidates.pop()
                src_poly = src_obj.get_voronoi(src)

                ipoly = intersect_two_polygons(dst_poly, src_poly)
                checked_srcs.add(src)

                if ipoly != None:
                    iarea = area_polygon(ipoly)
                    area_ratio = iarea/dst_area

                    if area_ratio > 1e-10:
                        dsw_dict[dst].append( (src, area_ratio) )
                        nbrs = set(src_obj.get_neighbors(src))
                        candidates.update(nbrs - checked_srcs)

                        if debug: ipoly_dict[dst].append( (src,ipoly,iarea) )

        if debug: self.save_netcdf_ipoly(ipoly_dict)

        return self.make_remap_matrix_from_dsw_dict(dsw_dict)
Beispiel #5
0
    def make_remap_matrix_mpi(self, debug=False):
        from mpi4py import MPI

        comm = MPI.COMM_WORLD
        nproc = comm.Get_size()
        myrank = comm.Get_rank()

        if nproc == 1:
            return self.make_remap_matrix()


        dst_obj = self.dst_obj
        src_obj = self.src_obj
        chunk_size = dst_obj.nsize//nproc//10

        dsw_dict = dict()       # {dst:[(src,wgt),(src,wgt),...],...}

        if debug:
            ipoly_dict = dict()  # {dst:[(src,ipoly,iarea),...],..}
        

        if myrank == 0:
            start = 0
            while start < dst_obj.nsize:
                rank = comm.recv(source=MPI.ANY_SOURCE, tag=0)
                comm.send(start, dest=rank, tag=10)
                start += chunk_size

            for i in range(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)

                if debug:
                    slave_ipoly_dict = comm.recv(source=rank, tag=30)
                    ipoly_dict.update(slave_src_poly_dict)
                    self.save_netcdf_ipoly(ipoly_dict)

            return self.make_remap_matrix_from_dsw_dict(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 {} quit.".format(myrank))
                    comm.send(dsw_dict, dest=0, tag=20)

                    if debug:
                        comm.send(ipoly_dict, dest=0, tag=30)

                    return None, None, None

                start = msg
                end = start + chunk_size
                end = dst_obj.nsize if end > dst_obj.nsize else end
                print("rank {}: {} ~ {} ({} %%)".format(myrank, start, end, end/dst_obj.nsize*100))

                for dst in range(start,end):
                    lat0, lon0 = dst_obj.latlons[dst]
                    dst_poly = dst_obj.get_voronoi(dst)
                    dst_area = area_polygon(dst_poly)

                    idx1, idx2, idx3, idx4 = src_obj.get_surround_idxs(lat0, lon0)
                    candidates = set([idx1, idx2, idx3, idx4])
                    if -1 in candidates: candidates.remove(-1)
                    checked_srcs = set()

                    dsw_dict[dst] = list()

                    if debug:
                        ipoly_dict[dst] = list()

                    while len(candidates) > 0:
                        src = candidates.pop()
                        src_poly = src_obj.get_voronoi(src)

                        ipoly = intersect_two_polygons(dst_poly, src_poly)
                        checked_srcs.add(src)

                        if ipoly != None:
                            iarea = area_polygon(ipoly)
                            area_ratio = iarea/dst_area

                            if area_ratio > 1e-10:
                                dsw_dict[dst].append( (src, area_ratio) )
                                nbrs = set(src_obj.get_neighbors(src))
                                candidates.update(nbrs - checked_srcs)

                                if debug:
                                    ipoly_dict[dst].append( (src,ipoly,iarea) )