Пример #1
0
def test_get_values():
    values = nc_utils.get_values(local_path(TESTDATA['cmip5_tasmax_2007_nc']))
    assert 12 == len(values)

    values = nc_utils.get_values(local_path(TESTDATA['cordex_tasmax_2007_nc']))
    assert 12 == len(values)

    values = nc_utils.get_values([local_path(TESTDATA['cordex_tasmax_2006_nc']),
                                 local_path(TESTDATA['cordex_tasmax_2007_nc'])])
    assert 23 == len(values)
    def _handler(self, request, response):
        # init_process_logger('log.txt')
        # response.outputs['output_log'].file = 'log.txt'
        ncs = extract_archive(
            resources=[inpt.file for inpt in request.inputs['resource']],
            dir_output=self.workdir)
        LOGGER.info('ncs: {}'.format(ncs))

        coords = []
        for coord in request.inputs['coords']:
            coords.append(coord.data)

        LOGGER.info('coords {}'.format(coords))
        filenames = []
        nc_exp = sort_by_filename(ncs, historical_concatination=True)

        for key in nc_exp.keys():
            try:
                LOGGER.info('start calculation for {}'.format(key))
                ncs = nc_exp[key]
                times = get_time(ncs)
                concat_vals = times
                header = 'date_time'
                filename = join(self.workdir, '{}.csv'.format(key))
                filenames.append(filename)

                for p in coords:
                    try:
                        response.update_status('processing point: {}'.format(p), 20)
                        # define the point:
                        p = p.split(',')
                        point = Point(float(p[0]), float(p[1]))

                        # get the values
                        timeseries = call(resource=ncs, geom=point, select_nearest=True, dir_output=self.workdir)
                        vals = get_values(timeseries)

                        # concatenation of values
                        header = header + ',{}-{}'.format(p[0], p[1])
                        concat_vals = column_stack([concat_vals, vals])
                    except Exception as e:
                        LOGGER.debug('failed for point {} {}'.format(p, e))
                response.update_status('*** all points processed for {0} ****'.format(key), 50)

                # TODO: Ascertain whether this 'savetxt' is a valid command without string formatting argument: '%s'
                savetxt(filename, concat_vals, fmt='%s', delimiter=',', header=header)
            except Exception as ex:
                LOGGER.debug('failed for {}: {}'.format(key, str(ex)))

        # set the outputs
        response.update_status('*** creating output tar archive ****', 90)
        tarout_file = archive(filenames, dir_output=self.workdir)
        response.outputs['tarout'].file = tarout_file
        return response
Пример #3
0
def fieldmean(resource):
    """
    calculating of a weighted field mean

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

    :return list: timeseries of the averaged values per timestep
    """
    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
Пример #4
0
def plot_map_spatialanalog(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 eggshell.nc import nc_utils
    from mpl_toolkits.axes_grid import make_axes_locatable
    import matplotlib.axes as maxes

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

        lats, lons = nc_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 Exception as ex:
        msg = 'failed to plot graphic {}'.format(ex)
        LOGGER.exception(msg)

    LOGGER.info('Plot created and figure saved')
    return fig
Пример #5
0
def plot_map_timemean(resource, variable=None, time_range=None,
             title=None, delta=0, cmap=None, vmin=None, vmax=None, figsize=(15, 15),
             file_extension='png', dir_output='.'):
    """
    creates a spatial map with the mean over the timestepps.
    If multiple files are provided, a mean over all files are condidered.

    :param resource: netCDF file(s) containng spatial values to be plotted.
    :param variable: variable to be visualised. If None (default), variable will be detected
    :param title: string to be used as title
    :param delta: set a delta for the values e.g. -273.15 to convert Kelvin to Celsius
    :param figsize: figure size defult=(15,15)
    :param vmin: colorbar minimum
    :param vmax: colorbar maximum
    :param file_extension: file extinction for the graphic
    :param dir_output: output directory to store the output graphic

    :returns str: path/to/file.png
    """
    # from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER


    try:
        LOGGER.debug('plot_map function read in values for {}'.format(resource))

        # get values of netcdf file
        if type(resource) == str:

            ds = Dataset(resource)

            if variable is None:
                variable = get_variable(resource)

            lat = ds.variables['rlat']
            lon = ds.variables['rlon']
            lons, lats = meshgrid(lon, lat)

            var = ds.variables[variable]
            var = get_values(f, time_range=time_range, variable=variable).data
            var_mean = np.nanmean(var, axis=0) + delta # mean over whole periode 30 Years 1981-2010 and transform to Celsius
        else:
            for i, f in enumerate(resource):
                if i == 0:
                    ds = Dataset(f)
                    lat = ds.variables['rlat']
                    lon = ds.variables['rlon']
                    lons, lats = meshgrid(lon, lat)

                    vals = get_values(f, time_range=time_range, variable=variable).data
                else:
                    vals = np.append(vals, get_values(f, time_range=time_range, variable=variable).data, axis=0)
            var_mean = np.nanmean(vals, axis=0) + delta

        # prepare plot
        LOGGER.info('preparing matplotlib figure')

        fig = plt.figure(figsize=figsize, facecolor='w', edgecolor='k')
        ax = plt.axes(projection=ccrs.PlateCarree())

        cs = plt.pcolormesh(lons, lats, var_mean,
                            transform=ccrs.PlateCarree(), cmap=cmap,
                            vmin=vmin, vmax=vmax,
                            )
        # extent=(-0,17,10.5,24)
        # ax.set_extent(extent)

        ax.add_feature(cfeature.BORDERS, linewidth=2, linestyle='--')
        # ax.add_feature(cfeature.RIVERS)
        # ax.stock_img()
        # ax.gridlines(draw_labels=False)
        gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True,
                          linewidth=2, color='gray', alpha=0.5, linestyle='--')

        gl.xlabels_top = False
        gl.ylables_right = False
        gl.ylables_left = False
        # gl.xlines = False
        # gl.xlocator = mticker.FixedLocator([0, 2,4,6,8,10,12,14,16] )
        # gl.xformatter = LONGITUDE_FORMATTER
        # gl.yformatter = LATITUDE_FORMATTER
        gl.xlabel_style = {'size': 15, 'color': 'black', 'weight': 'bold'}
        gl.ylabel_style = {'size': 15, 'color': 'black', 'weight': 'bold'}

        if cmap is None:
            if variable in ['pr', 'prAdjust',
                            'prcptot', 'rx1day', 'wetdays',
                            'cdd', 'cwd', 'sdii',
                            'max_5_day_precipitation_amount']:
                cmap = 'Blues'
            if variable in ['tas', 'tasAdjust', 'tg', 'tg_mean']:
                cmap = 'seismic'

        plt.title(title, fontsize=25)

        cax = fig.add_axes([ax.get_position().x1 + 0.1, ax.get_position().y0,
                            0.02, ax.get_position().height])
        cbar = plt.colorbar(cs, cax=cax) # Similar to fig.colorbar(im, cax = cax)
        cbar.ax.tick_params(labelsize=20)

        # ticklabs = cbar.ax.get_yticklabels()
        # cbar.ax.set_yticklabels(ticklabs, fontsize=15)
        # cb = add_colorbar(cs)

        LOGGER.info('Matplotlib pcolormesh plot done')

        output_png = fig2plot(fig=fig, file_extension='png',
                              dir_output=dir_output)
        plt.close()
        LOGGER.debug('Plot done for %s' % variable)
    except Exception as err:
        raise Exception('failed to calculate quantiles. %s' % err)

    return output_png