def testUsingSmallGrid(self):
        """
        Test using a small 5 by 5 grid

        Same data was used in FRUIT unit testing
        """

        input_fine_river_directions_test_field = field.makeField(self.input_fine_river_directions_test_data,
                                                                 field_type='RiverDirections',
                                                                 grid_type='LatLong',nlat=15,nlong=15)
        input_fine_total_cumulative_flow_test_field = field.makeField(self.input_fine_total_cumulative_flow_test_data,
                                                                      field_type='CumulativeFlow',
                                                                      grid_type='LatLong',nlat=15,nlong=15)
        cotat_params_text =\
            """
            &cotat_parameters
            MUFP = 1.5
            area_threshold = 9
            run_check_for_sinks = .True.
            /
            """
        with open(self.cotat_params_file_path,'w') as f:
            f.write(textwrap.dedent(cotat_params_text))
        output_coarse_river_directions = \
            cotat_plus_driver.run_cotat_plus(fine_rdirs_field=input_fine_river_directions_test_field,
                                             fine_total_cumulative_flow_field=\
                                             input_fine_total_cumulative_flow_test_field,
                                             cotat_plus_parameters_filepath=self.cotat_params_file_path,
                                             coarse_grid_type='LatLong',nlat=5,nlong=5)
        np.testing.assert_array_equal(output_coarse_river_directions.get_data(),
                                      self.small_grid_expected_result,
                                      "Running scaling code over small 5 by 5 grid doesn't"
                                      " produce expected results")
Example #2
0
def load_field(filename,file_type,field_type,unmask=True,timeslice=None,
               fieldname=None,check_for_grid_info=False,grid_type='HD',**grid_kwargs):
    """Inteface that loads a field as a raw array of data and returns it as a field object.

    Arguments:
    filename: string; the full path to the file to opened
    file_type: string; the code for this file type
    field_type: string; the code for this field type
    unmask (optional): boolean; flag to specifying whether the field is returned
            with any mask removed (True) or not (False)
    timeslice: integer; which timeslice to select from a (netCDF4) file with multiple time
        slices
    fieldname: string; which field to select from a (netCDF4) file with multiple fields
    check_for_grid_info: boolean; Search to see if file has grid info and use this
            to replace grid type specified if found
    grid_type: string; the code for this grid type
    **grid_kwargs: dictionary; key word arguments specifying parameters of the grid
    Returns:
    A field of object or an object of a field subclass

    Uses the getFileHelper pseudo-factory function to get the appropriate IOHelper subclass
    to load this file type and then uses this to loads the file; passing in any grid_kwargs
    supplied. Uses makeField factory function to create a field of the requested type with
    the loaded data and returns this object. Use a list to retrieve any grid information
    found by the loading function and add it to the field.
    """

    grid_info=[]
    raw_field = iohelper.getFileHelper(file_type).load_field(filename,unmask,timeslice,fieldname,
                                                             check_for_grid_info,grid_info,
                                                             grid_type,**grid_kwargs)
    if len(grid_info) == 0:
        return fld.makeField(raw_field,field_type,grid_type,**grid_kwargs)
    else:
        return fld.makeField(raw_field,field_type,grid_info[0])
def run_cotat_plus(fine_rdirs_field,fine_total_cumulative_flow_field,cotat_plus_parameters_filepath,
                   coarse_grid_type,**coarse_grid_kwargs):
    """Run the cotat plus fortran code using f2py for a lat-lon field

    Arguments:
    fine_rdirs_field: 2d ndarray; the fine river directions to be upscaled in 1-9 keypad format
    fine_total_cumulative_flow_field: 2d ndarray; the fine total cumulative flow (created from
        the fine_rdirs_field) to be used in upscaling
    cotat_plus_parameter_filepath: string; the file path containing the namelist with the parameters
        for the cotat plus upscaling algorithm
    coarse_grid_type: string; code for the coarse grid type to be upscaled to
    **coarse_grid_kwargs(optional): keyword dictionary; the parameter of the coarse grid to
        upscale to (if required)
    Return: 2d ndarray; the upscaled river direction on the coarse grid

    Compiles and runs the COTAT plus algorithm in Fortran using f2py for a lat-lon field
    """

    additional_fortran_filenames = ["base/area_mod.o",
                                    "base/coords_mod.o",
                                    "algorithms/cotat_parameters_mod.o",
                                    "algorithms/cotat_plus.o",
                                    "base/doubly_linked_list_mod.o",
                                    "base/doubly_linked_list_link_mod.o",
                                    "base/field_section_mod.o",
                                    "base/precision_mod.o",
                                    "base/subfield_mod.o",
                                    "algorithms/map_non_coincident_grids_mod.o",
                                    "base/unstructured_grid_mod.o"]
    additional_fortran_filepaths = [path.join(fortran_project_object_path,filename) for filename in\
                                    additional_fortran_filenames]
    f2py_mngr = f2py_manager.f2py_manager(path.join(fortran_project_source_path,
                                                    "drivers",
                                                    "cotat_plus_driver_mod.f90"),
                                          func_name="cotat_plus_latlon_f2py_wrapper",
                                          additional_fortran_files=additional_fortran_filepaths,
                                          include_path=fortran_project_include_path)
    coarse_grid = grid.makeGrid(coarse_grid_type,**coarse_grid_kwargs)
    if using_mpi():
        comm = MPI.COMM_WORLD
        comm.bcast(MPICommands.RUNCOTATPLUS, root=0)
    coarse_rdirs_field_raw = f2py_mngr.\
        run_current_function_or_subroutine(fine_rdirs_field.get_data().astype(np.int64,order='F'),
                                           fine_total_cumulative_flow_field.get_data().astype(np.int64,order='F'),
                                           cotat_plus_parameters_filepath,
                                           coarse_grid.get_grid_dimensions()[0],
                                           coarse_grid.get_grid_dimensions()[1])
    coarse_rdirs_field = field.makeField(coarse_rdirs_field_raw.astype(np.float64),'RiverDirections',coarse_grid_type,
                                         **coarse_grid_kwargs)
    if fine_rdirs_field.grid_has_coordinates():
      nlat_fine,nlon_fine = fine_rdirs_field.get_grid_dimensions()
      lat_pts_fine,lon_pts_fine = fine_rdirs_field.get_grid_coordinates()
      nlat_coarse,nlon_coarse = coarse_grid.get_grid_dimensions()
      lat_pts_coarse,lon_pts_coarse = \
        coordinate_scaling_utilities.generate_coarse_pts(nlat_fine,nlon_fine,
                                                         lat_pts_fine,lon_pts_fine,
                                                         nlat_coarse,nlon_coarse)
      coarse_rdirs_field.set_grid_coordinates([lat_pts_coarse,lon_pts_coarse])
    return coarse_rdirs_field
def follow_streams(rdirs_in, cumulative_flow):
    downstream_cells_out = np.zeros(rdirs_in.get_data().shape, dtype=np.int32)
    follow_streams_wrapper.follow_streams(rdirs_in.get_data(),
                                          cumulative_flow.\
                                          get_cells_with_loops().astype(np.int32),
                                          downstream_cells_out)
    return field.makeField(downstream_cells_out,
                           field_type="Generic",
                           grid_type=rdirs_in.get_grid())
    def testUsingSmallGrid(self):
        """
        Test using a small 5 by 5 grid as the coarse grid, 15 by 15 fine grid

        Same data was used in FRUIT unit testing
        """

        coarse_rdirs_field = field.makeField(self.coarse_rdirs,
                                             field_type='RiverDirections',
                                             grid_type='LatLong',
                                             nlat=5,
                                             nlong=5)
        coarse_cumulative_flow_field = field.makeField(
            self.coarse_cumulative_flow,
            field_type='CumulativeFlow',
            grid_type='LatLong',
            nlat=5,
            nlong=5)
        coarse_catchments_field = field.makeField(self.coarse_catchments,
                                                  field_type='Generic',
                                                  grid_type='LatLong',
                                                  nlat=15,
                                                  nlong=15)
        fine_rdirs_field = field.makeField(self.fine_rdirs,
                                           field_type='RiverDirections',
                                           grid_type='LatLong',
                                           nlat=15,
                                           nlong=15)
        fine_cumulative_flow_field = field.makeField(
            self.fine_cumulative_flow,
            field_type='CumulativeFlow',
            grid_type='LatLong',
            nlat=15,
            nlong=15)
        updated_output_coarse_river_directions =\
            loop_breaker_driver.run_loop_breaker(coarse_rdirs_field, coarse_cumulative_flow_field,
                                                 coarse_catchments_field, fine_rdirs_field,
                                                 fine_cumulative_flow_field, self.loop_nums_list,
                                                 coarse_grid_type='LatLong',nlat=5,nlong=5)
        np.testing.assert_array_equal(
            updated_output_coarse_river_directions.get_data(),
            self.expected_results,
            "Testing the loop breaking code with a small test grid doesn't give"
            " expected results")
Example #6
0
def advanced_flow_to_rivermouth_calculation_driver(input_river_directions_filename,
                                                   input_flow_to_cell_filename,
                                                   output_flow_to_river_mouths_filename,
                                                   input_river_directions_fieldname,
                                                   input_flow_to_cell_fieldname,
                                                   output_flow_to_river_mouths_fieldname):
    rdirs_field = iodriver.advanced_field_loader(input_river_directions_filename,
                                                 field_type="RiverDirections",
                                                 fieldname=input_river_directions_fieldname)
    flowtocell_field = iodriver.advanced_field_loader(input_flow_to_cell_filename,
                                                      field_type="CumulativeFlow",
                                                      fieldname=input_flow_to_cell_fieldname)
    rivermouth_field = field.makeField(rdirs_field.get_river_mouths(),'Generic',
                                       grid_type=rdirs_field.get_grid())
    flowtorivermouths_field = field.makeField(flowtocell_field.\
                                              find_cumulative_flow_at_outlets(rivermouth_field.\
                                                                              get_data()),
                                              field_type="Generic",
                                              grid_type=rdirs_field.get_grid())
    iodriver.advanced_field_writer(output_flow_to_river_mouths_filename,
                                   field=flowtorivermouths_field,
                                   fieldname=output_flow_to_river_mouths_fieldname)
Example #7
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))