Example #1
0
    def image(self, state):
        if not self.valid(state):
            return gridded_forecast.empty_image()

        try:
            path, pts = self.locator.locate(self.pattern, state.variable,
                                            state.initial_time,
                                            state.valid_time, state.pressure)
        except SearchFail:
            print("Search failed: {}".format(self.pattern))
            return gridded_forecast.empty_image()

        print(path, pts)

        units = self.read_units(path, state.variable)
        data = load_image_pts(path, state.variable, pts, pts)
        if (len(state.pressures) > 0) and (state.pressure is not None):
            level = "{} hPa".format(int(state.pressure))
        else:
            level = "Surface"
        data.update(
            gridded_forecast.coordinates(state.valid_time, state.initial_time,
                                         state.pressures, state.pressure))
        data["name"] = [self.name]
        data["units"] = [units]
        return data
Example #2
0
 def test(self):
     result = gridded_forecast.empty_image()
     self.assertEqual(
         result.keys(), {
             'x', 'y', 'dw', 'dh', 'image', 'name', 'units', 'valid',
             'initial', 'length', 'level'
         })
     for value in result.values():
         self.assertEqual(value, [])
Example #3
0
    def image(self, state):
        '''gets actual data. 

        X and Y passed to :meth:`geo.stretch_image` must be 1D arrays. NWCSAF data 
        are not on a regular grid so must be regridded.

        `values` passed to :meth:`geo.stretch_image` must be a NumPy Masked Array. 

        :param state: Bokeh State object of info from UI
        :returns: Output data from :meth:`geo.stretch_image`'''
        data = empty_image()
        for nc in self.locator._sets:
            if str(
                    datetime.datetime.strptime(
                        nc.nominal_product_time.replace('Z', 'UTC'),
                        '%Y-%m-%dT%H:%M:%S%Z')
            ) == state.valid_time and self.locator.varlist[
                    state.variable] in nc.variables:
                #regrid to regular grid
                x = nc['lon'][:].flatten()  # lat & lon both 2D arrays
                y = nc['lat'][:].flatten()  #
                z = nc[self.locator.varlist[state.variable]][:].flatten()

                #define grid
                xi, yi = np.meshgrid(
                    np.linspace(x.min(), x.max(), nc.dimensions['nx'].size),
                    np.linspace(y.min(), y.max(), nc.dimensions['ny'].size),
                )

                zi = griddata(np.array([x, y]).transpose(),
                              z, (xi, yi),
                              method='linear',
                              fill_value=np.nan)

                zi = np.ma.masked_invalid(zi, copy=False)
                zi = np.ma.masked_outside(
                    zi,
                    nc[self.locator.varlist[state.variable]].valid_range[0],
                    nc[self.locator.varlist[state.variable]].valid_range[1],
                    copy=False)
                data = geo.stretch_image(xi[0, :], yi[:, 0], zi)
                #data = geo.stretch_image(x[0,:], y[:,0], nc[state.variable][:])
                data.update(
                    coordinates(state.valid_time, state.initial_time,
                                state.pressures, state.pressure))
                data.update({
                    'name':
                    [str(nc[self.locator.varlist[state.variable]].long_name)],
                })
                if 'units' in nc[self.locator.varlist[
                        state.variable]].ncattrs():
                    data.update({
                        'units':
                        [str(nc[self.locator.varlist[state.variable]].units)]
                    })

        return data
Example #4
0
    def image(self, state):
        """
        Main image loading function. This function will actually realise the
        data,
        """
        if self.variable_id != state.variable:
            self.variable_id = state.variable
            self._cube = None

        valid_time = state.valid_time
        pressure = state.pressure

        selected_time = gridded_forecast._to_datetime(valid_time)

        # the guts of creating the bokeh object has been put into a separate
        # function so that it can be cached, so if image is called multiple
        # time the calculations are only done once (hopefully).
        cube = self.cube
        coord_names = [c1.name() for c1 in cube.coords()]
        if 'air_pressure' in coord_names and pressure is None:
            data = gridded_forecast.empty_image()
            return data

        data = _get_bokeh_image(cube, self.experiment_id,
                                self.variable_id,
                                self.institution_id, state.initial_time,
                                self.member_id, selected_time, pressure)

        data.update(gridded_forecast.coordinates(str(selected_time),
                                                 state.initial_time,
                                                 state.pressures,
                                                 pressure))
        data.update({
            'name': [self._label],
            'units': [str(cube.units)],
            'experiment': [self.experiment_id],
            'institution': [self.institution_id],
            'memberid': [self.member_id],
            'variableid': [self.variable_id]
        })

        return data
Example #5
0
def _get_bokeh_image(cube,
                     experiment_id,
                     variable_id,
                     institution_id,
                     initial_time,
                     member_id,
                     selected_time,
                     pressure,
                     ):
    """
    A helper function to do  the creation of the image dict required by bokeh.
    This includes downloading the actual data required for the current view, so
    this function is cached to reduce remote queries.
    """

    def time_comp(select_time, time_cell):  #
        data_time = gridded_forecast._to_datetime(time_cell.point)
        if abs((select_time - data_time).days) < 2:
            return True
        return False

    def lat_filter(lat):
        """
        Due to the way the current projection of gridded data works, the poles are
        not well handled, resulting in NaNs if we use the full range of latitudes.
        The current hack is to chop off latitude greater than 85 degrees north and
        south. Given the importance of data at the poles in climate change research,
        we will need to fix this in future.
        """
        return -85.0 < lat < 85.0

    def pressure_select(select_pressure, data_pressure):
        return abs(select_pressure - data_pressure.point) < 1.0

    if cube is None or initial_time is None:
        data = gridded_forecast.empty_image()
    else:
        constraint_dict = {'time': functools.partial(time_comp,
                                                     selected_time),
                           'latitude': lat_filter,
                           }
        coord_names = [c1.name() for c1 in cube.coords()]
        if 'air_pressure' in coord_names:
            constraint_dict['air_pressure'] = functools.partial(
                pressure_select,
                pressure,
            )
        cube_cropped = cube.extract(iris.Constraint(**constraint_dict))
        lat_pts = cube_cropped.coord('latitude').points
        long_pts = cube_cropped.coord('longitude').points - 180.0
        cube_data_cropped = cube_cropped.data
        cube_width = int(cube_data_cropped.shape[1] / 2)
        cube_data_cropped = numpy.concatenate(
            [cube_data_cropped[:, cube_width:],
             cube_data_cropped[:, :cube_width]], axis=1)

        data = geo.stretch_image(long_pts, lat_pts, cube_data_cropped)
        data['image'] = [numpy.ma.masked_array(data['image'][0],
                                               mask=numpy.isnan(
                                                   data['image'][0]))]
        return data