Esempio n. 1
0
    def test_can_run_bayesian_kriging_from_observation_sites_to_1km_grid(self):
        """
        Somewhat more complex test, first do kriging of 1 timeseries out to grid (expect same values flat)
        then do kriging of 3 time-series out to the grid (expect different values, no real verification here since this is done elsewhere

        """
        # arrange the test with a btk_parameter, a source grid and a destination grid
        btk_parameter = api.BTKParameter(temperature_gradient=-0.6, temperature_gradient_sd=0.25, sill=25.0, nugget=0.5, range=20000.0, zscale=20.0)
        fx = lambda z: api.DoubleVector.from_numpy(np.zeros(self.n))

        grid_1km_1 = self._create_geo_point_grid(self.mnx, self.mny, self.dx_model)
        grid_1km_3 = self._create_geo_point_grid(self.mnx, self.mny, self.dx_model)

        observation_sites = api.TemperatureSourceVector()
        ta_obs = api.TimeAxisFixedDeltaT(self.t, self.d * 3, int(self.n / 3))
        ta_grid = api.TimeAxisFixedDeltaT(self.t, self.d, self.n)
        point_fx = api.point_interpretation_policy.POINT_AVERAGE_VALUE
        ts_site_1 = api.TimeSeries(ta_obs,
                                   values=api.DoubleVector.from_numpy(
            (20.0 - 0.6 * 5.0 / 100) + 3.0 * np.sin(np.arange(start=0, stop=ta_obs.size(), step=1) * 2 * np.pi / 8.0 - np.pi / 2.0)
                                   ),
                                   point_fx=point_fx)
        ts_site_2 = api.TimeSeries(ta_obs, values=api.DoubleVector.from_numpy(
            (20.0 - 0.6 * 500.0 / 100) + 3.0 * np.sin(np.arange(start=0, stop=ta_obs.size(), step=1) * 2 * np.pi / 8.0 - np.pi / 2.0)),
                                   point_fx=point_fx)
        ts_site_3 = api.TimeSeries(ta_obs, values=api.DoubleVector.from_numpy(
            (20.0 - 0.6 * 1050.0 / 100) + 3.0 * np.sin(np.arange(start=0, stop=ta_obs.size(), step=1) * 2 * np.pi / 8.0 - np.pi / 2.0)),
                                   point_fx=point_fx)

        observation_sites.append(api.TemperatureSource(api.GeoPoint(50.0, 50.0, 5.0), ts_site_1))

        # act 1: just one time-series put into the system, should give same ts (true-averaged) in all the grid-1km_ts (which can be improved using std.gradient..)
        grid_1km_1ts = api.bayesian_kriging_temperature(observation_sites, grid_1km_1, ta_grid, btk_parameter)

        # assert 1:
        self.assertEqual(len(grid_1km_1ts), self.mnx * self.mny)
        expected_grid_1ts_values = ts_site_1.average(api.TimeAxis(ta_grid)).values.to_numpy()

        for gts in grid_1km_1ts:
            self.assertEqual(gts.ts.size(), ta_grid.size())
            self.assertTrue(np.allclose(expected_grid_1ts_values, gts.ts.values.to_numpy()))

        observation_sites.append(api.TemperatureSource(api.GeoPoint(9000.0, 500.0, 500), ts_site_2))
        observation_sites.append(api.TemperatureSource(api.GeoPoint(9000.0, 12000.0, 1050.0), ts_site_3))

        grid_1km_3ts = api.bayesian_kriging_temperature(observation_sites, grid_1km_3, ta_grid, btk_parameter)

        self.assertEqual(len(grid_1km_3ts), self.mnx * self.mny)

        for gts in grid_1km_3ts:
            self.assertEqual(gts.ts.size(), ta_grid.size())
            self.assertFalse(np.allclose(expected_grid_1ts_values, gts.ts.values.to_numpy()))
Esempio n. 2
0
    def _create_geo_ts_grid(self, nx, ny, dx, fx):
        """Create a geo_ts_grid of TemperatureSources,
           We just create a terrain model starting at 0 and increasing to max_elevation at max x and y.
           parameters
           ----------
           nx : int
            number of grid-cells in x direction
           ny : int
            number of grid-cells in y direction
           dx : float
             distance in meters for one of the sides in the grid
           fx : lambda z : 1.0
             a function that takes elevation z as input and generates a np.array len(self.ta) of float64 as time-series
           returns
           -------
           a TemperatureSourceVector() filled with geo-ts representing the grid.

        """
        arome_grid = api.TemperatureSourceVector()
        for i in range(nx):
            for j in range(ny):
                z = self.max_elevation * (i + j) / (nx + ny)
                ts = api.Timeseries(ta=self.ta,
                                    values=fx(z),
                                    point_fx=api.point_interpretation_policy.
                                    POINT_AVERAGE_VALUE)
                geo_ts = api.TemperatureSource(api.GeoPoint(i * dx, j * dx, z),
                                               ts)
                arome_grid.append(geo_ts)
        return arome_grid
Esempio n. 3
0
    def _create_geo_forecast_set(self, n_fc, t0, dt, n_steps, dt_fc, fx):
        """

        Parameters
        ----------
        n_fc : int number of forecasts, e.g. 8
        t0 : utctime start of first forecast
        dt : utctimespan delta t for forecast-ts
        n_steps : number of steps in one forecast-ts
        dt_fc : utctimespan delta t between each forecast, like deltahours(6)
        fx : lambda time_axis:  a function returning a DoubleVector with values for the supplied time-axis

        Returns
        -------
        api.TemperatureSourceVector()

        """
        fc_set = api.TemperatureSourceVector()
        geo_point = api.GeoPoint(
            0.0, 0.0, 0.0)  # any point will do, we just reuse the geo-ts
        for i in range(n_fc):
            ta = api.Timeaxis2(t0 + i * dt_fc, dt, n_steps)
            ts = api.Timeseries(
                ta=ta,
                values=fx(ta),
                point_fx=api.point_interpretation_policy.POINT_AVERAGE_VALUE)
            geo_ts = api.TemperatureSource(geo_point, ts)
            fc_set.append(geo_ts)
        return fc_set
Esempio n. 4
0
 def _make_fc_from_obs(self, obs_set, bias):
     fc_set = api.TemperatureSourceVector()
     bias_ts = api.Timeseries(self.ta, fill_value=bias)
     for obs in obs_set:
         geo_ts = api.TemperatureSource(obs.mid_point(), obs.ts + bias_ts)
         fc_set.append(geo_ts)
     return fc_set
Esempio n. 5
0
 def _make_fc_from_obs(self, obs_set, bias):
     fc_set = api.TemperatureSourceVector()
     bias_ts = api.TimeSeries(
         self.ta,
         fill_value=bias,
         point_fx=api.point_interpretation_policy.POINT_INSTANT_VALUE)
     for obs in obs_set:
         geo_ts = api.TemperatureSource(obs.mid_point(), obs.ts + bias_ts)
         fc_set.append(geo_ts)
     return fc_set
Esempio n. 6
0
 def _create_obs_set(self, geo_points):
     obs_set = api.TemperatureSourceVector()
     fx = lambda z: [15 for x in range(self.nt)]
     ts = api.TimeSeries(
         ta=self.ta,
         values=fx(self.ta),
         point_fx=api.point_interpretation_policy.POINT_AVERAGE_VALUE)
     for gp in geo_points:
         # Add only one TS per GP, but could be several
         geo_ts = api.TemperatureSource(gp, ts)
         obs_set.append(geo_ts)
     return obs_set
 def test_create_source_vector_does_not_leak(self):
     n = 365 * 24 * 1  # 1st checkpoint memory here,
     for i in range(10):
         v = api.TemperatureSourceVector([
             api.TemperatureSource(
                 api.GeoPoint(0.0, 1.0, 2.0),
                 api.TimeSeries(api.TimeAxis(api.time(0), api.time(3600),
                                             n),
                                fill_value=float(x),
                                point_fx=api.POINT_AVERAGE_VALUE))
             for x in range(n)
         ])
         self.assertIsNotNone(v)
         del v
     pass  # 2nd mem check here, should be approx same as first checkpoint
Esempio n. 8
0
 def _predict_bias(self, obs_set, fc_set):
     # Return a set of bias_ts per observation geo_point
     bias_set = api.TemperatureSourceVector()
     kf = api.KalmanFilter()
     kbp = api.KalmanBiasPredictor(kf)
     kta = api.TimeAxis(self.t0, api.deltahours(3), 8)
     for obs in obs_set:
         kbp.update_with_forecast(fc_set, obs.ts, kta)
         pattern = api.KalmanState.get_x(kbp.state)
         # a_ts = api.TimeSeries(pattern, api.deltahours(3), self.ta)  # can do using ct of TimeSeries, or:
         b_ts = api.create_periodic_pattern_ts(pattern, api.deltahours(3),
                                               self.ta.time(0),
                                               self.ta)  # function
         bias_set.append(api.TemperatureSource(obs.mid_point(), b_ts))
     return bias_set