Ejemplo n.º 1
0
def simple_run_demo():
    """Simple demo using HBV time-series and similar model-values

    """
    # 1. Setup the time-axis for our simulation
    normal_calendar = Calendar(3600) # we need UTC+1, since day-boundaries in day series in SmG is at UTC+1
    t_start = normal_calendar.time(2010, 9, 1) # we start at
    t_end   = normal_calendar.add(t_start,Calendar.YEAR,5) # 5 years period for simulation
    time_axis = Timeaxis(t_start, model_dt, normal_calendar.diff_units(t_start,t_end,model_dt))

    # 2. Create the shyft model from the HBV model-repository
    shyft_model = create_kjela_model(PTHSKModel, kjela.geo_ts_repository)

    # 3. establish the initial state
    # using the *pattern* of distribution after one year (so hbv-zone 1..10 get approximate distribution of discharge)
    #      *and* the observed discharge at the start time t_start
    #
    t_burnin = normal_calendar.add(t_start,Calendar.YEAR,1) # use one year to get distribution between hbvzones
    burnin_time_axis = Timeaxis(t_start, model_dt, normal_calendar.diff_units(t_start, t_burnin, model_dt))
    q_obs_m3s_ts = observed_kjela_discharge(time_axis.total_period()) # get out the observation ts
    q_obs_m3s_at_t_start= q_obs_m3s_ts(t_start) # get the m3/s at t_start
    initial_state = burn_in_state(shyft_model,burnin_time_axis, q_obs_m3s_at_t_start)

    # 4. now run the model with the established state
    #    that will start out with the burn in state
    shyft_model.run(time_axis, initial_state)

    # 5. display results etc. goes here
    plot_results(shyft_model, q_obs_m3s_ts)
    plt.show()
Ejemplo n.º 2
0
    def test_dtss_partition_by_average(self):
        """
        This test illustrates use of partition_by client and server-side.
        The main point here is to ensure that the evaluate period covers
        both the historical and evaluation peri
        """
        with tempfile.TemporaryDirectory() as c_dir:
            # setup data to be calculated
            utc = Calendar()
            d = deltahours(1)
            t = utc.time(2000, 1, 1)
            n = utc.diff_units(t, utc.add(t, Calendar.YEAR, 10), d)
            ta = TimeAxis(t, d, n)
            td = TimeAxis(t, d * 24, n // 24)
            n_ts = 1
            store_tsv = TsVector()  # something we store at server side
            for i in range(n_ts):
                pts = TimeSeries(
                    ta,
                    np.sin(
                        np.linspace(start=0, stop=1.0 * (i + 1),
                                    num=ta.size())),
                    point_fx.POINT_AVERAGE_VALUE)
                ts_id = shyft_store_url(f"{i}")
                store_tsv.append(TimeSeries(
                    ts_id, pts))  # generate a bound pts to store

            # start dtss server
            dtss = DtsServer()
            cache_on_write = True
            port_no = find_free_port()
            host_port = 'localhost:{0}'.format(port_no)
            dtss.set_auto_cache(True)
            dtss.set_listening_port(port_no)
            dtss.set_container(
                "test", c_dir
            )  # notice we set container 'test' to point to c_dir directory
            dtss.start_async(
            )  # the internal shyft time-series will be stored to that container

            # create dts client
            c = DtsClient(
                host_port,
                auto_connect=False)  # demonstrate object life-time connection
            c.store_ts(store_tsv,
                       overwrite_on_write=True,
                       cache_on_write=cache_on_write)

            t_0 = utc.time(2018, 1, 1)
            tax = TimeAxis(t_0, Calendar.DAY, 365)
            ts_h1 = TimeSeries(shyft_store_url(f'{0}'))
            ts_h2 = store_tsv[0]
            ts_p1 = ts_h1.partition_by(utc, t, Calendar.YEAR, 10,
                                       t_0).average(tax)
            ts_p2 = ts_h2.partition_by(utc, t, Calendar.YEAR, 10,
                                       t_0).average(tax)
Ejemplo n.º 3
0
def period_percentiles_tsv(
        ts: TimeSeries,
        period: UtcPeriod,
        average_dt: int,
        percentile_period: UtcPeriod,
        percentiles: Sequence[int],
        client: DtsClient, calendar: Calendar
) -> TsVector:
    """Compute percentiles from a part of a time-series and generate a TsVector of
    percentile time-series spanning a possibly different time period.

    Args:
        ts: TimeSeries to compute percentile time-series for.
        period: Time period the output time-series should span.
        average_dt: Period to average values by when partitioning the input time-series.
        percentile_period: Period from ts to compute percentiles for.
        percentiles: Percentiles to compute. Values should be in the range ``0..100``.
        client: DtsClient to use for performing the partitioning.
        calendar: Calendar to to for interpreting time and partitioning the input
            time-series.

    Returns:
        A TsVector with one TimeSeries for each value in percentiles, all spanning period.
    """
    periods = int((percentile_period.end - percentile_period.start)//average_dt)

    n_avg = calendar.diff_units(period.start, period.end, average_dt)
    if n_avg*average_dt < period.end - period.start:
        n_avg += 1

    tsv = client.evaluate(
        ts.average(TimeAxis(period.start, average_dt, n_avg))
          .partition_by(calendar, period.start, average_dt, periods, period.start),
        period
    )
    tsv_p = tsv.percentiles(TimeAxis(period.start, average_dt, 1), percentiles)

    tsv = TsVector()
    ta = TimeAxis(period.start, period.end - period.start, 1)
    for ts_p in tsv_p:
        tsv.append(TimeSeries(ta, [ts_p.values[0]], POINT_AVERAGE_VALUE))

    return tsv
Ejemplo n.º 4
0
def windowed_percentiles_tsv(
        ts: TimeSeries,
        period: UtcPeriod,
        average_dt: int,
        percentile_dt: int,
        percentiles: Sequence[int],
        client: DtsClient, calendar: Calendar
) -> TsVector:
    """Compute percentiles for a time-series in a gliding window fashion.

     The input time-series is partitioned and averaged using ``ts.partition_by`` such
     that each value is included in percentile computations spanning percentile_dt time
     from the value occurrence.

    Args:
        ts: TimeSeries to compute percentile time-series for.
        period: Period to generate percentile time-series for.
        average_dt: Period to average values by when partitioning the input time-series.
            This is the time-step of the time-series in the output TsVector.
        percentile_dt: Time span for a value to contribute to percentile computations.
        percentiles: Percentiles to compute. Values should be in the range ``0..100``.
        client: DtsClient to use for performing the partitioning.
        calendar: Calendar to to for interpreting time and partitioning the input
            time-series.

    Returns:
        A TsVector with one TimeSeries for each value in percentiles, all spanning period.
    """
    periods = int(percentile_dt//average_dt)

    n_avg = calendar.diff_units(period.start, period.end, average_dt)
    if n_avg*average_dt < period.end - period.start:
        n_avg += 1

    tsv = client.evaluate(
        ts.average(TimeAxis(period.start, average_dt, n_avg))
          .partition_by(calendar, period.start, average_dt, periods, period.start)
          .time_shift(periods*average_dt),
        period
    )

    return tsv.percentiles(TimeAxis(period.start, average_dt, n_avg), percentiles)
Ejemplo n.º 5
0
def selector_ts(
        ts: TimeSeries,
        period: UtcPeriod,
        average_dt: int,
        threshold_tss: Sequence[TimeSeries],
        tss: Sequence[TimeSeries],
        mask_point_fx: point_interpretation_policy,
        client: DtsClient, calendar: Calendar
) -> TimeSeries:
    """Select values from different time-series based on values from a single
    time-series when compared to a set of threshold time-series.

    Args:
        ts: TimeSeries to base selections on.
        period: Period to select values in.
        average_dt: Time step to use for the internal masking series. An average of
            the input ts together with the threshold time-series in threshold_tss is
            used to generate the masks.
        threshold_tss: Threshold time-series. Should be one less than the number of
            time-series to choose from.
        tss: TimeSeries to choose values from.
        mask_point_fx: Point interpretation to use for the mask time-series. If equal
            to POINT_INSTANT_VALUE the boundaries between different selection
            regions is smoothed. If equal to POINT_AVERAGE_VALUE the boundaries are
            sharp.
        client: DtsClient use for computations and data retrieval.
        calendar: Calendar used to interpret time.

    Returns:
        A TimeSeries that is the selection of values from tss.
    """
    assert len(threshold_tss) == len(tss) - 1, ('the number of thresholds should be one less '
                                                'than the number of time-series')

    # setup averaging for mask
    tsv = TsVector()
    # ----------
    n = calendar.diff_units(period.start, period.end, average_dt)
    if n * average_dt < period.end - period.start:
        n += 1
    ta_avg = TimeAxis(period.start, average_dt, n)
    tsv.append(ts.average(ta_avg))
    # ----------
    tsv: TsVector = client.evaluate(tsv, period)
    # ----------
    avg_ts = tsv[0]
    del tsv

    # compute mask
    masks: List[DoubleVector] = []
    for avg_p, avg_v in zip(avg_ts.get_time_axis(), avg_ts.values):
        added_mask = False
        for i in range(len(tss)):
            if i == len(masks):
                masks.append(DoubleVector())
            if not added_mask:
                # determine period threshold
                if i == 0:
                    min_threshold = -1_000_000_000
                    max_threshold = threshold_tss[0](avg_p.start)
                elif i == len(tss) - 1:
                    min_threshold = threshold_tss[-1](avg_p.start)
                    max_threshold = 1_000_000_000
                else:
                    min_threshold = threshold_tss[i - 1](avg_p.start)
                    max_threshold = threshold_tss[i](avg_p.start)
                # set mask value
                if min_threshold <= avg_v < max_threshold:
                    added_mask = True
                    masks[i].append(1.0)
                else:
                    masks[i].append(0.0)
            else:
                masks[i].append(0.0)

    # construct final ts
    computed_ts = None
    for i, ts_expr in enumerate(tss):
        if computed_ts is not None:
            computed_ts += ts_expr * TimeSeries(ta_avg, masks[i], mask_point_fx)
        else:
            computed_ts = ts_expr * TimeSeries(ta_avg, masks[i], mask_point_fx)

    return computed_ts