コード例 #1
0
def main(rdirs_filename, output_filename, grid_type, **grid_kwargs):
    """Top level function for cumulative flow to cell flow map generation

    Inputs:
    rdir_filename: string; full path to the file contain the input river
        direction field
    output_filename: string; full path of the target file to write the
        generated cumulative flow to cell field to
    grid_type: string; a keyword specifying the grid type of the input
        and output fields
    **grid_kwargs (optional): keyword dictionary; any parameters of the
        input and output grid that are required
    Returns: Nothing
    """

    rdirs = iodriver.load_field(rdirs_filename,
                                iodriver.get_file_extension(rdirs_filename),
                                "Generic",
                                grid_type=grid_type,
                                **grid_kwargs)
    nlat, nlong = rdirs.get_grid().get_grid_dimensions()
    paths_map = field.Field(create_hypothetical_river_paths_map(
        riv_dirs=rdirs.get_data(),
        lsmask=None,
        use_f2py_func=True,
        use_f2py_sparse_iterator=True,
        nlat=nlat,
        nlong=nlong),
                            grid=grid_type,
                            **grid_kwargs)
    iodriver.write_field(output_filename, paths_map,
                         iodriver.get_file_extension(output_filename))
コード例 #2
0
def main(filename,
         output_filename,
         loop_logfile,
         use_cpp_code=True,
         grid_type='HD',
         **grid_kwargs):
    """Generates a file with numbered catchments from a given river flow direction file

    Inputs:
    filename: string; the input file of river directions
    output_filename: string; the target file for the output numbered catchments
    loop_logfile: string; an input file of catchments with loop to be updated
    use_cpp_alg: bool; use the Cpp code if True otherwise use the Fortran code
    grid_type: string; a keyword giving the type of grid being used
    **grid_kwargs(optional): keyword dictionary; the parameter of the grid to
    be used (if required)
    Returns: Nothing

    Produces the numbered catchments where the numbering is in descending order of size;
    also update the loop log file to reflect the relabelling of catchements and runs a
    check on the type of catchments generated (which are placed in a log file with the
    same basename as the output catchments but with the extension '.log').
    """

    rdirs = iodriver.load_field(
        filename,
        file_type=iodriver.get_file_extension(filename),
        field_type='Generic',
        grid_type=grid_type,
        **grid_kwargs)
    if use_cpp_code:
        catchments = compute_catchments_cpp(rdirs.get_data(), loop_logfile)
    else:
        catchment_types, catchments = compute_catchments(
            rdirs.get_data(), loop_logfile)
        check_catchment_types(catchment_types,
                              logfile=path.splitext(output_filename)[0] +
                              ".log")
    numbered_catchments = field.Field(renumber_catchments_by_size(
        catchments, loop_logfile),
                                      grid=grid_type,
                                      **grid_kwargs)
    iodriver.write_field(
        filename=output_filename,
        field=numbered_catchments,
        file_type=iodriver.get_file_extension(output_filename))
コード例 #3
0
def generate_orography_with_sinks_filled(input_orography_filename,output_orography_filename,
                                         ls_mask_filename=None,truesinks_filename=None,
                                         flip_ud=True,flip_lsmask_ud=True,
                                         flip_truesinks_ud=True,grid_type='HD',
                                         add_slight_slope_when_filling_sinks=True,
                                         slope_param=0.1,**grid_kwargs):
    """Generate an orography with the sinks filled using a priority flood type technique
    Input:
    input_orography_filename: string; the full path to the file containing the input orography
    output_orography_filename: string; the full path to the target file to write the output orography to
    ls_mask_filename: string; the full path to the file containing the input landsea mask.None means ignore.
    truesinks_filename: string; the full path to the file containing the true sinks to use. None means ignore.
    flip_ud: boolean; Flip the orography upside down before processing
    flip_lsmask_ud: boolean; Flip the landsea mask upside down before processing
    flip_truesinks_ud: boolean; Flip the true sinks upside down before processing
    grid_type: string; keyword for the grid type being used
    add_slight_slope_when_filling_sinks: boolean; a small increment to the height of each successive cell when
        filling a sink to give sink a slight slope
    slope_param: double; the small increment to add if adding a slight slope when fillings sinks
    **grid_kwargs: keyword dictionary; paramaters of the grid being used (if necessary)
    returns: nothing

    Load and manipulates necessary fields (making dummy field where necessary) then calls C++ sink
    filling algorithm through cython to perform actual sink filling and finally write out the result.
    """

    orography = iodriver.load_field(input_orography_filename,
                                    file_type=iodriver.get_file_extension(input_orography_filename),
                                    field_type='Orography', grid_type=grid_type,**grid_kwargs)
    if flip_ud:
        orography.flip_data_ud()
    grid_dims=orography.get_grid().get_grid_dimensions()
    if not truesinks_filename:
        truesinks = Field(np.empty((1,1),dtype=np.int32),grid='HD')
        use_true_sinks = False;
    else:
        use_true_sinks = True;
        truesinks = iodriver.load_field(truesinks_filename,
                                        file_type=iodriver.\
                                        get_file_extension(truesinks_filename),
                                        field_type='Generic', grid_type=grid_type,
                                        **grid_kwargs)
        if flip_truesinks_ud:
            truesinks.flip_data_ud()
    if ls_mask_filename is None:
        use_ls_mask = False
        ls_mask = Field(ls_mask = np.zeros(grid_dims,dtype=np.int32,order='C'),grid='LatLong',
                        nlat=grid_dims[0],nlon=grid_dims[1])
    else:
        use_ls_mask = True
        ls_mask = iodriver.load_field(ls_mask_filename,
                                      file_type=iodriver.get_file_extension(ls_mask_filename),
                                      field_type='Generic',grid_type=grid_type,**grid_kwargs)
        if flip_lsmask_ud:
            ls_mask.flip_data_ud()
    #Dtype change and ascontinguousarray must be applied here so orography keeps the correct
    #reference when running the C++ code
    orography.change_dtype(np.float64)
    orography.make_contiguous()
    fill_sinks_wrapper.fill_sinks_cpp_func(orography_array=orography.get_data(),
                                           method = 1,
                                           use_ls_mask = use_ls_mask,
                                           landsea_in = np.ascontiguousarray(ls_mask.get_data(),
                                                                             dtype=np.int32),
                                           set_ls_as_no_data_flag = False,
                                           use_true_sinks = use_true_sinks,
                                           true_sinks_in = np.ascontiguousarray(truesinks.get_data(),
                                                                                dtype=np.int32),
                                           add_slope =add_slight_slope_when_filling_sinks,
                                           epsilon = slope_param)
    iodriver.write_field(output_orography_filename,orography,
                         file_type=iodriver.get_file_extension(output_orography_filename))
コード例 #4
0
def generate_sinkless_flow_directions(filename,output_filename,ls_mask_filename=None,
                                      truesinks_filename=None,catchment_nums_filename=None,
                                      flip_ud=True,grid_type='HD',**grid_kwargs):
    """Generate sinkless flow directions from a given orography

    Input:
    filename: string; the full path to the file containing the input orography
    output_filename: string; the full target path for the output file the generated flow direction will
        be written to
    ls_mask_filename: string, the full path to the file containing the input landsea mask. None means ignore.
    truesinks_filename: string, the full path to the file containing the true sinks to use. None means ignore.
    flip_ud: boolean; If true flip the input fields upside down before processing...
        this affects the directions you get as it affects whether 7 8 9 is up and 1 2 3 is
        down or visa versa
    grid_type: string; keyword for the grid type being used
    **grid_kwargs: keyword dictionary; paramaters of the grid being used (if necessary)
    returns: nothing

    Loads the orography, creates an empty array for the river flow direction of the same size; either loads
    the landsea mask or makes a dummy field for this of the appropriate size (required for the interface to
    work correctly) and then passes this input to fill_sinks_cpp_func of Cython fill_sinks_wrapper to interface
    with the C++ code that actual generates the flow directions according to Algorithm 4 of Barnes et al (2014).
    Finally save the output river direction field.
    """

    orography = iodriver.load_field(filename,
                                    file_type=iodriver.get_file_extension(filename),
                                    field_type='Orography', grid_type=grid_type,**grid_kwargs)
    if flip_ud:
        orography.flip_data_ud()
    grid_dims=orography.get_grid().get_grid_dimensions()
    rdirs = np.zeros(grid_dims,dtype=np.float64,order='C')
    if not truesinks_filename:
        truesinks = Field(np.empty((1,1),dtype=np.int32),grid='HD')
        use_true_sinks = False;
    else:
        use_true_sinks = True;
        truesinks = iodriver.load_field(truesinks_filename,
                                        file_type=iodriver.\
                                        get_file_extension(truesinks_filename),
                                        field_type='Generic', grid_type=grid_type,
                                        **grid_kwargs)
        if flip_ud:
            truesinks.flip_data_ud()
    if ls_mask_filename is None:
        use_ls_mask = False
        ls_mask = np.zeros(grid_dims,dtype=np.int32,order='C')
    else:
        use_ls_mask = True
        ls_mask = iodriver.load_field(ls_mask_filename,
                                      file_type=iodriver.get_file_extension(ls_mask_filename),
                                      field_type='Generic',grid_type=grid_type,**grid_kwargs)
        if flip_ud:
            ls_mask.flip_data_ud()
    catchment_nums = np.zeros(grid_dims,dtype=np.int32,order='C')
    next_cell_lat_index_in = np.zeros(grid_dims,dtype=np.int32,order='C')
    next_cell_lon_index_in = np.zeros(grid_dims,dtype=np.int32,order='C')
    fill_sinks_wrapper.fill_sinks_cpp_func(orography_array=np.ascontiguousarray(orography.get_data(), #@UndefinedVariable
                                                                                dtype=np.float64),
                                           method = 4,
                                           use_ls_mask = use_ls_mask,
                                           landsea_in = np.ascontiguousarray(ls_mask.get_data(),
                                                                             dtype=np.int32),
                                           set_ls_as_no_data_flag = False,
                                           use_true_sinks = use_true_sinks,
                                           true_sinks_in = np.ascontiguousarray(truesinks.get_data(),
                                                                                dtype=np.int32),
                                           next_cell_lat_index_in = next_cell_lat_index_in,
                                           next_cell_lon_index_in = next_cell_lon_index_in,
                                           rdirs_in = rdirs,
                                           catchment_nums_in = catchment_nums,
                                           prefer_non_diagonal_initial_dirs = False)
    iodriver.write_field(output_filename,Field(rdirs,grid_type,**grid_kwargs),
                         file_type=iodriver.get_file_extension(output_filename))
    if catchment_nums_filename:
        iodriver.write_field(catchment_nums_filename,
                             field=Field(catchment_nums,grid_type,**grid_kwargs),
                             file_type=iodriver.get_file_extension(catchment_nums_filename))
コード例 #5
0
def main(rdirs_filepath,updatedrdirs_filepath,lsmask_filepath=None,
         flowtocell_filepath=None,rivermouths_filepath=None,
         flowtorivermouths_filepath=None,skip_marking_mouths=False,
         flip_mask_ud=False,grid_type='HD',**grid_kwargs):
    """Top level function to drive the river mouth marking process

    Arguments:
    rdirs_filepath: string; full path to input river directions file
    updatedrdirs_filepath: string; full path to target output river directions file
    lsmask_filepath(optional): string; full path to land sea mask filepath
    flowtocell_filepath(optional): string; full path to cumulative flow input file path. Requires
        flowtorivermouths_filepath to be defined for this option to be meaningful; if it is not
        will raise a warning
    rivermouths_filepath(optional): string; full path to optional target river mouths output
        file - if used this will create a file where the position of river mouths is marked
        True and all other points are marked false
    flowtorivermouths_filepath(optional): string; full path to optional target flow to river mouth
        output file that will contain 0 everywhere expect at river mouths where it will contain the
        cumulative flow to that river mouth
    skip_marking_mouths(optional): boolean; if this flag is set to True then don't mark river mouths
        and perform only the additional task otherwise (if it is False) proceed as normal
    flip_mask_ud: boolean; flip the landsea mask (if any) upside down before processing?
    grid_type: string; keyword specifying the grid type
    **grid_kwargs: dictionary of keyword arguments; parameters for the specified grid type if required
    Return: Nothing

    Additional tasks are producing a river mouths output file and producing a flow to river mouth output
    file.
    """

    #Load files
    rdirs_field = iodriver.load_field(filename=rdirs_filepath,
                                      file_type=iodriver.get_file_extension(rdirs_filepath),
                                      field_type="RiverDirections",
                                      grid_type=grid_type,**grid_kwargs)
    if lsmask_filepath:
        lsmask = iodriver.load_field(filename=lsmask_filepath,
                                     file_type=iodriver.get_file_extension(lsmask_filepath),
                                     field_type="Generic",
                                     grid_type=grid_type,**grid_kwargs)
        if flip_mask_ud:
            lsmask.flip_data_ud()
    else:
        lsmask = None

    if flowtocell_filepath:
        flowtocell_field = iodriver.load_field(filename=flowtocell_filepath,
                                               file_type=iodriver.get_file_extension(flowtocell_filepath),
                                               field_type="CumulativeFlow",
                                               grid_type=grid_type,**grid_kwargs)
    else:
        flowtocell_field = None

    if not skip_marking_mouths:
        #Perform the actual marking of river mouths
        rdirs_field.mark_river_mouths(lsmask.get_data() if lsmask is not None else None)

        #Write out the updated river directions field
        iodriver.write_field(filename=updatedrdirs_filepath,
                             field=rdirs_field,
                             file_type=iodriver.get_file_extension(updatedrdirs_filepath))

    #Perform any additional tasks if any: either making a seperate river mouths mask file or
    #generating a file with the cumulative flow to each river mouth or both (or potentially neither)
    if rivermouths_filepath or (flowtocell_field is not None):
        rivermouth_field = field.makeField(rdirs_field.get_river_mouths(),'Generic',grid_type,
                                           **grid_kwargs)
        if flowtocell_field is not None:
            if flowtorivermouths_filepath:
                flowtorivermouths_field = field.makeField(flowtocell_field.\
                                                          find_cumulative_flow_at_outlets(rivermouth_field.\
                                                                                          get_data()),
                                                          'Generic',grid_type,
                                                          **grid_kwargs)

                iodriver.write_field(flowtorivermouths_filepath,flowtorivermouths_field,
                                     file_type=iodriver.get_file_extension(flowtorivermouths_filepath))
            else:
                raise UserWarning("Flow to cell file specified but no target flow to river"
                                  " mouth target file defined; not processing the flow to"
                                  " cell field")
        if rivermouths_filepath:
            iodriver.write_field(rivermouths_filepath,rivermouth_field,
                                 file_type=iodriver.get_file_extension(rivermouths_filepath))
コード例 #6
0
def drive_orography_upscaling(input_fine_orography_file,
                              output_coarse_orography_file,
                              landsea_file=None,
                              true_sinks_file=None,
                              upscaling_parameters_filename=None,
                              fine_grid_type='LatLong10min',
                              coarse_grid_type='HD',
                              input_orography_field_name=None,
                              flip_landsea=False,
                              rotate_landsea=False,
                              flip_true_sinks=False,
                              rotate_true_sinks=False,
                              fine_grid_kwargs={},
                              **coarse_grid_kwargs):
    """Drive the C++ sink filling code base to make a tarasov-like orography upscaling

    Arguments:
    input_fine_orography_file: string; full path to input fine orography file
    output_coarse_orography_file: string; full path of target output coarse orography file
    landsea_file: string; full path to input fine landsea mask file (optional)
    true_sinks_file: string; full path to input fine true sinks file (optional)
    upscaling_parameters_filename: string; full path to the orography upscaling parameter
        file (optional)
    fine_grid_type: string; code for the fine grid type to be upscaled from  (optional)
    coarse_grid_type: string; code for the coarse grid type to be upscaled to (optional)
    input_orography_field_name: string; name of field in the input orography file (optional)
    flip_landsea: bool; flip the input landsea mask upside down
    rotate_landsea: bool; rotate the input landsea mask by 180 degrees along the horizontal axis
    flip_true_sinks: bool; flip the input true sinks field upside down
    rotate_true_sinks: bool; rotate the input true sinks field by 180 degrees along the
        horizontal axis
    fine_grid_kwargs:  keyword dictionary; the parameter of the fine grid to upscale
        from (if required)
    **coarse_grid_kwargs: keyword dictionary; the parameters of the coarse grid to upscale
        to (if required)
    Returns: Nothing.
    """

    if upscaling_parameters_filename:
        config = read_and_validate_config(upscaling_parameters_filename)
        method = config.getint("orography_upscaling_parameters", "method")
        add_slope_in = config.getboolean("orography_upscaling_parameters",
                                         "add_slope_in")
        epsilon_in = config.getfloat("orography_upscaling_parameters",
                                     "epsilon_in")
        tarasov_separation_threshold_for_returning_to_same_edge_in =\
            config.getint("orography_upscaling_parameters",
                          "tarasov_separation_threshold_for_returning_to_same_edge_in")
        tarasov_min_path_length_in = config.getfloat(
            "orography_upscaling_parameters", "tarasov_min_path_length_in")
        tarasov_include_corners_in_same_edge_criteria_in = \
            config.getboolean("orography_upscaling_parameters",
                              "tarasov_include_corners_in_same_edge_criteria_in")
    else:
        #use defaults
        method = 1
        add_slope_in = False
        epsilon_in = 0.1
        tarasov_separation_threshold_for_returning_to_same_edge_in = 5
        tarasov_min_path_length_in = 2.0
        tarasov_include_corners_in_same_edge_criteria_in = False
    output_orography = field.makeEmptyField(field_type='Orography',
                                            dtype=np.float64,
                                            grid_type=coarse_grid_type,
                                            **coarse_grid_kwargs)
    input_orography = iodriver.load_field(
        input_fine_orography_file,
        file_type=get_file_extension(input_fine_orography_file),
        field_type='Orography',
        unmask=True,
        fieldname=input_orography_field_name,
        grid_type=fine_grid_type,
        **fine_grid_kwargs)
    if landsea_file:
        landsea_mask = iodriver.load_field(
            landsea_file,
            file_type=get_file_extension(landsea_file),
            field_type='Generic',
            unmask=True,
            grid_type=fine_grid_type,
            **fine_grid_kwargs)
        if flip_landsea:
            landsea_mask.flip_data_ud()
        if rotate_landsea:
            landsea_mask.rotate_field_by_a_hundred_and_eighty_degrees()
    else:
        landsea_mask = field.makeEmptyField(field_type='Generic',
                                            dtype=np.int32,
                                            grid_type=fine_grid_type,
                                            **fine_grid_kwargs)
    if true_sinks_file:
        true_sinks = iodriver.load_field(
            true_sinks_file,
            file_type=get_file_extension(true_sinks_file),
            field_type='Generic',
            unmask=True,
            grid_type=fine_grid_type,
            **fine_grid_kwargs)
        if flip_true_sinks:
            true_sinks.flip_data_ud()
        if rotate_true_sinks:
            true_sinks.rotate_field_by_a_hundred_and_eighty_degrees()
    else:
        true_sinks = field.makeEmptyField(field_type='Generic',
                                          dtype=np.int32,
                                          grid_type=fine_grid_type,
                                          **fine_grid_kwargs)
    if not np.issubdtype(input_orography.get_data().dtype, np.float64()):
        input_orography.change_dtype(np.float64)
        #Make sure old data type array is flushed out of memory immediately
        gc.collect()
    upscale_orography_wrapper.upscale_orography(orography_in=input_orography.get_data(),
                                                orography_out=output_orography.get_data(),
                                                method=method,landsea_in=landsea_mask.get_data(),
                                                true_sinks_in=true_sinks.get_data(),
                                                add_slope_in=add_slope_in, epsilon_in=epsilon_in,
                                                tarasov_separation_threshold_for_returning_to_same_edge_in=\
                                                tarasov_separation_threshold_for_returning_to_same_edge_in,
                                                tarasov_min_path_length_in=tarasov_min_path_length_in,
                                                tarasov_include_corners_in_same_edge_criteria_in=\
                                                tarasov_include_corners_in_same_edge_criteria_in)
    iodriver.write_field(
        output_coarse_orography_file,
        output_orography,
        file_type=get_file_extension(output_coarse_orography_file))