Exemple #1
0
def test_iteritems():
    d = {'a': 0, 'b': 1, 'c': 2}
    for k, v in iteritems(d):
        assert type(k) == str
        assert type(v) == int
Exemple #2
0
def rasm_soil(data, soil_file):
    """Write VIC formatted soil parameter file"""

    message = """
*** ---------------------------------------------------------------------- ***
Notes about RASM soil parameter file generations:
 - To fill in missing grid cells 'mask' variable must be the same as the
   domain file mask.
 - Inactive grid cells will have a dummy line printed for all variables except
   the lons/lats.
 - Any grid cells with nans will be copied from the previous line without nans
   or FILL_VALUEs.
*** --------------------------------------------------------------------- ***\n
    """

    print(message)

    # ---------------------------------------------------------------- #
    c = grid_params.cols(nlayers=3)
    f = grid_params.format(nlayers=3)

    c.soil_param['Nveg'] = np.array([0])
    f.soil_param['Nveg'] = '%1i'

    numcells = data['mask'].size

    arrayshape = (numcells, 1 +
                  np.max([np.max(cols)
                          for v, cols in iteritems(c.soil_param)]))
    soil_params = np.empty(arrayshape)
    dtypes = ['%1i'] * arrayshape[1]
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # find nearest real grid cell for all grid cells where frozen soil mask is
    # active
    # This is needed because the RASM mask is often different than existing
    # datasets
    print('Finding/filling nearest neighbors for all variables based on '
          'fs_active mask')

    # real mask (from input dataset)
    ry, rx = np.nonzero(data['fs_active'])

    # fill mask (we will fill all of these grid cells with their nearest real
    # value)
    my_mask = np.zeros(data['fs_active'].shape, dtype=int)
    my_mask[ry, rx] = 1

    fy, fx = np.nonzero(my_mask == 0)

    # Find nearest real grid cell
    combined = np.dstack(([data['yc'][ry, rx], data['xc'][ry, rx]]))[0]
    points = list(
        np.vstack((data['yc'][fy, fx], data['xc'][fy, fx])).transpose())
    mytree = cKDTree(combined)
    dist, inds = mytree.query(points, k=1)

    # loop over all variables and fill in values
    for var in c.soil_param:
        if var not in [
                'run_cell', 'grid_cell', 'lats', 'lons', 'fs_active', 'Nveg'
        ]:
            # unmask the variable
            data[var] = np.array(data[var])
            # fill with nearest data
            if data[var].ndim == 2:
                data[var][fy, fx] = data[var][ry[inds], rx[inds]]
            elif data[var].ndim == 3:
                data[var][:, fy, fx] = data[var][:, ry[inds], rx[inds]]
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # This is the domain mask
    yinds, xinds = np.nonzero(data['mask'] == 1)
    ymask, xmask = np.nonzero(data['mask'] == 0)
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # Fix problematic avg_T values
    print('Finding/filling nearest neighbors for avg_T\n')

    # real mask (from input dataset)
    ry, rx = np.nonzero((data['avg_T'] > -50) & (data['avg_T'] < 99))

    # fill mask (we will fill all of these grid cells with their nearest
    # real value)
    my_mask = np.zeros(data['avg_T'].shape)
    my_mask[ry, rx] = 1

    fy, fx = np.nonzero(my_mask == 0)

    # Find nearest real grid cell
    if len(fy) > 0:
        combined = np.dstack(([data['yc'][ry, rx], data['xc'][ry, rx]]))[0]
        points = list(
            np.vstack((data['yc'][fy, fx], data['xc'][fy, fx])).transpose())
        mytree = cKDTree(combined)
        dist, inds = mytree.query(points, k=1)

        data['avg_T'] = np.array(data['avg_T'])
        data['avg_T'][fy, fx] = data['avg_T'][ry[inds], rx[inds]]
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # For rasm, all cols are shifted one to right to make room for nveg in
    # col 0
    i = -1
    for var, cols in iteritems(c.soil_param):
        for col in cols:
            dtypes[col] = f.soil_param[var]

    for (y, x), maskval in np.ndenumerate(data['mask']):
        # advance the row count
        i += 1

        # put real data
        for var in c.soil_param:
            cols = c.soil_param[var]
            if data[var].ndim == 2:
                soil_params[i, cols] = data[var][y, x]
            elif data[var].ndim == 3:
                for j, col in enumerate(cols):
                    soil_params[i, col] = data[var][j, y, x]

        # write the grid cell number
        soil_params[i, 2] = i + 1
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # Write phi_s
    soil_params[:, c.soil_param['phi_s']] = -999
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # Write nveg
    soil_params[:, 0] = data['Nveg'][:, :].flatten()
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # Set all grid cells to run
    soil_params[:, 1] = 1  # run
    soil_params[:, -1] = 1  # run with frozen soils on
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # rewrite the lons/lats columns
    soil_params[:, 3] = data['lats'].flatten()
    soil_params[:, 4] = data['lons'].flatten()

    assert soil_params[-1, 3] == data['lats'][y, x]
    assert soil_params[-1, 4] == data['lons'][y, x]
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # check for nans
    # sometimes RASM has land grid cells that the input file does not.
    # In this case, we will use the previous lnd grid cell
    if np.isnan(soil_params.sum()):
        bad_cells = []
        replacements = []
        for i, cell in enumerate(soil_params):
            if np.isnan(np.sum(cell)):
                bad_cells.append(i)
                j = i
                while True:
                    j -= 1
                    if (FILL_VALUE not in soil_params[j, :]) and \
                            not np.isnan(np.sum(soil_params[j, :])):
                        soil_params[i, 5:] = soil_params[j, 5:]
                        replacements.append(j)
                        break
        print('Fixed {0} bad cells'.format(len(bad_cells)))
        print('Example: {0}-->{1}'.format(bad_cells[0], replacements[0]))
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # Print summary of variables
    for var, cols in iteritems(c.soil_param):
        print('{0: <12}--> min: {1:<09.3f}, max: {2:<09.3f}, mean:'
              ' {3:<09.3f}'.format(var, soil_params[:, cols].min(),
                                   soil_params[:, cols].max(),
                                   soil_params[:, cols].mean()))
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # Finish up
    assert soil_params[-1, 3] == data['lats'][y, x]
    assert soil_params[-1, 4] == data['lons'][y, x]
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # Write the file
    print('writing soil parameter file: {0}'.format(soil_file))

    np.savetxt(soil_file, soil_params, fmt=dtypes)

    print('done RASM with soil')
    # ---------------------------------------------------------------- #

    return
Exemple #3
0
def rasm_soil(data, soil_file):
    """Write VIC formatted soil parameter file"""

    message = """
*** ---------------------------------------------------------------------- ***
Notes about RASM soil parameter file generations:
 - To fill in missing grid cells 'mask' variable must be the same as the
   domain file mask.
 - Inactive grid cells will have a dummy line printed for all variables except
   the lons/lats.
 - Any grid cells with nans will be copied from the previous line without nans
   or FILL_VALUEs.
*** --------------------------------------------------------------------- ***\n
    """

    print(message)

    # ---------------------------------------------------------------- #
    c = grid_params.cols(nlayers=3)
    f = grid_params.format(nlayers=3)

    c.soil_param['Nveg'] = np.array([0])
    f.soil_param['Nveg'] = '%1i'

    numcells = data['mask'].size

    arrayshape = (numcells, 1 + np.max([np.max(cols) for v, cols in
                                        iteritems(c.soil_param)]))
    soil_params = np.empty(arrayshape)
    dtypes = ['%1i'] * arrayshape[1]
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # find nearest real grid cell for all grid cells where frozen soil mask is
    # active
    # This is needed because the RASM mask is often different than existing
    # datasets
    print('Finding/filling nearest neighbors for all variables based on '
          'fs_active mask')

    # real mask (from input dataset)
    ry, rx = np.nonzero(data['fs_active'])

    # fill mask (we will fill all of these grid cells with their nearest real
    # value)
    my_mask = np.zeros(data['fs_active'].shape, dtype=int)
    my_mask[ry, rx] = 1

    fy, fx = np.nonzero(my_mask == 0)

    # Find nearest real grid cell
    combined = np.dstack(([data['yc'][ry, rx], data['xc'][ry, rx]]))[0]
    points = list(np.vstack((data['yc'][fy, fx],
                             data['xc'][fy, fx])).transpose())
    mytree = cKDTree(combined)
    dist, inds = mytree.query(points, k=1)

    # loop over all variables and fill in values
    for var in c.soil_param:
        if var not in ['run_cell', 'grid_cell', 'lats', 'lons', 'fs_active',
                       'Nveg']:
            # unmask the variable
            data[var] = np.array(data[var])
            # fill with nearest data
            if data[var].ndim == 2:
                data[var][fy, fx] = data[var][ry[inds], rx[inds]]
            elif data[var].ndim == 3:
                data[var][:, fy, fx] = data[var][:, ry[inds], rx[inds]]
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # This is the domain mask
    yinds, xinds = np.nonzero(data['mask'] == 1)
    ymask, xmask = np.nonzero(data['mask'] == 0)
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # Fix problematic avg_T values
    print('Finding/filling nearest neighbors for avg_T\n')

    # real mask (from input dataset)
    ry, rx = np.nonzero((data['avg_T'] > -50) & (data['avg_T'] < 99))

    # fill mask (we will fill all of these grid cells with their nearest
    # real value)
    my_mask = np.zeros(data['avg_T'].shape)
    my_mask[ry, rx] = 1

    fy, fx = np.nonzero(my_mask == 0)

    # Find nearest real grid cell
    if len(fy) > 0:
        combined = np.dstack(([data['yc'][ry, rx], data['xc'][ry, rx]]))[0]
        points = list(np.vstack((data['yc'][fy, fx],
                                 data['xc'][fy, fx])).transpose())
        mytree = cKDTree(combined)
        dist, inds = mytree.query(points, k=1)

        data['avg_T'] = np.array(data['avg_T'])
        data['avg_T'][fy, fx] = data['avg_T'][ry[inds], rx[inds]]
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # For rasm, all cols are shifted one to right to make room for nveg in
    # col 0
    i = -1
    for var, cols in iteritems(c.soil_param):
        for col in cols:
            dtypes[col] = f.soil_param[var]

    for (y, x), maskval in np.ndenumerate(data['mask']):
        # advance the row count
        i += 1

        # put real data
        for var in c.soil_param:
            cols = c.soil_param[var]
            if data[var].ndim == 2:
                soil_params[i, cols] = data[var][y, x]
            elif data[var].ndim == 3:
                for j, col in enumerate(cols):
                    soil_params[i, col] = data[var][j, y, x]

        # write the grid cell number
        soil_params[i, 2] = i + 1
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # Write phi_s
    soil_params[:, c.soil_param['phi_s']] = -999
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # Write nveg
    soil_params[:, 0] = data['Nveg'][:, :].flatten()
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # Set all grid cells to run
    soil_params[:, 1] = 1  # run
    soil_params[:, -1] = 1  # run with frozen soils on
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # rewrite the lons/lats columns
    soil_params[:, 3] = data['lats'].flatten()
    soil_params[:, 4] = data['lons'].flatten()

    assert soil_params[-1, 3] == data['lats'][y, x]
    assert soil_params[-1, 4] == data['lons'][y, x]
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # check for nans
    # sometimes RASM has land grid cells that the input file does not.
    # In this case, we will use the previous lnd grid cell
    if np.isnan(soil_params.sum()):
        bad_cells = []
        replacements = []
        for i, cell in enumerate(soil_params):
            if np.isnan(np.sum(cell)):
                bad_cells.append(i)
                j = i
                while True:
                    j -= 1
                    if (FILL_VALUE not in soil_params[j, :]) and \
                            not np.isnan(np.sum(soil_params[j, :])):
                        soil_params[i, 5:] = soil_params[j, 5:]
                        replacements.append(j)
                        break
        print('Fixed {0} bad cells'.format(len(bad_cells)))
        print('Example: {0}-->{1}'.format(bad_cells[0], replacements[0]))
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # Print summary of variables
    for var, cols in iteritems(c.soil_param):
        print('{0: <12}--> min: {1:<09.3f}, max: {2:<09.3f}, mean:'
              ' {3:<09.3f}'.format(var,
                                   soil_params[:, cols].min(),
                                   soil_params[:, cols].max(),
                                   soil_params[:, cols].mean()))
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # Finish up
    assert soil_params[-1, 3] == data['lats'][y, x]
    assert soil_params[-1, 4] == data['lons'][y, x]
    # ---------------------------------------------------------------- #

    # ---------------------------------------------------------------- #
    # Write the file
    print('writing soil parameter file: {0}'.format(soil_file))

    np.savetxt(soil_file, soil_params, fmt=dtypes)

    print('done RASM with soil')
    # ---------------------------------------------------------------- #

    return