Exemple #1
0
    def __init__(self, lon1=180.0, lat1=0.0, lon2=180.0, lat2=0.0, **kwargs):
        """
        Basis vactors of the rotated coordinate system in the original coord system
        e1 = -p1/|p1|                   =>   row0
        e2 = -( p2 - (p1, p2) * p1) / |p2 - (p1, p2) * p1| #perpendicular to e1, and lies in
        the plane parallel to the plane (p1^p2)  => row1
        e3 = [p1,p2] / |[p1, p2]| , perpendicular to the plane (p1^p2)          => row2
        """

        self.lon1 = lon1
        self.lon2 = lon2
        self.lat1 = lat1
        self.lat2 = lat2

        self.mean_earth_radius_m_crcm5 = 0.637122e7  # mean earth radius used in the CRCM5 model for area calculation

        p1 = lat_lon.lon_lat_to_cartesian(lon1, lat1, R=1.0)
        p2 = lat_lon.lon_lat_to_cartesian(lon2, lat2, R=1.0)

        p1 = np.array(p1)
        p2 = np.array(p2)

        cross_prod = np.cross(p1, p2)
        dot_prod = np.dot(p1, p2)

        row0 = -np.array(p1) / np.sqrt(np.dot(p1, p1))
        e2 = (dot_prod * p1 - p2)
        row1 = e2 / np.sqrt(np.dot(e2, e2))
        row2 = cross_prod / np.sqrt(np.dot(cross_prod, cross_prod))
        self.rot_matrix = np.matrix([row0, row1, row2])
        assert isinstance(self.rot_matrix, np.matrix)
Exemple #2
0
    def __init__(self, file_path = "", var_name = "",
                 bathymetry_path = "/skynet3_rech1/huziy/NEMO_OFFICIAL/dev_v3_4_STABLE_2012/NEMOGCM/CONFIG/GLK_LIM3_Michigan/EXP00/bathy_meter.nc"):
        """
        :param file_path:
        :param var_name:
        :param bathymetry_path: used to mask land points
        """
        self.current_time_frame = -1
        self.var_name = var_name

        self.cube = iris.load_cube(file_path, constraint=iris.Constraint(cube_func=lambda c: c.var_name == var_name))
        self.lons, self.lats = cartography.get_xy_grids(self.cube)

        lons2d_gl, lats2d_gl = nemo_commons.get_2d_lons_lats_from_nemo(path=bathymetry_path)
        mask_gl = nemo_commons.get_mask(path=bathymetry_path)

        xs, ys, zs = lat_lon.lon_lat_to_cartesian(lons2d_gl.flatten(), lats2d_gl.flatten())
        xt, yt, zt = lat_lon.lon_lat_to_cartesian(self.lons.flatten(), self.lats.flatten())

        tree = cKDTree(list(zip(xs, ys, zs)))
        dists, indices = tree.query(list(zip(xt, yt, zt)))

        self.mask = mask_gl.flatten()[indices].reshape(self.lons.shape)


        self.nt = self.cube.shape[0]
        assert isinstance(self.cube, Cube)
        print(self.nt)
Exemple #3
0
    def get_data_from_file_interpolate_if_needed(self, the_path):

        the_path = str(the_path)

        if the_path.lower()[-3:] in ["cis", "nic"]:
            data = self._parse_nic_cis_data_file(the_path)
        else:
            data = self.get_data_from_path(the_path)

        if data.shape != (self.ncols_target, self.ncols_target):
            # The interpolation is needed
            domain_descr = data.shape
            if domain_descr not in self.domain_descr_to_kdtree:

                if domain_descr == (516, 510):
                    self.lons2d_other = np.flipud(np.loadtxt(self.path_to_other_lons)).transpose()
                    self.lats2d_other = np.flipud(np.loadtxt(self.path_to_other_lats)).transpose()
                else:
                    self.lons2d_other, self.lats2d_other = self._generate_grid_from_descriptor(domain_descr)

                xs, ys, zs = lat_lon.lon_lat_to_cartesian(self.lons2d_other.flatten(), self.lats2d_other.flatten())

                kdtree_other = cKDTree(data=list(zip(xs, ys, zs)))

                self.domain_descr_to_kdtree[data.shape] = kdtree_other

            kdtree_other = self.domain_descr_to_kdtree[data.shape]
            xt, yt, zt = lat_lon.lon_lat_to_cartesian(self.lons2d_target.flatten(), self.lats2d_target.flatten())
            dsts, inds = kdtree_other.query(list(zip(xt, yt, zt)))


            return data.flatten()[inds].reshape(self.lons2d_target.shape)

        else:
            return data
Exemple #4
0
def plot_difference(basemap,
                    lons1, lats1, data1, label1,
                    lons2, lats2, data2, label2,
                    base_folder="/skynet3_rech1/huziy/veg_fractions/"
                    ):
    xs, ys, zs = lat_lon.lon_lat_to_cartesian(lons2.flatten(), lats2.flatten())
    xt, yt, zt = lat_lon.lon_lat_to_cartesian(lons1.flatten(), lats1.flatten())

    ktree = cKDTree(list(zip(xs, ys, zs)))
    dists, inds = ktree.query(list(zip(xt, yt, zt)))

    # Calculate differences
    diff_dict = {}
    for key, the_field in data2.items():
        diff_dict[key] = the_field.flatten()[inds].reshape(data1[key].shape) - data1[key]

    x, y = basemap(lons1, lats1)
    imname = "sand_clay_diff_{0}-{1}.jpeg".format(label2, label1)
    impath = os.path.join(base_folder, imname)
    plot_sand_and_clay_diff(x, y, basemap, diff_dict["SAND"], diff_dict["CLAY"],
                            out_image=impath)

    del diff_dict["SAND"], diff_dict["CLAY"]
    imname = "veg_fract_diff_{0}-{1}.jpeg".format(label2, label1)
    impath = os.path.join(base_folder, imname)
    plot_veg_fractions_diff(x, y, basemap, diff_dict,
                            out_image=impath)
Exemple #5
0
    def __init__(self, lon1=180.0, lat1=0.0, lon2=180.0, lat2=0.0, **kwargs):
        """
        Basis vactors of the rotated coordinate system in the original coord system
        e1 = -p1/|p1|                   =>   row0
        e2 = -( p2 - (p1, p2) * p1) / |p2 - (p1, p2) * p1| #perpendicular to e1, and lies in
        the plane parallel to the plane (p1^p2)  => row1
        e3 = [p1,p2] / |[p1, p2]| , perpendicular to the plane (p1^p2)          => row2
        """

        self.lon1 = lon1
        self.lon2 = lon2
        self.lat1 = lat1
        self.lat2 = lat2

        self.mean_earth_radius_m_crcm5 = 0.637122e7  # mean earth radius used in the CRCM5 model for area calculation

        p1 = lat_lon.lon_lat_to_cartesian(lon1, lat1, R=1.0)
        p2 = lat_lon.lon_lat_to_cartesian(lon2, lat2, R=1.0)

        p1 = np.array(p1)
        p2 = np.array(p2)

        cross_prod = np.cross(p1, p2)
        dot_prod = np.dot(p1, p2)

        row0 = -np.array(p1) / np.sqrt(np.dot(p1, p1))
        e2 = (dot_prod * p1 - p2)
        row1 = e2 / np.sqrt(np.dot(e2, e2))
        row2 = cross_prod / np.sqrt(np.dot(cross_prod, cross_prod))
        self.rot_matrix = np.matrix([row0, row1, row2])
        assert isinstance(self.rot_matrix, np.matrix)
def main(in_file: Path, target_grid_file: Path, out_dir: Path=None):

    if out_dir is not None:
        out_dir.mkdir(exist_ok=True)
        out_file = out_dir / (in_file.name + "_interpolated")
    else:
        out_file = in_file.parent / (in_file.name + "_interpolated")

    if out_file.exists():
        print(f"Skipping {in_file}, output already exists ({out_file})")
        return

    with xarray.open_dataset(target_grid_file) as ds_grid:
        lons, lats = ds_grid["lon"][:].values, ds_grid["lat"][:].values

        xt, yt, zt = lat_lon.lon_lat_to_cartesian(lons.flatten(), lats.flatten())

        with xarray.open_dataset(in_file) as ds_in:

            lons_s, lats_s = ds_in["lon"][:].values, ds_in["lat"][:].values
            xs, ys, zs = lat_lon.lon_lat_to_cartesian(lons_s.flatten(), lats_s.flatten())

            ktree = KDTree(list(zip(xs, ys, zs)))
            dists, inds = ktree.query(list(zip(xt, yt, zt)), k=1)




            # resample to daily
            ds_in_r = ds_in.resample(t="1D", keep_attrs=True).mean()


            ds_out = xarray.Dataset()
            for vname, var in ds_grid.variables.items():
                ds_out[vname] = var[:]

            ds_out["t"] = ds_in_r["t"][:]


            for vname, var in ds_in_r.variables.items():

                assert isinstance(var, xarray.Variable)

                var = var.squeeze()

                # only interested in (t, x, y) fields
                if var.ndim != 3:
                    print(f"skipping {vname}")
                    continue

                if vname.lower() not in ["t", "time", "lon", "lat"]:
                    print(f"Processing {vname}")
                    var_interpolated = [var[ti].values.flatten()[inds].reshape(lons.shape) for ti in range(var.shape[0])]
                    ds_out[vname] = xarray.DataArray(
                        var_interpolated, dims=("t", "x", "y"),
                        attrs=var.attrs,
                    )

            ds_out.to_netcdf(out_file)
Exemple #7
0
def main(in_file: Path, target_grid_file: Path, out_dir: Path=None):

    if out_dir is not None:
        out_dir.mkdir(exist_ok=True)
        out_file = out_dir / (in_file.name + "_interpolated")
    else:
        out_file = in_file.parent / (in_file.name + "_interpolated")

    if out_file.exists():
        print(f"Skipping {in_file}, output already exists ({out_file})")
        return

    with xarray.open_dataset(target_grid_file) as ds_grid:
        lons, lats = ds_grid["lon"][:].values, ds_grid["lat"][:].values

        xt, yt, zt = lat_lon.lon_lat_to_cartesian(lons.flatten(), lats.flatten())

        with xarray.open_dataset(in_file) as ds_in:

            lons_s, lats_s = ds_in["lon"][:].values, ds_in["lat"][:].values
            xs, ys, zs = lat_lon.lon_lat_to_cartesian(lons_s.flatten(), lats_s.flatten())

            ktree = KDTree(list(zip(xs, ys, zs)))
            dists, inds = ktree.query(list(zip(xt, yt, zt)), k=1)




            # resample to daily
            ds_in_r = ds_in.resample(t="1D", keep_attrs=True).mean()


            ds_out = xarray.Dataset()
            for vname, var in ds_grid.variables.items():
                ds_out[vname] = var[:]

            ds_out["t"] = ds_in_r["t"][:]


            for vname, var in ds_in_r.variables.items():

                assert isinstance(var, xarray.Variable)

                var = var.squeeze()

                # only interested in (t, x, y) fields
                if var.ndim != 3:
                    print(f"skipping {vname}")
                    continue

                if vname.lower() not in ["t", "time", "lon", "lat"]:
                    print(f"Processing {vname}")
                    var_interpolated = [var[ti].values.flatten()[inds].reshape(lons.shape) for ti in range(var.shape[0])]
                    ds_out[vname] = xarray.DataArray(
                        var_interpolated, dims=("t", "x", "y"),
                        attrs=var.attrs,
                    )

            ds_out.to_netcdf(out_file)
    def read_and_interpolate_homa_data(self, path="", start_year=None, end_year=None, season_to_months=None):
        """
        :param path:
        :param target_cube:
        """
        import pandas as pd

        ds = Dataset(path)
        sst = ds.variables["sst"][:]

        # read longitudes and latitudes from a file
        lons_source = ds.variables["lon"][:]
        lats_source = ds.variables["lat"][:]



        month_to_season = defaultdict(lambda: "no-season")

        for seas, mths in season_to_months.items():
            for m in mths:
                month_to_season[m] = seas


        # time variable
        time_var = ds.variables["time"]
        dates = num2date(time_var[:], time_var.units)

        if hasattr(sst, "mask"):
            sst[sst.mask] = np.nan

        panel = pd.Panel(data=sst, items=dates, major_axis=range(sst.shape[1]), minor_axis=range(sst.shape[2]))



        seasonal_sst = panel.groupby(
            lambda d: (d.year, month_to_season[d.month]), axis="items").mean()


        # source grid
        xs, ys, zs = lat_lon.lon_lat_to_cartesian(lons_source.flatten(), lats_source.flatten())
        kdtree = cKDTree(data=list(zip(xs, ys, zs)))

        # target grid
        xt, yt, zt = lat_lon.lon_lat_to_cartesian(self.lons.flatten(), self.lats.flatten())

        dists, inds = kdtree.query(list(zip(xt, yt, zt)))



        assert isinstance(seasonal_sst, pd.Panel)

        result = {}
        for the_year in range(start_year, end_year + 1):
            result[the_year] = {}
            for the_season in list(season_to_months.keys()):
                the_mean = seasonal_sst.select(lambda item: item == (the_year, the_season), axis="items")
                result[the_year][the_season] = the_mean.values.flatten()[inds].reshape(self.lons.shape)

        return result
def main(dfs_var_name="t2", cru_var_name="tmp",
         dfs_folder="/home/huziy/skynet3_rech1/NEMO_OFFICIAL/DFS5.2_interpolated",
         cru_file = "data/cru_data/CRUTS3.1/cru_ts_3_10.1901.2009.tmp.dat.nc"):

    if not os.path.isdir(NEMO_IMAGES_DIR):
        os.mkdir(NEMO_IMAGES_DIR)

    #year range is inclusive [start_year, end_year]
    start_year = 1981
    end_year = 2009

    season_name_to_months = OrderedDict([
        ("Winter", (1, 2, 12)),
        ("Spring", list(range(3, 6))),
        ("Summer", list(range(6, 9))),
        ("Fall", list(range(9, 12)))])

    cru_t_manager = CRUDataManager(var_name=cru_var_name, path=cru_file)
    cru_lons, cru_lats = cru_t_manager.lons2d, cru_t_manager.lats2d
    #get seasonal means (CRU)
    season_to_mean_cru = cru_t_manager.get_seasonal_means(season_name_to_months=season_name_to_months,
                                                          start_year=start_year,
                                                          end_year=end_year)
    #get seasonal means Drakkar
    dfs_manager = DFSDataManager(folder_path=dfs_folder, var_name=dfs_var_name)
    season_to_mean_dfs = dfs_manager.get_seasonal_means(season_name_to_months=season_name_to_months,
                                                        start_year=start_year,
                                                        end_year=end_year)

    dfs_lons, dfs_lats = dfs_manager.get_lons_and_lats_2d()
    xt, yt, zt = lat_lon.lon_lat_to_cartesian(dfs_lons.flatten(), dfs_lats.flatten())
    xs, ys, zs = lat_lon.lon_lat_to_cartesian(cru_lons.flatten(), cru_lats.flatten())
    ktree = cKDTree(data=list(zip(xs, ys, zs)))
    dists, inds = ktree.query(list(zip(xt, yt, zt)))

    season_to_err = OrderedDict()
    for k in season_to_mean_dfs:
        interpolated_cru = season_to_mean_cru[k].flatten()[inds].reshape(dfs_lons.shape)
        if dfs_var_name.lower() == "t2":
            #interpolated_cru += 273.15
            season_to_mean_dfs[k] -= 273.15
        elif dfs_var_name.lower() == "precip":  # precipitation in mm/day
            season_to_mean_dfs[k] *= 24 * 60 * 60

        season_to_err[k] = season_to_mean_dfs[k] #- interpolated_cru

    season_indicator = "-".join(sorted(season_to_err.keys()))
    fig_path = os.path.join(NEMO_IMAGES_DIR, "{3}_errors_{0}-{1}_{2}_dfs.jpeg".format(start_year,
                                                                                  end_year,
                                                                                  season_indicator,
                                                                                  dfs_var_name))

    basemap = nemo_commons.get_default_basemap_for_glk(dfs_lons, dfs_lats, resolution="l")
    x, y = basemap(dfs_lons, dfs_lats)
    coords_and_basemap = {
        "basemap": basemap, "x": x, "y": y
    }

    plot_errors_in_one_figure(season_to_err, fig_path=fig_path, **coords_and_basemap)
def main(in_file="", out_file=None, target_grid: GridConfig = None):

    if out_file is None:
        out_file = "{}_interpolated".format(in_file)

    # input file
    dsin = Dataset(in_file)

    # output file
    with Dataset(out_file, "w") as dsout:
        # Copy dimensions
        for dname, the_dim in dsin.dimensions.items():
            print(dname, len(the_dim))

            # change the x and y dimensions only
            if dname not in ["x", "y"]:
                dsout.createDimension(
                    dname,
                    len(the_dim) if not the_dim.isunlimited() else None)
            elif dname == "x":
                dsout.createDimension(dname, target_grid.ni)
            elif dname == "y":
                dsout.createDimension(dname, target_grid.nj)

        lons_t, lats_t = [
            field.T
            for field in target_grid.get_lons_and_lats_of_gridpoint_centers()
        ]
        lons_s, lats_s = [dsin.variables[k][:] for k in ["nav_lon", "nav_lat"]]

        xs, ys, zs = lat_lon.lon_lat_to_cartesian(lons_s.flatten(),
                                                  lats_s.flatten())
        xt, yt, zt = lat_lon.lon_lat_to_cartesian(lons_t.flatten(),
                                                  lats_t.flatten())
        ktree = KDTree(list(zip(xs, ys, zs)))
        dists, inds = ktree.query(list(zip(xt, yt, zt)))

        # Copy variables
        for v_name, varin in dsin.variables.items():

            outVar = dsout.createVariable(v_name, varin.datatype,
                                          varin.dimensions)
            print(varin.datatype, v_name)

            # Copy variable attributes
            outVar.setncatts({k: varin.getncattr(k) for k in varin.ncattrs()})

            if "x" not in varin.dimensions:
                outVar[:] = varin[:]
            elif v_name == "nav_lon":
                outVar[:] = lons_t
            elif v_name == "nav_lat":
                outVar[:] = lats_t
            else:
                outVar[:] = interpolate_data_nn(varin[:], inds, lons_t.shape)

    # close the input file
    dsin.close()
def get_dataless_model_points_for_stations(station_list,
                                           accumulation_area_km2_2d,
                                           model_lons2d, model_lats2d, i_array,
                                           j_array):
    """
    returns a map {station => modelpoint} for comparison modeled streamflows with observed

    this uses exactly the same method for searching model points as one in diagnose_point (nc-version)

    """
    lons = model_lons2d[i_array, j_array]
    lats = model_lats2d[i_array, j_array]
    model_acc_area_1d = accumulation_area_km2_2d[i_array, j_array]
    npoints = 1
    result = {}

    x0, y0, z0 = lat_lon.lon_lat_to_cartesian(lons, lats)
    kdtree = cKDTree(list(zip(x0, y0, z0)))

    for s in station_list:
        # list of model points which could represent the station

        assert isinstance(s, Station)
        x, y, z = lat_lon.lon_lat_to_cartesian(s.longitude, s.latitude)
        dists, inds = kdtree.query((x, y, z), k=5)

        if npoints == 1:

            deltaDaMin = np.min(
                np.abs(model_acc_area_1d[inds] - s.drainage_km2))

            # this returns a  list of numpy arrays
            imin = np.where(
                np.abs(model_acc_area_1d[inds] -
                       s.drainage_km2) == deltaDaMin)[0][0]
            selected_cell_index = inds[imin]
            # check if difference in drainage areas is not too big less than 10 %

            print(s.river_name, deltaDaMin / s.drainage_km2)
            # if deltaDaMin / s.drainage_km2 > 0.2:
            #    continue

            mp = ModelPoint()
            mp.accumulation_area = model_acc_area_1d[selected_cell_index]
            mp.longitude = lons[selected_cell_index]
            mp.latitude = lats[selected_cell_index]
            mp.cell_index = selected_cell_index
            mp.distance_to_station = dists[imin]

            print("Distance to station: ", dists[imin])
            print("Model accumulation area: ", mp.accumulation_area)
            print("Obs accumulation area: ", s.drainage_km2)

            result[s] = mp
        else:
            raise Exception("npoints = {0}, is not yet implemented ...")
    return result
Exemple #12
0
    def interpolate_data_to_model_grid(self, model_lons_2d, model_lats_2d, data_obs):
        x0, y0, z0 = lat_lon.lon_lat_to_cartesian(model_lons_2d.flatten(), model_lats_2d.flatten())
        x, y, z = lat_lon.lon_lat_to_cartesian(self.lons2d.flatten(), self.lats2d.flatten())

        if self.ktree is None:
            self.ktree = KDTree(list(zip(x, y, z)))

        d, i = self.ktree.query(list(zip(x0, y0, z0)))

        return data_obs.flatten()[i].reshape(model_lons_2d.shape)
def get_dataless_model_points_for_stations(station_list, accumulation_area_km2_2d,
                                           model_lons2d, model_lats2d,
                                           i_array, j_array):
    """
    returns a map {station => modelpoint} for comparison modeled streamflows with observed

    this uses exactly the same method for searching model points as one in diagnose_point (nc-version)

    """
    lons = model_lons2d[i_array, j_array]
    lats = model_lats2d[i_array, j_array]
    model_acc_area_1d = accumulation_area_km2_2d[i_array, j_array]
    npoints = 1
    result = {}

    x0, y0, z0 = lat_lon.lon_lat_to_cartesian(lons, lats)
    kdtree = cKDTree(list(zip(x0, y0, z0)))

    for s in station_list:
        # list of model points which could represent the station

        assert isinstance(s, Station)
        x, y, z = lat_lon.lon_lat_to_cartesian(s.longitude, s.latitude)
        dists, inds = kdtree.query((x, y, z), k=5)

        if npoints == 1:

            deltaDaMin = np.min(np.abs(model_acc_area_1d[inds] - s.drainage_km2))

            # this returns a  list of numpy arrays
            imin = np.where(np.abs(model_acc_area_1d[inds] - s.drainage_km2) == deltaDaMin)[0][0]
            selected_cell_index = inds[imin]
            # check if difference in drainage areas is not too big less than 10 %

            print(s.river_name, deltaDaMin / s.drainage_km2)
            # if deltaDaMin / s.drainage_km2 > 0.2:
            #    continue

            mp = ModelPoint()
            mp.accumulation_area = model_acc_area_1d[selected_cell_index]
            mp.longitude = lons[selected_cell_index]
            mp.latitude = lats[selected_cell_index]
            mp.cell_index = selected_cell_index
            mp.distance_to_station = dists[imin]

            print("Distance to station: ", dists[imin])
            print("Model accumulation area: ", mp.accumulation_area)
            print("Obs accumulation area: ", s.drainage_km2)

            result[s] = mp
        else:
            raise Exception("npoints = {0}, is not yet implemented ...")
    return result
Exemple #14
0
def get_closest_value_for_point(lon0, lat0, lons_s, lats_s, data_s, tree=None):

    x, y, z = lat_lon.lon_lat_to_cartesian(lons_s.flatten(), lats_s.flatten())

    if tree is None:
        tree = KDTree(data=list(zip(x, y, z)))

    x0, y0, z0 = lat_lon.lon_lat_to_cartesian(lon0, lat0)

    d, i = tree.query((x0, y0, z0))

    return data_s.flatten()[i]
Exemple #15
0
    def interpolate_data_to_model_grid(self, model_lons_2d, model_lats_2d,
                                       data_obs):
        x0, y0, z0 = lat_lon.lon_lat_to_cartesian(model_lons_2d.flatten(),
                                                  model_lats_2d.flatten())
        x, y, z = lat_lon.lon_lat_to_cartesian(self.lons2d.flatten(),
                                               self.lats2d.flatten())

        if self.ktree is None:
            self.ktree = KDTree(list(zip(x, y, z)))

        d, i = self.ktree.query(list(zip(x0, y0, z0)))

        return data_obs.flatten()[i].reshape(model_lons_2d.shape)
def plot_depth_to_bedrock(basemap,
                          lons1,
                          lats1,
                          field1,
                          label1,
                          lons2,
                          lats2,
                          field2,
                          label2,
                          base_folder="/skynet3_rech1/huziy/veg_fractions/"):
    xs, ys, zs = lat_lon.lon_lat_to_cartesian(lons2.flatten(), lats2.flatten())
    xt, yt, zt = lat_lon.lon_lat_to_cartesian(lons1.flatten(), lats1.flatten())

    ktree = cKDTree(list(zip(xs, ys, zs)))
    dists, inds = ktree.query(list(zip(xt, yt, zt)))

    levels = np.arange(0, 5.5, 0.5)

    field2_interp = field2.flatten()[inds].reshape(field1.shape)

    field1 = np.ma.masked_where(field1 < 0, field1)
    field2_interp = np.ma.masked_where(field2_interp < 0, field2_interp)

    vmin = min(field1.min(), field2_interp.min())
    vmax = max(field1.max(), field2_interp.max())
    cmap = cm.get_cmap("BuPu", len(levels) - 1)
    bn = BoundaryNorm(levels, len(levels) - 1)
    x, y = basemap(lons1, lats1)
    imname = "depth_to_bedrock_{0}-{1}.jpeg".format(label2, label1)
    impath = os.path.join(base_folder, imname)
    fig = plt.figure(figsize=(6, 2.5))
    gs = GridSpec(1, 3, width_ratios=[1, 1, 0.05])
    ax = fig.add_subplot(gs[0, 0])
    basemap.pcolormesh(x, y, field1, vmin=vmin, vmax=vmax, cmap=cmap, norm=bn)
    basemap.drawcoastlines(linewidth=common_plot_params.COASTLINE_WIDTH)
    ax.set_title(label1)

    ax = fig.add_subplot(gs[0, 1])
    im = basemap.pcolormesh(x,
                            y,
                            field2_interp,
                            vmin=vmin,
                            vmax=vmax,
                            cmap=cmap,
                            norm=bn)
    basemap.drawcoastlines(linewidth=common_plot_params.COASTLINE_WIDTH)
    ax.set_title(label2)

    plt.colorbar(im, cax=fig.add_subplot(gs[0, 2]))
    fig.tight_layout()
    fig.savefig(impath, dpi=common_plot_params.FIG_SAVE_DPI)
Exemple #17
0
def get_timeseries_for_points(lons, lats, data_path="", varname="LD"):
    """
    return the list of timeseries for the points with the given coordinates,
    using the nearest neighbor interpolation
    :param varname: variable name
    :param data_path: path to the hdf5 file
    :param lons:
    :param lats:
    :return: pd.DataFrame with axes (time, point_index)
    """

    assert len(lons) == len(lats)

    df = None
    indices = None
    lk_fraction = None
    with tb.open_file(data_path) as h:
        var_table = h.get_node("/{}".format(varname))
        for i, row in enumerate(var_table):
            if df is None:
                df = pd.DataFrame(index=range(len(var_table)), columns=["date", ] + list(range(len(lons))))

                # calculate indices of the grid corresponding to the points
                bmp_info = get_basemap_info_from_hdf(file_path=data_path)
                """
                :type bmp_info: BasemapInfo
                """
                grid_lons, grid_lats = bmp_info.lons, bmp_info.lats

                x, y, z = lat_lon.lon_lat_to_cartesian(grid_lons.flatten(), grid_lats.flatten())

                ktree = KDTree(list(zip(x, y, z)))

                x1, y1, z1 = lat_lon.lon_lat_to_cartesian(lons, lats)

                dists, indices = ktree.query(list(zip(x1, y1, z1)))

                lk_fraction = get_array_from_file(path=data_path, var_name="lake_fraction")

            df.loc[i, :] = [datetime(row["year"], row["month"], row["day"], row["hour"]), ] + list(row["field"].flatten()[indices])

    # print lake fractions
    print(lk_fraction.flatten()[indices])
    print(sum(lk_fraction.flatten()[indices] > 0.05))

    df.set_index("date", inplace=True)
    df.sort_index(inplace=True)
    return df
Exemple #18
0
def get_flat_index(lon, lat, the_kd_tree ):
    """
    :type the_kd_tree: KDTree
    """
    x0,y0,z0 = lat_lon.lon_lat_to_cartesian(lon, lat)
    d, i = the_kd_tree.query((x0,y0,z0))
    return i
Exemple #19
0
    def get_kdtree(self, lons=None, lats=None, cache=True):
        """

        :param lons:
        :param lats:
        :param cache: if True then reuse the kdtree
        :return:
        """
        if lons is None:
            lons = self.lons
            lats = self.lats

        if lons is None:
            raise Exception(
                "The coordinates (lons and lats) are not yet set for the manager, please read some data first")

        if cache and self.kdtree is not None:
            return self.kdtree

        xs, ys, zs = lat_lon.lon_lat_to_cartesian(lons.flatten(), lats.flatten())
        kdtree = KDTree(list(zip(xs, ys, zs)))

        if cache:
            self.kdtree = kdtree

        return kdtree
Exemple #20
0
    def __init__(self, ax, basemap, lons2d, lats2d, ncVarDict, times,
                 start_date, end_date):
        """
        Plots a vertical profile at the point nearest to the clicked one
        :type ax: Axes
        """
        assert isinstance(ax, Axes)
        self.basemap = basemap
        assert isinstance(self.basemap, Basemap)

        self.lons_flat = lons2d.flatten()
        self.lats_flat = lats2d.flatten()
        self.ncVarDict = ncVarDict
        self.lons2d = lons2d
        self.lats2d = lats2d
        self.counter = 0
        self.ax = ax
        x, y, z = lat_lon.lon_lat_to_cartesian(lons2d.flatten(),
                                               lats2d.flatten())
        self.kdtree = KDTree(list(zip(x, y, z)))

        self.sel_time_indices = np.where(
            [start_date <= t <= end_date for t in times])[0]
        self.times = times[self.sel_time_indices]

        ax.figure.canvas.mpl_connect("button_press_event", self)
def get_zone_around_lakes_mask(lons, lats, lake_mask, ktree=None, dist_km=100):
    """
    Returns the mask of a zone around lakes (excluding lakes) of a given width
    :type ktree: cKDTree
    :param ktree:
    :param lons:
    :param lats:
    :param lake_mask:
    :param dist_km:
    """

    x, y, z = lat_lon.lon_lat_to_cartesian(lons[lake_mask], lats[lake_mask])

    near_lake_zone = np.zeros_like(lons, dtype=bool)

    nlons = lons.shape[0] * lons.shape[1]
    near_lake_zone.shape = (nlons,)

    for xi, yi, zi in zip(x, y, z):
        dists, inds = ktree.query(np.array([[xi, yi, zi], ]), k=nlons, distance_upper_bound=dist_km * 1000)
        near_lake_zone[inds[inds < nlons]] = True

    near_lake_zone.shape = (lons.shape[0], lons.shape[1])

    # Remove lake points from the mask
    near_lake_zone &= ~lake_mask

    return near_lake_zone
Exemple #22
0
    def _init_fields(self, nc_dataset):
        nc_vars = nc_dataset.variables
        lons = nc_vars["lon"][:]
        lats = nc_vars["lat"][:]


        if lons.ndim == 1:
            lats2d, lons2d = np.meshgrid(lats, lons)
        elif lons.ndim == 2:
            lats2d, lons2d = lats, lons
        else:
            raise NotImplementedError("Cannot handle {}-dimensional coordinates".format(lons.ndim))


        self.lons2d, self.lats2d = lons2d, lats2d

        self.times_var = nc_vars["time"]
        self.times_num = nc_vars["time"][:]

        if hasattr(self.times_var, "calendar"):
            self.times = num2date(self.times_num, self.times_var.units, self.times_var.calendar)
        else:
            self.times = num2date(self.times_num, self.times_var.units)


        if not self.lazy:

            self.var_data = nc_vars[self.var_name][:]
            if nc_vars[self.var_name].shape[1:] != self.lons2d.shape:
                print("nc_vars[self.var_name].shape = {}".format(nc_vars[self.var_name].shape))
                self.var_data = np.transpose(self.var_data, axes=[0, 2, 1])


        x_in, y_in, z_in = lat_lon.lon_lat_to_cartesian(self.lons2d.flatten(), self.lats2d.flatten())
        self.kdtree = cKDTree(list(zip(x_in, y_in, z_in)))
Exemple #23
0
    def get_daily_timeseries_using_mask(self, mask, lons2d_target, lats2d_target, multipliers_2d, start_date=None,
                                        end_date=None):
        """
        multipliers_2d used to multiply the values when aggregating into a single timeseries
        sum(mi * vi) - in space
        """

        bool_vect = np.array([start_date <= t <= end_date for t in self.times])

        new_times = list(filter(lambda t: start_date <= t <= end_date, self.times))
        new_vals = self.var_data[bool_vect, :, :]
        x_out, y_out, z_out = lat_lon.lon_lat_to_cartesian(lons2d_target.flatten(), lats2d_target.flatten())

        print(len(new_times))

        flat_mask = mask.flatten()
        x_out = x_out[flat_mask == 1]
        y_out = y_out[flat_mask == 1]
        z_out = z_out[flat_mask == 1]
        mults = multipliers_2d.flatten()[flat_mask == 1]
        data_interp = [self._interp_and_sum(new_vals[t, :, :].flatten(), flat_mask, x_out, y_out, z_out) for t in
                       range(len(new_times))]

        print("Interpolated all")
        return TimeSeries(time=new_times, data=data_interp).get_ts_of_daily_means()
Exemple #24
0
    def getMeanFieldForMonthsInterpolatedTo(self,
                                            months=None,
                                            lonstarget=None,
                                            latstarget=None,
                                            start_year=None,
                                            end_year=None):
        """


        :type lonstarget: object
        :param months:
        :param lonstarget:
        :param latstarget:
        :param start_year:
        :param end_year:
        :return: the field in mm/day
        """
        mean_field = self.getMeanFieldForMonths(months=months,
                                                start_year=start_year,
                                                end_year=end_year)

        lons1d, lats1d = lonstarget.flatten(), latstarget.flatten()
        xt, yt, zt = lat_lon.lon_lat_to_cartesian(lons1d, lats1d)

        dists, indices = self.kdtree.query(list(zip(xt, yt, zt)))
        return mean_field.flatten()[indices].reshape(lonstarget.shape)
Exemple #25
0
    def get_daily_clim_fields_aggregated_and_interpolated_to(self, start_year=None, end_year=None,
                                              lons_target=None, lats_target=None, n_agg_x=1, n_agg_y=1):
        """
        Aggregate fields to the desired resolution prior to interpolation
        :param start_year:
        :param end_year:
        :param lons_target:
        :param lats_target:
        """
        # Return 365 fields
        df = self.get_daily_climatology_fields(start_year=start_year, end_year=end_year)

        assert isinstance(df, pd.Panel)

        lons1d, lats1d = lons_target.flatten(), lats_target.flatten()
        xt, yt, zt = lat_lon.lon_lat_to_cartesian(lons1d, lats1d)

        dists, indices = self.kdtree.query(list(zip(xt, yt, zt)), k=n_agg_x * n_agg_y)

        clim_fields = [
            df.loc[:, day, :].values.flatten()[indices].mean(axis=1).reshape(lons_target.shape) for day in df.major_axis
        ]
        clim_fields = np.asarray(clim_fields)
        clim_fields = np.ma.masked_where(np.isnan(clim_fields), clim_fields)
        return df.major_axis, clim_fields
Exemple #26
0
    def interpolate_data_to(self, data_in, lons2d, lats2d, nneighbours=4):
        """
        Interpolates data_in to the grid defined by (lons2d, lats2d)
        assuming that the data_in field is on the initial CRU grid

        interpolate using 4 nearest neighbors and inverse of squared distance
        """

        x_out, y_out, z_out = lat_lon.lon_lat_to_cartesian(lons2d.flatten(), lats2d.flatten())
        dst, ind = self.kdtree.query(list(zip(x_out, y_out, z_out)), k=nneighbours)

        data_in_flat = data_in.flatten()

        inverse_square = 1.0 / dst ** 2
        if len(dst.shape) > 1:
            norm = np.sum(inverse_square, axis=1)
            norm = np.array([norm] * dst.shape[1]).transpose()
            coefs = inverse_square / norm

            data_out_flat = np.sum(coefs * data_in_flat[ind], axis=1)
        elif len(dst.shape) == 1:
            data_out_flat = data_in_flat[ind]
        else:
            raise Exception("Could not find neighbor points")
        return np.reshape(data_out_flat, lons2d.shape)
Exemple #27
0
 def toGeographicLonLat(self, x, y):
     """
     convert geographic lat / lon to rotated coordinates
     """
     p = lat_lon.lon_lat_to_cartesian(x, y, R=1)
     p = self.rot_matrix.T * np.mat(p).T
     return lat_lon.cartesian_to_lon_lat(p.A1)
Exemple #28
0
    def _init_fields(self, nc_dataset):
        nc_vars = nc_dataset.variables
        lons = nc_vars["lon"][:]
        lats = nc_vars["lat"][:]

        if lons.ndim == 1:
            lats2d, lons2d = np.meshgrid(lats, lons)
        elif lons.ndim == 2:
            lats2d, lons2d = lats, lons
        else:
            raise NotImplementedError(
                "Cannot handle {}-dimensional coordinates".format(lons.ndim))

        self.lons2d, self.lats2d = lons2d, lats2d

        self.times_var = nc_vars["time"]
        self.times_num = nc_vars["time"][:]

        if hasattr(self.times_var, "calendar"):
            self.times = num2date(self.times_num, self.times_var.units,
                                  self.times_var.calendar)
        else:
            self.times = num2date(self.times_num, self.times_var.units)

        if not self.lazy:

            self.var_data = nc_vars[self.var_name][:]
            if nc_vars[self.var_name].shape[1:] != self.lons2d.shape:
                print("nc_vars[self.var_name].shape = {}".format(
                    nc_vars[self.var_name].shape))
                self.var_data = np.transpose(self.var_data, axes=[0, 2, 1])

        x_in, y_in, z_in = lat_lon.lon_lat_to_cartesian(
            self.lons2d.flatten(), self.lats2d.flatten())
        self.kdtree = cKDTree(list(zip(x_in, y_in, z_in)))
Exemple #29
0
    def interpolate_data_to(self, data_in, lons2d, lats2d, nneighbours=4):
        """
        Interpolates data_in to the grid defined by (lons2d, lats2d)
        assuming that the data_in field is on the initial CRU grid

        interpolate using 4 nearest neighbors and inverse of squared distance
        """

        x_out, y_out, z_out = lat_lon.lon_lat_to_cartesian(
            lons2d.flatten(), lats2d.flatten())
        dst, ind = self.kdtree.query(list(zip(x_out, y_out, z_out)),
                                     k=nneighbours)

        data_in_flat = data_in.flatten()

        inverse_square = 1.0 / dst**2
        if len(dst.shape) > 1:
            norm = np.sum(inverse_square, axis=1)
            norm = np.array([norm] * dst.shape[1]).transpose()
            coefs = inverse_square / norm

            data_out_flat = np.sum(coefs * data_in_flat[ind], axis=1)
        elif len(dst.shape) == 1:
            data_out_flat = data_in_flat[ind]
        else:
            raise Exception("Could not find neighbor points")
        return np.reshape(data_out_flat, lons2d.shape)
Exemple #30
0
    def __init__(self,
                 ax,
                 basemap,
                 tmin_3d,
                 tmax_3d,
                 lons2d,
                 lats2d,
                 levelheights=None):
        """
        Plots a vertical profile at the point nearest to the clicked one
        :type ax: Axes
        """
        assert isinstance(ax, Axes)
        self.basemap = basemap
        assert isinstance(self.basemap, Basemap)
        self.tmin_3d = tmin_3d
        self.tmax_3d = tmax_3d
        self.lons2d = lons2d
        self.lats2d = lats2d
        self.T0 = 273.15

        self.lons_flat = lons2d.flatten()
        self.lats_flat = lats2d.flatten()
        self.level_heights = levelheights

        self.counter = 0
        self.ax = ax
        x, y, z = lat_lon.lon_lat_to_cartesian(lons2d.flatten(),
                                               lats2d.flatten())
        self.kdtree = KDTree(list(zip(x, y, z)))
        ax.figure.canvas.mpl_connect("button_press_event", self)
        pass
Exemple #31
0
 def _init_kd_tree(self):
     """
     Init KDTree used for interpolation
     """
     x0, y0, z0 = lat_lon.lon_lat_to_cartesian(self.lon2d.flatten(),
                                               self.lat2d.flatten())
     self.kdtree = KDTree(list(zip(x0, y0, z0)))
Exemple #32
0
    def _get_spatial_integrals_over_points_in_time(self, lons2d_target, lats2d_target, mask,
                                                   areas2d, start_date=None, end_date=None, var_name=""):
        """
        i)  Interpolate to the grid (lons2d_target, lats2d_target)
        ii) Apply the mask to the interpoated fields and sum with coefficients from areas2d

        Note: the interpolation is done using nearest neighbor approach

        returns a timeseries of {t -> sum(Ai[mask]*xi[mask])(t)}
        """


        #interpolation
        x1, y1, z1 = lat_lon.lon_lat_to_cartesian(lons2d_target.flatten(), lats2d_target.flatten())

        dists, indices = self.kdtree.query(list(zip(x1, y1, z1)))

        mask1d = mask.flatten().astype(int)
        areas1d = areas2d.flatten()

        result = {}
        for the_date in list(self.date_to_path.keys()):
            if start_date is not None:
                if start_date > the_date: continue

            if end_date is not None:
                if end_date < the_date: continue

            data = self.get_field_for_date(the_date, var_name=var_name)
            result[the_date] = np.sum(data.flatten()[indices][mask1d == 1] * areas1d[mask1d == 1])

        times = list(sorted(result.keys()))
        values = [result[x] for x in times]
        print("nvals, min, max", len(values), min(values), max(values))
        return TimeSeries(time=times, data=values)
Exemple #33
0
def get_flat_index(lon, lat, the_kd_tree):
    """
    :type the_kd_tree: KDTree
    """
    x0, y0, z0 = lat_lon.lon_lat_to_cartesian(lon, lat)
    d, i = the_kd_tree.query((x0, y0, z0))
    return i
Exemple #34
0
    def get_kdtree(self, lons=None, lats=None, cache=True):
        """

        :param lons:
        :param lats:
        :param cache: if True then reuse the kdtree
        :return:
        """
        if lons is None:
            lons = self.lons
            lats = self.lats

        if lons is None:
            raise Exception(
                "The coordinates (lons and lats) are not yet set for the manager, please read some data first")

        if cache and self.kdtree is not None:
            return self.kdtree

        xs, ys, zs = lat_lon.lon_lat_to_cartesian(lons.flatten(), lats.flatten())
        kdtree = KDTree(list(zip(xs, ys, zs)))

        if cache:
            self.kdtree = kdtree

        return kdtree
Exemple #35
0
def get_zone_around_lakes_mask(lons, lats, lake_mask, ktree=None, dist_km=100):
    """
    Returns the mask of a zone around lakes (excluding lakes) of a given width
    :type ktree: cKDTree
    :param ktree:
    :param lons:
    :param lats:
    :param lake_mask:
    :param dist_km:
    """

    x, y, z = lat_lon.lon_lat_to_cartesian(lons[lake_mask], lats[lake_mask])

    near_lake_zone = np.zeros_like(lons, dtype=bool)

    nlons = lons.shape[0] * lons.shape[1]
    near_lake_zone.shape = (nlons, )

    for xi, yi, zi in zip(x, y, z):
        dists, inds = ktree.query(np.array([
            [xi, yi, zi],
        ]),
                                  k=nlons,
                                  distance_upper_bound=dist_km * 1000)
        near_lake_zone[inds[inds < nlons]] = True

    near_lake_zone.shape = (lons.shape[0], lons.shape[1])

    # Remove lake points from the mask
    near_lake_zone &= ~lake_mask

    return near_lake_zone
Exemple #36
0
    def get_daily_timeseries_using_mask(self,
                                        mask,
                                        lons2d_target,
                                        lats2d_target,
                                        multipliers_2d,
                                        start_date=None,
                                        end_date=None):
        """
        multipliers_2d used to multiply the values when aggregating into a single timeseries
        sum(mi * vi) - in space
        """

        bool_vect = np.array([start_date <= t <= end_date for t in self.times])

        new_times = list(
            filter(lambda t: start_date <= t <= end_date, self.times))
        new_vals = self.var_data[bool_vect, :, :]
        x_out, y_out, z_out = lat_lon.lon_lat_to_cartesian(
            lons2d_target.flatten(), lats2d_target.flatten())

        print(len(new_times))

        flat_mask = mask.flatten()
        x_out = x_out[flat_mask == 1]
        y_out = y_out[flat_mask == 1]
        z_out = z_out[flat_mask == 1]
        mults = multipliers_2d.flatten()[flat_mask == 1]
        data_interp = [
            self._interp_and_sum(new_vals[t, :, :].flatten(), flat_mask, x_out,
                                 y_out, z_out) for t in range(len(new_times))
        ]

        print("Interpolated all")
        return TimeSeries(time=new_times,
                          data=data_interp).get_ts_of_daily_means()
Exemple #37
0
 def toGeographicLonLat(self, x, y):
     """
     convert geographic lat / lon to rotated coordinates
     """
     p = lat_lon.lon_lat_to_cartesian(x, y, R=1)
     p = self.rot_matrix.T * np.mat(p).T
     return lat_lon.cartesian_to_lon_lat(p.A1)
Exemple #38
0
    def __init__(self, name_to_date_to_field, basemap, lons2d, lats2d,
                 ax = None, cell_area = None, cell_manager = None, data_manager = None):


        self.gwdi_mean_field = None
        self.traf_mean_field = None
        self.tdra_mean_field = None
        self.upin_mean_field = None


        self.basemap = basemap
        self.date_to_stfl_field = name_to_date_to_field["STFL"]
        self.date_to_traf_field = name_to_date_to_field["TRAF"]
        self.date_to_tdra_field = name_to_date_to_field["TDRA"]
        self.date_to_pr_field = name_to_date_to_field["PR"]
        self.date_to_swe_field = name_to_date_to_field["I5"]
        self.date_to_swst_field = name_to_date_to_field["SWST"]
        #self.date_to_imav_field = name_to_date_to_field["IMAV"]

        self.acc_area_km2 = name_to_date_to_field["FACC"]
        #:type : CellManager
        self.cell_manager = cell_manager
        assert isinstance(self.cell_manager, CellManager)
        self.cell_area = cell_area

        x, y, z = lat_lon.lon_lat_to_cartesian(lons2d.flatten(), lats2d.flatten())
        self.kdtree = KDTree(list(zip(x,y,z)))
        ax.figure.canvas.mpl_connect("button_press_event", self)
        self.ax = ax
        self.lons2d = lons2d
        self.lats2d = lats2d
        self.data_manager = data_manager
        assert isinstance(self.data_manager, Crcm5ModelDataManager)


        self.x_pr, self.y_pr = basemap(lons2d, lats2d)

        self.lons_flat = lons2d.flatten()
        self.lats_flat = lats2d.flatten()
        self.dates_sorted = list( sorted(list(name_to_date_to_field.items())[0][1].keys()) )


        self.counter = 0

        self.date_to_swsr_field = name_to_date_to_field["SWSR"]
        self.date_to_swsl_field = name_to_date_to_field["SWSL"]
        #self.date_to_gwdi_field = name_to_date_to_field["GWDI"]
        self.date_to_upin_field = name_to_date_to_field["UPIN"]


        #static fields
        self.slope = name_to_date_to_field["SLOP"]
        self.channel_length = name_to_date_to_field["LENG"]
        self.lake_outlet = name_to_date_to_field["LKOU"]

        self.coef_bf = -np.ones(self.slope.shape)

        good_points = self.slope >= 0
        self.coef_bf[good_points] = (self.slope[good_points]) ** 0.5 / ((self.channel_length[good_points]) ** (4.0/3.0) * data_manager.manning_bf[good_points] )
Exemple #39
0
    def toProjectionXY(self, lon, lat):
        """
        Convert geographic lon/lat coordinates to the rotated lat lon coordinates
        """

        p = lat_lon.lon_lat_to_cartesian(lon, lat, R=1)
        p = self.rot_matrix * np.mat(p).T
        return lat_lon.cartesian_to_lon_lat(p.A1)
Exemple #40
0
    def toProjectionXY(self, lon, lat):
        """
        Convert geographic lon/lat coordinates to the rotated lat lon coordinates
        """

        p = lat_lon.lon_lat_to_cartesian(lon, lat, R=1)
        p = self.rot_matrix * np.mat(p).T
        return lat_lon.cartesian_to_lon_lat(p.A1)
Exemple #41
0
    def get_lake_model_points_for_stations(self, station_list, lake_fraction=None,
                                           nneighbours=8):

        """
        For lake levels we have a bit different search algorithm since accumulation area is not a very sensible param to compare
        :return {station: list of corresponding model points}

        :param station_list:
        :param lake_fraction:
        :param drainaige_area_reldiff_limit:
        :param nneighbours:
        :return: :raise Exception:
        """

        station_to_model_point_list = {}
        nx, ny = self.lons2d.shape
        i1d, j1d = list(range(nx)), list(range(ny))
        j2d, i2d = np.meshgrid(j1d, i1d)
        i_flat, j_flat = i2d.flatten(), j2d.flatten()

        for s in station_list:
            mp_list = []

            assert isinstance(s, Station)
            x, y, z = lat_lon.lon_lat_to_cartesian(s.longitude, s.latitude)
            dists, inds = self.kdtree.query((x, y, z), k=nneighbours)
            if nneighbours == 1:
                dists = [dists]
                inds = [inds]

            for d, i in zip(dists, inds):
                ix = i_flat[i]
                jy = j_flat[i]
                mp = ModelPoint(ix=ix, jy=jy)

                mp.longitude = self.lons2d[ix, jy]
                mp.latitude = self.lats2d[ix, jy]

                mp.distance_to_station = d
                if lake_fraction is not None:
                    if lake_fraction[ix, jy] <= 0.001:  # skip the model point if almost no lakes inisde
                        continue

                    mp.lake_fraction = lake_fraction[ix, jy]
                mp_list.append(mp)

            if lake_fraction is not None:
                lf = 0.0
                for mp in mp_list:
                    lf += mp.lake_fraction

                if lf <= 0.001:
                    continue

            station_to_model_point_list[s] = mp_list
            print("Found model point for the station {0}".format(s))

        return station_to_model_point_list
Exemple #42
0
    def __init__(self, flow_dirs, nx=None, ny=None,
                 lons2d=None,
                 lats2d=None,
                 accumulation_area_km2=None):
        self.cells = []
        self.lons2d = lons2d
        self.lats2d = lats2d
        self.flow_directions = flow_dirs

        self.accumulation_area_km2 = accumulation_area_km2

        # calculate characteristic distance
        if not any([None is arr for arr in [self.lats2d, self.lons2d]]):
            v1 = lat_lon.lon_lat_to_cartesian(self.lons2d[0, 0], self.lats2d[0, 0])
            v2 = lat_lon.lon_lat_to_cartesian(self.lons2d[1, 1], self.lats2d[1, 1])
            dv = np.array(v2) - np.array(v1)
            self.characteristic_distance = np.sqrt(np.dot(dv, dv))

            x, y, z = lat_lon.lon_lat_to_cartesian(self.lons2d.flatten(), self.lats2d.flatten())
            self.kdtree = cKDTree(list(zip(x, y, z)))

        if None not in [nx, ny]:
            self.nx = nx
            self.ny = ny
        else:
            nx, ny = flow_dirs.shape
            self.nx, self.ny = flow_dirs.shape

        for i in range(nx):
            self.cells.append(list([Cell(i=i, j=j, flow_dir_value=flow_dirs[i, j]) for j in range(ny)]))

        self._without_next_mask = np.zeros((nx, ny), dtype=np.int)
        self._wo_next_wo_prev_mask = np.zeros((nx, ny), dtype=np.int)  # mask of the potential outlets
        for i in range(nx):
            if i % 100 == 0:
                print("Created {}/{}".format(i, nx))
            for j in range(ny):
                i_next, j_next = direction_and_value.to_indices(i, j, flow_dirs[i][j])
                next_cell = None
                if 0 <= i_next < nx:
                    if 0 <= j_next < ny:
                        next_cell = self.cells[i_next][j_next]

                self._without_next_mask[i, j] = int(next_cell is None)
                self.cells[i][j].set_next(next_cell)
Exemple #43
0
def regenerate_station_to_gridcell_mapping(start_year, end_year,
                                           model_manager):
    """
    should be called when grid or search algorithm change
    """

    assert isinstance(model_manager, Crcm5ModelDataManager)

    ktree = model_manager.kdtree
    model_acc_area = model_manager.accumulation_area_km2
    model_acc_area_1d = model_acc_area.flatten()

    #    selected_ids = ["104001", "103715",
    #                    "093806", "093801",
    #                    "092715",
    #                    "081006", "040830"]

    selected_ids = None
    start_date = datetime(start_year, 1, 1)
    end_date = datetime(end_year, 12, 31)

    stations = cehq_station.read_station_data(selected_ids=selected_ids,
                                              start_date=start_date,
                                              end_date=end_date)

    station_to_grid_point = {}
    for s in stations:
        assert isinstance(s, Station)
        x, y, z = lat_lon.lon_lat_to_cartesian(s.longitude, s.latitude)
        dists, inds = ktree.query((x, y, z), k=8)

        deltaDaMin = np.min(np.abs(model_acc_area_1d[inds] - s.drainage_km2))

        imin = np.where(
            np.abs(model_acc_area_1d[inds] - s.drainage_km2) == deltaDaMin)[0]

        deltaDa2D = np.abs(model_acc_area - s.drainage_km2)

        ij = np.where(deltaDa2D == deltaDaMin)

        mp = ModelPoint()
        mp.accumulation_area = model_acc_area[ij[0][0], ij[1][0]]
        mp.ix = ij[0][0]
        mp.jy = ij[1][0]
        mp.longitude = model_manager.lons2D[mp.ix, mp.jy]
        mp.latitude = model_manager.lats2D[mp.ix, mp.jy]

        #flow in mask
        mp.flow_in_mask = model_manager.get_mask_for_cells_upstream(
            mp.ix, mp.jy)

        station_to_grid_point[s] = mp

        print("da_diff (sel) = ", deltaDaMin)
        print("dist (sel) = ", dists[imin])

    return station_to_grid_point
Exemple #44
0
    def get_mean_upstream_timeseries_monthly(self, model_point, data_manager):
        """
        get mean swe upstream of the model_point

        year range for selection is in model_point.continuous_data_years() ..
        """
        assert isinstance(model_point, ModelPoint)
        assert isinstance(data_manager, Crcm5ModelDataManager)

        # create the mask of points over which the averaging is going to be done
        lons_targ = data_manager.lons2D[model_point.flow_in_mask == 1]
        lats_targ = data_manager.lats2D[model_point.flow_in_mask == 1]

        xt, yt, zt = lat_lon.lon_lat_to_cartesian(lons_targ, lats_targ)

        nxs, nys = self.lons2d.shape
        i_source, j_source = list(range(nxs)), list(range(nys))

        j_source, i_source = np.meshgrid(j_source, i_source)

        i_source = i_source.flatten()
        j_source = j_source.flatten()

        dists, inds = self.kdtree.query(list(zip(xt, yt, zt)), k=1)
        ixsel = i_source[inds]
        jysel = j_source[inds]

        print("Calculating spatial mean")
        #calculate spatial mean
        #calculate spatial mean
        if self.lazy:
            theVar = self.nc_vars[self.var_name]

            data_series = []
            for i, j in zip(ixsel, jysel):
                data_series.append(theVar[:, j, i])

            data_series = np.mean(data_series, axis=0)
        else:
            data_series = np.mean(self.var_data[:, ixsel, jysel], axis=1)

        print("Finished calculating spatial mean")

        #calculate daily climatology
        df = pandas.DataFrame(data=data_series,
                              index=self.times,
                              columns=["values"])

        df["year"] = df.index.map(lambda d: d.year)

        df = df[df["year"].isin(model_point.continuous_data_years)]
        monthly_clim = df.groupby(by=lambda d: d.month).mean()

        month_dates = [datetime(1985, m, 15) for m in range(1, 13)]
        vals = [monthly_clim.ix[d.month, "values"] for d in month_dates]

        return pandas.TimeSeries(data=vals, index=month_dates)
 def get_kd_tree(self):
     """
     :rtype : KDTree
     for interpolation purposes
     """
     if self._kdtree is None:
         x, y, z = lat_lon.lon_lat_to_cartesian(self.lons.flatten(), self.lats.flatten() )
         self._kdtree = KDTree(zip(x,y,z))
     return self._kdtree
Exemple #46
0
    def get_mean_upstream_timeseries_monthly(self, model_point, data_manager):
        """
        get mean swe upstream of the model_point

        year range for selection is in model_point.continuous_data_years() ..
        """
        assert isinstance(model_point, ModelPoint)
        assert isinstance(data_manager, Crcm5ModelDataManager)



        # create the mask of points over which the averaging is going to be done
        lons_targ = data_manager.lons2D[model_point.flow_in_mask == 1]
        lats_targ = data_manager.lats2D[model_point.flow_in_mask == 1]

        xt, yt, zt = lat_lon.lon_lat_to_cartesian(lons_targ, lats_targ)

        nxs, nys = self.lons2d.shape
        i_source, j_source = list(range(nxs)), list(range(nys))

        j_source, i_source = np.meshgrid(j_source, i_source)

        i_source = i_source.flatten()
        j_source = j_source.flatten()

        dists, inds = self.kdtree.query(list(zip(xt, yt, zt)), k=1)
        ixsel = i_source[inds]
        jysel = j_source[inds]

        print("Calculating spatial mean")
        #calculate spatial mean
        #calculate spatial mean
        if self.lazy:
            theVar = self.nc_vars[self.var_name]

            data_series = []
            for i, j in zip(ixsel, jysel):
                data_series.append(theVar[:, j, i])

            data_series = np.mean(data_series, axis=0)
        else:
            data_series = np.mean(self.var_data[:, ixsel, jysel], axis=1)

        print("Finished calculating spatial mean")

        #calculate daily climatology
        df = pandas.DataFrame(data=data_series, index=self.times, columns=["values"])

        df["year"] = df.index.map(lambda d: d.year)

        df = df[df["year"].isin(model_point.continuous_data_years)]
        monthly_clim = df.groupby(by=lambda d: d.month).mean()

        month_dates = [datetime(1985, m, 15) for m in range(1, 13)]
        vals = [monthly_clim.ix[d.month, "values"] for d in month_dates]

        return pandas.TimeSeries(data=vals, index=month_dates)
def test_evol_for_point():
    lon = -100
    lat = 60

    path = "/home/huziy/skynet1_rech3/cordex/for_Samira/b1/tmp_era40_b1.nc"

    ds = Dataset(path)
    data = ds.variables["tmp"][:]
    years = ds.variables["year"][:]

    coord_file = "/skynet1_rech3/huziy/cordex/CORDEX_DIAG/NorthAmerica_0.44deg_CanESM_B1"
    coord_file = os.path.join(coord_file, "pmNorthAmerica_0.44deg_CanHisto_B1_195801_moyenne")
    #coord_file = os.path.join(data_folder, "pmNorthAmerica_0.44deg_ERA40-Int2_195801_moyenne")
    b, lons2d, lats2d = draw_regions.get_basemap_and_coords(file_path=coord_file)

    sel_lons = [lon]
    sel_lats = [lat]
    xo,yo,zo = lat_lon.lon_lat_to_cartesian(sel_lons, sel_lats)

    xi, yi, zi = lat_lon.lon_lat_to_cartesian(lons2d.flatten(), lats2d.flatten())
    ktree = KDTree(list(zip(xi,yi,zi)))
    dists, indexes =  ktree.query(list(zip(xo,yo,zo)))


    print(len(indexes))
    print(indexes)
    idx = indexes[0]

    import matplotlib.pyplot as plt
    plt.figure()
    data_to_show = []

    for i, y in enumerate(years):

        data_to_show.append(data[i,:,:].flatten()[idx])

    plt.plot(years, data_to_show, "-s", lw = 3)
    plt.grid()

    plt.show()



    pass
    def get_data_from_file_interpolate_if_needed(self, the_path):

        the_path = str(the_path)

        if the_path.lower()[-3:] in ["cis", "nic"]:
            data = self._parse_nic_cis_data_file(the_path)
        else:
            data = self.get_data_from_path(the_path)



        # Convert to the 0 to 1 range
        data /= 100.


        assert np.all(data.mask) or (np.ma.max(data) <= 1), "ice cover max value is too high {}".format(np.ma.max(data))

        if data.shape != (self.ncols_target, self.ncols_target):
            # The interpolation is needed
            domain_descr = data.shape
            if domain_descr not in self.domain_descr_to_kdtree:

                if domain_descr == (516, 510):
                    self.lons2d_other = np.flipud(np.loadtxt(self.path_to_other_lons)).transpose()
                    self.lats2d_other = np.flipud(np.loadtxt(self.path_to_other_lats)).transpose()
                else:
                    self.lons2d_other, self.lats2d_other = self._generate_grid_from_descriptor(domain_descr)

                xs, ys, zs = lat_lon.lon_lat_to_cartesian(self.lons2d_other.flatten(), self.lats2d_other.flatten())

                kdtree_other = cKDTree(data=list(zip(xs, ys, zs)))

                self.domain_descr_to_kdtree[data.shape] = kdtree_other

            kdtree_other = self.domain_descr_to_kdtree[data.shape]
            xt, yt, zt = lat_lon.lon_lat_to_cartesian(self.lons2d_target.flatten(), self.lats2d_target.flatten())
            dsts, inds = kdtree_other.query(list(zip(xt, yt, zt)))


            return data.flatten()[inds].reshape(self.lons2d_target.shape)

        else:
            return data
Exemple #49
0
def find_closest_ini_point(
        folder_with_ini_files="/home/huziy/skynet1_rech3/SCA7026_CLASS/offline_initialisation",
        longitude=None,
        latitude=None,
        filename_prefix="ERA40_NEW"):

    ktree, paths = generate_kdtree(folder_with_ini_files, filename_prefix)
    x, y, z = lat_lon.lon_lat_to_cartesian(longitude, latitude)
    dist, i = ktree.query((x, y, z))
    return paths[i]
Exemple #50
0
 def get_kd_tree(self):
     """
     :rtype : KDTree
     for interpolation purposes
     """
     if self._kdtree is None:
         x, y, z = lat_lon.lon_lat_to_cartesian(self.lons.flatten(),
                                                self.lats.flatten())
         self._kdtree = KDTree(list(zip(x, y, z)))
     return self._kdtree
Exemple #51
0
    def get_mean_upstream_timeseries_daily(self,
                                           model_point,
                                           dm,
                                           stamp_dates=None):
        """
        get mean swe upstream of the model_point
        """
        assert isinstance(model_point, ModelPoint)

        assert isinstance(dm, Crcm5ModelDataManager)

        # create the mask of points over which the averaging is going to be done
        lons_targ = dm.lons2D[model_point.flow_in_mask == 1]
        lats_targ = dm.lats2D[model_point.flow_in_mask == 1]

        xt, yt, zt = lat_lon.lon_lat_to_cartesian(lons_targ, lats_targ)

        nxs, nys = self.lons2d.shape
        i_source, j_source = list(range(nxs)), list(range(nys))

        j_source, i_source = np.meshgrid(j_source, i_source)

        i_source = i_source.flatten()
        j_source = j_source.flatten()

        dists, inds = self.kdtree.query(list(zip(xt, yt, zt)), k=1)
        ixsel = i_source[inds]
        jysel = j_source[inds]

        df_empty = pandas.DataFrame(index=self.times)
        df_empty["year"] = df_empty.index.map(lambda d: d.year)

        # calculate spatial mean
        sel_date_indices = np.where(df_empty["year"].isin(
            model_point.continuous_data_years))[0]
        if self.lazy:
            the_var = self.nc_vars[self.var_name]
            data_series = np.mean([
                the_var[sel_date_indices, j, i] for i, j in zip(ixsel, jysel)
            ],
                                  axis=0)
        else:
            data_series = np.mean(self.var_data[:, ixsel, jysel], axis=1)

        # calculate daily climatology
        df = pandas.DataFrame(data=data_series,
                              index=self.times,
                              columns=["values"])

        df["year"] = df.index.map(lambda d: d.year)
        df = df[df["year"].isin(model_point.continuous_data_years)]
        daily_clim = df.groupby(by=lambda d: (d.month, d.day)).mean()

        vals = [daily_clim.ix[(d.month, d.day), "values"] for d in stamp_dates]
        return pandas.TimeSeries(data=vals, index=stamp_dates)
Exemple #52
0
def fill_missing_values(route_slope,
                        interpolated_slopes,
                        lons2d=None,
                        lats2d=None):

    to_fill = (route_slope >= 0) & (interpolated_slopes < 0)

    # Only do the filling if necessary
    if not np.any(to_fill):
        return

    correct_slopes = interpolated_slopes >= 0

    x, y, z = lat_lon.lon_lat_to_cartesian(lons2d[correct_slopes],
                                           lats2d[correct_slopes])
    ktree = cKDTree(list(zip(x, y, z)))

    xt, yt, zt = lat_lon.lon_lat_to_cartesian(lons2d[to_fill], lats2d[to_fill])
    dists, inds = ktree.query(list(zip(xt, yt, zt)))
    interpolated_slopes[to_fill] = interpolated_slopes[correct_slopes][inds]
Exemple #53
0
def find_closest_ini_point(
    folder_with_ini_files="/home/huziy/skynet1_rech3/SCA7026_CLASS/offline_initialisation",
    longitude=None,
    latitude=None,
    filename_prefix="ERA40_NEW",
):

    ktree, paths = generate_kdtree(folder_with_ini_files, filename_prefix)
    x, y, z = lat_lon.lon_lat_to_cartesian(longitude, latitude)
    dist, i = ktree.query((x, y, z))
    return paths[i]
    def _set_kd_tree(self):

        if len(self.lons.shape) == 1:
            lats_2d, lons_2d = np.meshgrid(self.lats, self.lons)
        else:
            lats_2d, lons_2d = self.lats, self.lons

        x, y, z = lat_lon.lon_lat_to_cartesian(lons_2d.flatten(), lats_2d.flatten())
        print lons_2d.shape, lats_2d.shape
        print lons_2d[0,0], lons_2d[-1, 0]
        print self.data.shape
        self.kdtree = KDTree(data = zip(x, y, z))
Exemple #55
0
    def get_seasonal_clim_interpolated_to(self, target_lon2d=None, target_lat2d=None, season_to_months=None, start_year=-np.Inf, end_year=np.Inf):
        season_to_clim = self.get_seasonal_clim(season_to_months=season_to_months, start_year=start_year, end_year=end_year)

        selection = (self.lons <= 180) & (self.lons >= -180) & (self.lats >= -90) & (self.lats <= 90)

        if self.kdtree is None:
            x, y, z = lat_lon.lon_lat_to_cartesian(self.lons[selection], self.lats[selection])
            self.kdtree = KDTree(list(zip(x, y, z)))

        x1, y1, z1 = lat_lon.lon_lat_to_cartesian(target_lon2d.flatten(), target_lat2d.flatten())
        dists, inds = self.kdtree.query(list(zip(x1, y1, z1)))
        season_to_clim_interpolated = OrderedDict()

        for season, clim in season_to_clim.items():
            season_to_clim_interpolated[season] = clim[selection][inds].reshape(target_lon2d.shape)

        #
        plt.show()


        return season_to_clim_interpolated
Exemple #56
0
def plot_depth_to_bedrock(basemap,
                          lons1, lats1, field1, label1,
                          lons2, lats2, field2, label2,
                          base_folder="/skynet3_rech1/huziy/veg_fractions/"
                          ):
    xs, ys, zs = lat_lon.lon_lat_to_cartesian(lons2.flatten(), lats2.flatten())
    xt, yt, zt = lat_lon.lon_lat_to_cartesian(lons1.flatten(), lats1.flatten())

    ktree = cKDTree(list(zip(xs, ys, zs)))
    dists, inds = ktree.query(list(zip(xt, yt, zt)))

    levels = np.arange(0, 5.5, 0.5)

    field2_interp = field2.flatten()[inds].reshape(field1.shape)

    field1 = np.ma.masked_where(field1 < 0, field1)
    field2_interp = np.ma.masked_where(field2_interp < 0, field2_interp)

    vmin = min(field1.min(), field2_interp.min())
    vmax = max(field1.max(), field2_interp.max())
    cmap = cm.get_cmap("BuPu", len(levels) - 1)
    bn = BoundaryNorm(levels, len(levels) - 1)
    x, y = basemap(lons1, lats1)
    imname = "depth_to_bedrock_{0}-{1}.jpeg".format(label2, label1)
    impath = os.path.join(base_folder, imname)
    fig = plt.figure(figsize=(6, 2.5))
    gs = GridSpec(1, 3, width_ratios=[1, 1, 0.05])
    ax = fig.add_subplot(gs[0, 0])
    basemap.pcolormesh(x, y, field1, vmin=vmin, vmax=vmax, cmap=cmap, norm=bn)
    basemap.drawcoastlines(linewidth=common_plot_params.COASTLINE_WIDTH)
    ax.set_title(label1)

    ax = fig.add_subplot(gs[0, 1])
    im = basemap.pcolormesh(x, y, field2_interp, vmin=vmin, vmax=vmax, cmap=cmap, norm=bn)
    basemap.drawcoastlines(linewidth=common_plot_params.COASTLINE_WIDTH)
    ax.set_title(label2)

    plt.colorbar(im, cax=fig.add_subplot(gs[0, 2]))
    fig.tight_layout()
    fig.savefig(impath, dpi=common_plot_params.FIG_SAVE_DPI)