Beispiel #1
0
def test_get_coordinates():
    ncs = [local_path(TESTDATA['cordex_tasmax_2006_nc']),
           local_path(TESTDATA['cordex_tasmax_2007_nc'])]

    lats, lons = utils.get_coordinates(ncs, unrotate=False)

    assert 1 == len(lats.shape)

    lats, lons = utils.get_coordinates(ncs)
    assert 103 == len(lats)
    assert 106 == len(lons)
Beispiel #2
0
def fieldmean(resource):
    """
    calculating of a weighted field mean

    :param resource: str or list of str containing the netCDF files pathes

    :return list: averaged values
    """
    from flyingpigeon.utils import get_values, get_coordinates
    from numpy import radians, average, cos, sqrt

    data = get_values(resource)  # np.squeeze(ds.variables[variable][:])
    dim = data.shape
    if len(data.shape) == 3:
        # TODO if data.shape == 2 , 4 ...

        lats, lons = get_coordinates(resource, unrotate=True)

        if len(lats.shape) == 2:
            # TODO: calcult weighed average with 2D lats (rotated pole coordinates)
            lats, lons = get_coordinates(resource)

        if dim[0] == len(lats):
            lat_index = 0
        elif dim[1] == len(lats):
            lat_index = 1
        elif dim[2] == len(lats):
            lat_index = 2
        else:
            LOGGER.exception(
                'length of latitude is not matching values dimensions')

        lat_w = sqrt(cos(lats * radians(1)))
        meanLon = average(data, axis=lat_index, weights=lat_w)
        meanTimeserie = average(meanLon, axis=1)
        print('fieldmean calculated')
    else:
        print('not 3D shaped data. Average can not be calculated')
    return meanTimeserie
Beispiel #3
0
def plot_extend(resource, file_extension='png'):
    """
    plots the extend (domain) of the values stored in a netCDF file:

    :parm resource: path to netCDF file
    :param file_extension: file format of the graphic. if file_extension=None a matplotlib figure will be returned

    :return graphic: graphic in specified format
    """
    import matplotlib.patches as mpatches
    lats, lons = utils.get_coordinates(resource, unrotate=True)

    # box_top = 45
    # x, y = [-20, -20, 45, 45, -44], [-45, box_top, box_top, -45, -45]

    xy = np.array([[np.min(lons), np.min(lats)],
                   [np.max(lons), np.min(lats)],
                   [np.max(lons), np.max(lats)],
                   [np.min(lons), np.max(lats)]])

    fig = plt.figure(figsize=(20, 10), dpi=600, facecolor='w', edgecolor='k')
    projection = ccrs.Robinson()

    #  ccrs.Orthographic(central_longitude=np.mean(xy[:, 0]),
    #  central_latitude=np.mean(xy[:, 1]),
    #  globe=None)  # Robinson()

    ax = plt.axes(projection=projection)
    ax.stock_img()
    ax.coastlines()
    ax.add_patch(mpatches.Polygon(xy, closed=True,  transform=ccrs.PlateCarree(), color='coral', alpha=0.6))
    # ccrs.Geodetic()
    ax.gridlines()
    plt.show()

    if file_extension is None:
        map_graphic = fig
    else:
        map_graphic = fig2plot(fig=fig, file_extension=file_extension)
    plt.close()

    return map_graphic
Beispiel #4
0
def get_PAmask(coordinates=[], nc=None):
    """
    generates a matrix with 1/0 values over land areas. (NaN for water regions)

    :param coordinates: 2D array with lat lon coordinates representing tree observation
    :param domain: region (default='EUR-11')

    :return : PAmask
    """
    from scipy import spatial
    import numpy as np
    import numpy.ma as ma

#    from netCDF4 import Dataset
#    from flyingpigeon import config
#    DIR_MASKS = config.masks_dir()

    from flyingpigeon.utils import get_variable
    from flyingpigeon.utils import get_coordinates, get_values  # unrotate_pole,

    lats, lons = np.array(get_coordinates(nc))  # unrotate_pole(nc, write_to_file=False))
    sftlf = get_values(nc)[0, :, :]
    #
    # sftlf[sftlf.mask is True] = 0
    # sftlf[sftlf.mask is False] = np.nan

    domain = sftlf.shape

    lats1D = np.array(lats).ravel()
    lons1D = np.array(lons).ravel()
    tree = spatial.KDTree(zip(lats1D, lons1D))
    l, i = tree.query(coordinates)

    PA = np.zeros(len(lats1D))
    PA[i] = 1
    #
    PAmask = PA.reshape(domain)
    PAmask[sftlf.mask] = np.nan

    return PAmask
Beispiel #5
0
def fieldmean(resource):
    """
    calculating of a weighted field mean

    :param resource: str or list of str containing the netCDF files pathes

    :return list: timeseries of the averaged values per timepstep
    """
    from flyingpigeon.utils import get_values, get_coordinates, get_index_lat
    from numpy import radians, average, cos, sqrt, array

    data = get_values(resource)  # np.squeeze(ds.variables[variable][:])
    dim = data.shape
    LOGGER.debug(data.shape)

    if len(data.shape) == 3:
        # TODO if data.shape == 2 , 4 ...
        lats, lons = get_coordinates(resource, unrotate=False)
        lats = array(lats)
        if len(lats.shape) == 2:
            lats = lats[:, 0]
        else:
            LOGGER.debug('Latitudes not reduced to 1D')
        # TODO: calculat weighed average with 2D lats (rotated pole coordinates)
        # lats, lons = get_coordinates(resource, unrotate=False)
        # if len(lats.shape) == 2:
        #     lats, lons = get_coordinates(resource)

        lat_index = get_index_lat(resource)
        LOGGER.debug('lats dimension %s ' % len(lats.shape))
        LOGGER.debug('lats index %s' % lat_index)

        lat_w = sqrt(cos(lats * radians(1)))
        meanLon = average(data, axis=lat_index, weights=lat_w)
        meanTimeserie = average(meanLon, axis=1)
        LOGGER.debug('fieldmean calculated')
    else:
        LOGGER.error('not 3D shaped data. Average can not be calculated')
    return meanTimeserie
Beispiel #6
0
def map_spatial_analog(ncfile, variable='dissimilarity', cmap='viridis', title='Spatial analog'):
    """Return a matplotlib Figure instance showing a map of the dissimilarity measure.
    """
    import netCDF4 as nc
    from flyingpigeon import utils
    from mpl_toolkits.axes_grid import make_axes_locatable
    import matplotlib.axes as maxes

    try:
        var = utils.get_values(ncfile, variable)
        LOGGER.info('Data loaded')

        lats, lons = utils.get_coordinates(ncfile, variable=variable, unrotate=False)

        if len(lats.shape) == 1:
            cyclic_var, cyclic_lons = add_cyclic_point(var, coord=lons)

            lons = cyclic_lons.data
            var = cyclic_var

        with nc.Dataset(ncfile) as D:
            V = D.variables[variable]
            lon, lat = map(float, V.target_location.split(','))

        LOGGER.info('Lat and lon loaded')

    except Exception as e:
        msg = 'Failed to get data for plotting: {0}\n{1}'.format(ncfile, e)
        LOGGER.exception(msg)
        raise Exception(msg)

    try:
        fig = plt.figure(facecolor='w', edgecolor='k')
        fig.subplots_adjust(top=.95, bottom=.05, left=.03, right=.95)

        ax = plt.axes(
            projection=ccrs.Robinson(central_longitude=int(np.mean(lons))))

        divider = make_axes_locatable(ax)
        cax = divider.new_horizontal("4%", pad=0.15, axes_class=maxes.Axes)
        fig.add_axes(cax)

        ax.plot(lon, lat, marker='o', mfc='#292421', ms=13, transform=ccrs.PlateCarree())
        ax.plot(lon, lat, marker='o', mfc='#ffffff', ms=7, transform=ccrs.PlateCarree())

        cs = ax.contourf(lons, lats, var, 60,
                         transform=ccrs.PlateCarree(),
                         cmap=cmap, interpolation='nearest')

        ax.coastlines(color='k', linewidth=.8)
        ax.set_title(title)

        cb = plt.colorbar(cs, cax=cax, orientation='vertical')
        cb.set_label(u"–            Dissimilarity             +")  # ha='left', va='center')
        cb.set_ticks([])

    except:
        msg = 'failed to plot graphic'
        LOGGER.exception(msg)

    LOGGER.info('Plot created and figure saved')
    return fig
Beispiel #7
0
def map_robustness(signal, high_agreement_mask, low_agreement_mask,
                   variable=None, cmap='seismic', title=None,
                   file_extension='png'):
    """
    generates a graphic for the output of the ensembleRobustness process for a lat/long file.

    :param signal: netCDF file containing the signal difference over time
    :param highagreement:
    :param lowagreement:
    :param variable:
    :param cmap: default='seismic',
    :param title: default='Model agreement of signal'
    :returns str: path/to/file.png
    """
    from flyingpigeon import utils
    from numpy import mean, ma

    if variable is None:
        variable = utils.get_variable(signal)

    try:
        var_signal = utils.get_values(signal)
        mask_l = utils.get_values(low_agreement_mask)
        mask_h = utils.get_values(high_agreement_mask)

        # mask_l = ma.masked_where(low < 0.5, low)
        # mask_h = ma.masked_where(high < 0.5, high)
        # mask_l[mask_l == 0] = np.nan
        # mask_h[mask_h == 0] = np.nan

        LOGGER.info('data loaded')

        lats, lons = utils.get_coordinates(signal, unrotate=True)

        if len(lats.shape) == 1:
            cyclic_var, cyclic_lons = add_cyclic_point(var_signal, coord=lons)
            mask_l, cyclic_lons = add_cyclic_point(mask_l, coord=lons)
            mask_h, cyclic_lons = add_cyclic_point(mask_h, coord=lons)

            lons = cyclic_lons.data
            var_signal = cyclic_var

        LOGGER.info('lat lon loaded')

        minval = round(np.nanmin(var_signal))
        maxval = round(np.nanmax(var_signal)+.5)

        LOGGER.info('prepared data for plotting')
    except:
        msg = 'failed to get data for plotting'
        LOGGER.exception(msg)
        raise Exception(msg)

    try:
        fig = plt.figure(facecolor='w', edgecolor='k')

        ax = plt.axes(projection=ccrs.Robinson(central_longitude=int(mean(lons))))
        norm = MidpointNormalize(midpoint=0)

        cs = plt.contourf(lons, lats, var_signal, 60, norm=norm, transform=ccrs.PlateCarree(),
                          cmap=cmap, interpolation='nearest')

        cl = plt.contourf(lons, lats, mask_l, 1, transform=ccrs.PlateCarree(), colors='none', hatches=[None, '/'])
        ch = plt.contourf(lons, lats, mask_h, 1, transform=ccrs.PlateCarree(), colors='none', hatches=[None, '.'])
        # artists, labels = ch.legend_elements()
        # plt.legend(artists, labels, handleheight=2)
        # plt.clim(minval,maxval)
        ax.coastlines()
        ax.gridlines()
        # ax.set_global()

        if title is None:
            plt.title('%s with Agreement' % variable)
        else:
            plt.title(title)
        plt.colorbar(cs)

        plt.annotate('// = low model ensemble agreement', (0, 0), (0, -10),
                     xycoords='axes fraction', textcoords='offset points', va='top')
        plt.annotate('..  = high model ensemble agreement', (0, 0), (0, -20),
                     xycoords='axes fraction', textcoords='offset points', va='top')

        graphic = fig2plot(fig=fig, file_extension=file_extension)
        plt.close()

        LOGGER.info('Plot created and figure saved')
    except:
        msg = 'failed to plot graphic'
        LOGGER.exception(msg)

    return graphic
Beispiel #8
0
def map_robustness(signal,
                   high_agreement_mask,
                   low_agreement_mask,
                   cmap='seismic',
                   title=None):
    """
    generates a graphic for the output of the ensembleRobustness process for a lat/long file.

    :param signal: netCDF file containing the signal difference over time
    :param highagreement:
    :param lowagreement:
    :param variable:
    :param cmap: default='seismic',
    :param title: default='Model agreement of signal'
    :returns str: path/to/file.png
    """

    try:
        # from flyingpigeon.utils import get_values
        from cartopy.util import add_cyclic_point
        # from flyingpigeon.utils import get_coordinates

        var_signal = utils.get_values(signal)
        mask_l = utils.get_values(low_agreement_mask)
        mask_h = utils.get_values(high_agreement_mask)

        mask_l.mask = var_signal.mask
        mask_h.mask = var_signal.mask

        mask_l.mask[mask_l.data is 0] = False
        mask_h.mask[mask_h.data is 0] = False

        LOGGER.debug('values loaded')

        lats, lons = utils.get_coordinates(signal)

        #
        # cyclic_var, cyclic_lons = add_cyclic_point(var_signal, coord=lons)
        # mask_l, cyclic_lons = add_cyclic_point(mask_l, coord=lons)
        # mask_h, cyclic_lons = add_cyclic_point(mask_h, coord=lons)
        #
        # lons = cyclic_lons.data
        # var_signal = cyclic_var
        #
        LOGGER.debug('coordinates loaded')
        #
        minval = round(np.nanmin(var_signal))
        maxval = round(np.nanmax(var_signal) + .5)

        LOGGER.info('prepared data for plotting')
    except:
        msg = 'failed to get data for plotting'
        LOGGER.exception(msg)

    try:
        fig = plt.figure(facecolor='w',
                         edgecolor='k')  # figsize=(20,10), dpi=600,
        ax = plt.axes(projection=ccrs.Robinson(central_longitude=0))
        norm = MidpointNormalize(midpoint=0)

        cs = plt.contourf(lons,
                          lats,
                          var_signal,
                          60,
                          transform=ccrs.PlateCarree(),
                          norm=norm,
                          cmap=cmap,
                          interpolation='nearest')
        cl = plt.contourf(lons,
                          lats,
                          mask_l,
                          60,
                          transform=ccrs.PlateCarree(),
                          colors='none',
                          hatches=['//'])
        ch = plt.contourf(lons,
                          lats,
                          mask_h,
                          60,
                          transform=ccrs.PlateCarree(),
                          colors='none',
                          hatches=['.'])

        # plt.clim(minval, maxval)
        ax.coastlines()
        # ax.set_global()

        if title is None:
            plt.title('Robustness')
        else:
            plt.title(title)

        plt.colorbar(cs)

        plt.annotate('// = low model ensemble agreement', (0, 0), (0, -10),
                     xycoords='axes fraction',
                     textcoords='offset points',
                     va='top')
        plt.annotate('..  = high model ensemble agreement', (0, 0), (0, -20),
                     xycoords='axes fraction',
                     textcoords='offset points',
                     va='top')

        _, graphic = mkstemp(dir='.', suffix='.png')
        fig.savefig(graphic)
        plt.close()

        LOGGER.info('Plot created and figure saved')
    except:
        msg = 'failed to plot graphic'
        LOGGER.exception(msg)
        _, graphic = mkstemp(dir='.', suffix='.png')
    return graphic