fips.offset_block#

fips.offset_block(obs_space, by, block='offset', blocks=None)[source]#

Return a block of offsets for the state: one per group of observations, and the map to them.

An offset is an unknown that adds to each observation of its group (the background at a site in a month, a calibration bias of a network): it is solved for with the state, as a block of its own, instead of being fixed (the problem’s offset) or left in the model-data mismatch. Its prior and its covariance are the caller’s: the offsets’ labels are the groups, so a covariance model on their levels correlates them (an Exponential("obs_time", "30D") between the months of one site).

Parameters:
  • obs_space (Space) – The observations.

  • by (Any) – The groups, as sum() takes them: one offset for each group of observations that has any ([bins, "site"] for one per interval and site, with bins an IntervalIndex named after the time level).

  • block (str) – The name of the offsets’ block in the state.

  • blocks (str | Sequence[str] | None) – The blocks of observations the offsets apply to, every block by default; their observations share an offset when their groups have the same labels. Observations of another block get none. For separate offsets per block, call this once per block with another block name.

Return type:

tuple[Vector, Operator]

Returns:

  • prior (Vector) – Zeros on the offsets’ space: one block, block, labeled by the groups (sorted) on the levels the keys name.

  • forward (Operator) – The forward block, from the offsets (its columns) to obs_space (its rows): 1 where an observation has that offset, 0 elsewhere. Sparse. It is the transpose of sum()’s operator on the same groups.

Raises:

See also

sum

The aggregation on the same groups.

Examples

One offset per site and month, for hourly observations at two sites:

>>> import numpy as np
>>> import pandas as pd
>>> import fips
>>> labels = pd.MultiIndex.from_product(
...     [["A", "B"], pd.to_datetime(["2020-01-10", "2020-01-20", "2020-02-05"])],
...     names=["site", "obs_time"],
... )
>>> obs = fips.Vector.from_series(pd.Series(400.0, index=labels), block="co2")
>>> months = pd.interval_range(
...     pd.Timestamp("2020-01-01"),
...     periods=2,
...     freq="MS",
...     closed="left",
...     name="obs_time",
... )
>>> prior, forward = fips.offset_block(obs.space, by=[months, "site"])
>>> prior.space
Space(offset: 4 x ['obs_time', 'site'])
>>> forward.dense()
array([[1., 0., 0., 0.],
       [1., 0., 0., 0.],
       [0., 0., 1., 0.],
       [0., 1., 0., 0.],
       [0., 1., 0., 0.],
       [0., 0., 0., 1.]])

The offsets go in the state beside the fluxes, with a prior covariance of their own:

prior = fips.Vector.from_blocks({"flux": flux_prior, "offset": prior})
H = fips.Operator.from_blocks(
    {("co2", "flux"): H_flux, ("co2", "offset"): forward["co2", "offset"]}
)
prior_cov = fips.Covariance.block_diag(
    flux=flux_cov, offset=fips.Independent().with_std(0.5)
)