pycif.plugins.obsvects.standard — API reference#
Configuration reference: standard plugin
- pycif.plugins.obsvects.standard.build_full_r.build_r(obsvect, **kwargs)[source]#
Build the full observation error covariance matrix \(\mathbf{R}\).
Constructs the square matrix \(\mathbf{R} \in \mathbb{R}^{m \times m}\) by filling diagonal blocks for each observation tracer with the squared per-observation errors:
\[R_{ii} = \sigma_{\varepsilon,i}^2 \quad \forall\, i \in [\text{ypointer},\, \text{ypointer} + \text{dim})\]Off-diagonal elements remain zero (diagonal covariance assumption).
Warning
This returns a dense \(m \times m\) matrix. For large observation vectors (e.g. \(m > 10^4\)) this will be memory-prohibitive. Use
rinvprod()for the efficient diagonal application.- Parameters:
obsvect (Plugin) – obsvect plugin instance (provides
yobs_err,dim, and access to the datavect tracer metadata).**kwargs – unused; accepted for interface consistency.
- Returns:
diagonal matrix of shape
(dim, dim)containing the squared observation errors on the main diagonal.- Return type:
np.ndarray
- pycif.plugins.obsvects.standard.fetch.default_fetch(ref_dir, ref_file, input_dates, target_dir, tracer=None, **kwargs)[source]#
Resolve observation monitor files and symlink them to the run directory.
For each sub-simulation date in input_dates, expands ref_dir and ref_file using
strftimeformatting, creates a symlink from the source file to target_dir, and returns de-duplicated sorted lists of local file paths and their associated dates.- Parameters:
ref_dir (str) – directory template for the source files; may contain
strftimeformat codes (e.g./data/%Y/%m).ref_file (str) – file name template; may contain
strftimecodes (e.g.monitor_%Y%m%d.nc).input_dates (dict) – mapping from sub-simulation start dates to lists of dates for which files should be fetched.
target_dir (str) – local run directory into which symbolic links are written; the base name of each source file is preserved.
tracer – unused; accepted for interface consistency with other fetch functions.
**kwargs – unused; accepted for interface consistency.
- Returns:
a pair
(list_files, list_dates)where both are dicts keyed by the same sub-simulation start dates as input_dates. Each value is a sorted, de-duplicated list of local file paths or resolved datetime objects respectively.- Return type:
tuple[dict, dict]
- pycif.plugins.obsvects.standard.ini_mapper.ini_mapper(obsvect, general_mapper={}, backup_comps={}, transforms_order=[], ref_transform='', **kwargs)[source]#
Build the transform mapper for the observation vector.
Scans the datavect components and collects every
(component, tracer)pair whoseisobsflag isTrue. These pairs become the output tracer IDs of the observation operator — i.e. the quantities that thetoobsvectsystem transform will write intoobsvect.ysim.- Parameters:
obsvect (Plugin) – obsvect plugin instance (carries the populated
datavectwith component/tracer metadata).general_mapper (dict) – mapper dictionaries from other transforms; unused but accepted for interface consistency.
backup_comps (dict) – unused; accepted for interface consistency.
transforms_order (list) – unused; accepted for interface consistency.
ref_transform (str) – unused; accepted for interface consistency.
**kwargs – unused.
- Returns:
mapper dict with
"inputs": {}(observation vector has no inputs from other transforms) and"outputs": {(comp, trcr): …}for every observation tracer.- Return type:
dict
- pycif.plugins.obsvects.standard.init_rinvprod.init_rinvprod(obsvect, measurements, **kwargs)[source]#
Sanitise observation errors before the \(\mathbf{R}^{-1}\) product.
Replaces any non-positive (zero or negative)
obserrorvalues in the datastore with the dataset mean, preventingrinvprod()from encountering divisions by zero.Note
Transport error inflation is mentioned in comments as a future extension; at present only the zero-error replacement is implemented.
- pycif.plugins.obsvects.standard.init_y0.init_y0(obsvect, **kwargs)[source]#
Initialise the flat observation-vector arrays from the datavect configuration.
Iterates over every
component / tracerpair declared inobsvect.datavect.componentsand, for each one that is flagged as an observation (tracer.isobs):Loads the datastore from a pre-computed
monitor.ncfile (dir_obsvectis set) or reads it from the raw monitor files viainit_param().Assigns a contiguous slice in the global
yobs/yobs_err/ysim/dyarrays usingtracer.ypointer.Appends the
obsvect_maskboolean array that marks which observations enter the cost function (is_obsvect == True).Optionally applies per-tracer error scaling (
obserror_scaleandobserror_value).Compresses the tracer datastore to save memory.
Dumps the final observation vector when
obsvect.dump_obsis set.
- Parameters:
obsvect (Plugin) – obsvect plugin instance. On entry its flat arrays (
yobs,ysim, etc.) are empty; on exit they are filled.**kwargs – forwarded to
init_param()and downstream datastreamread/fetchmethods.
- Returns:
the updated obsvect instance (also modified in-place).
- Return type:
- pycif.plugins.obsvects.standard.rinvprod.rinvprod(obsvect, dy: ndarray[tuple[Any, ...], dtype[floating]], inverse: bool = True, mask: ndarray[tuple[Any, ...], dtype[bool]] | None = None) ndarray[tuple[Any, ...], dtype[floating]][source]#
Apply the observation error covariance (or its inverse) to a vector.
Assumes a diagonal observation error covariance matrix \(\mathbf{R} = \mathrm{diag}(\sigma_{\varepsilon,1}^2, \ldots, \sigma_{\varepsilon,m}^2)\).
Two modes of operation:
inverse=True(default) — computes \(\mathbf{R}^{-1}\,\delta\mathbf{y}\):\[(\mathbf{R}^{-1}\,\delta\mathbf{y})_i = \frac{\delta y_i}{\sigma_{\varepsilon,i}^2}\]Used in the cost function gradient: \(\nabla J_o = \mathbf{H}^\top \mathbf{R}^{-1} (\mathcal{H}(\mathbf{x}) - \mathbf{y}^o)\).
inverse=False— computes a noise-perturbed observation sample \(\mathbf{y}^o + \mathbf{R}^{1/2}\,\delta\mathbf{y}\):\[(\mathbf{R}^{1/2}\,\delta\mathbf{y} + \mathbf{y}^o)_i = \sigma_{\varepsilon,i}\,\delta y_i + y^o_i\]Used for Monte Carlo sampling of perturbed observations.
An optional mask restricts the operation to the active observation subset (
obsvect.obsvect_mask); masked-out positions are set to zero in the output.- Parameters:
obsvect (Plugin) – obsvect plugin instance (provides
yobs_errandyobs).dy (np.ndarray) – input vector, shape
(dim,).inverse (bool) – if
Trueapply \(\mathbf{R}^{-1}\); ifFalseapply \(\mathbf{R}^{1/2}\) and addyobs.mask (np.ndarray of bool, optional) – boolean mask of shape
(dim,)selecting a subset of observations. Positions where the mask isFalseare set to zero in the output.
- Returns:
result vector, shape
(dim,).- Return type:
np.ndarray
- Raises:
ValueError – if mask has a different shape than dy, or if any entry of
yobs_erris zero or NaN (which would make \(\mathbf{R}^{-1}\) undefined or infinite).
- pycif.plugins.obsvects.standard.utils.check_monitor.check_monitor(self, tracer)[source]#
Check whether a pre-existing monitor file is compatible with the current run.
Compares the domain dimensions and simulation dates stored in the monitor’s
nc_attributes(or.attrs) against the current model configuration. This allowsinit_param()to decide whether to re-use the monitor as-is or to reload and re-crop the raw observations.- Parameters:
- Returns:
a four-element tuple
(allcorrect, ok_hcoord, ok_vcoord, do_tstep)where:allcorrect— all checks passed; the monitor can be used as-is.ok_hcoord— horizontal domain (nlat,nlon) matches.ok_vcoord— vertical coordinate is consistent (alwaysTruein the current implementation — reserved for future use).do_tstep— temporal re-cropping is required (Truewhen dates do not match).
When the monitor has no
nc_attributes(old format), returns(False, False, False, True)to trigger a full reload.- Return type:
tuple[bool, bool, bool, bool]
- pycif.plugins.obsvects.standard.utils.dump.dump(obsvect, dir_dump)[source]#
Write the populated observation vector to
monitor.ncfiles.For each observation tracer, creates a copy of its datastore, fills the
maindatacolumns (obs,obserror,sim,sim_tl) from the flat obsvect arrays, optionally adds anorig_indexcolumn, and serialises the result to:<dir_dump>/<component>/<tracer>/monitor.nc
The file format is controlled by
obsvect.dump_type('nc'or'csv'). Global NetCDF attributes recording the run dates and model configuration are written asnc_attributes.- Parameters:
obsvect (Plugin) – obsvect plugin instance. Must have been initialised (
yobs,ysim,dy,yobs_errfilled).dir_dump (str) – root directory under which the per-tracer sub- directories are created.
- pycif.plugins.obsvects.standard.utils.read.read(obsvect, dir_dump)[source]#
Reload simulation results from previously dumped
monitor.ncfiles.Reads the
sim,sim_tl,obs, andobserrorcolumns from the per-tracermonitor.ncfiles written bydump()and copies them back into the flat obsvect arrays (ysim,dy,yobs,yobs_err). Also restorestracer.datastorefor each tracer.This is used to reload forward-run results without re-running the observation operator (e.g. for adjoint restarts or post-processing).
- Parameters:
- Returns:
Trueif no observation tracers were found (nothing to read);Falseif at least one tracer was successfully reloaded.- Return type:
bool
- pycif.plugins.obsvects.standard.utils.vcoord.vcoord(obsvect, **kwargs)[source]#
Assign a model vertical level to each observation.
Dispatches to one of two strategies based on whether a pre-defined station level file is available:
vcoordfromfile()— whenobsvect.file_statlevis set, reads a text table mapping station names to fixed level indices.vcoordfrommeteo()— otherwise, derives the level by matching each observation’s altitude against a hard-coded mid-layer altitude array (LMDZ-specific, provisional implementation).
The
levelcolumn ofobsvect.datastore["data"]is filled in-place.
- pycif.plugins.obsvects.standard.utils.vcoord.vcoordfromfile(datastore, file_lev, **kwargs)[source]#
Assign model levels to observations using a pre-defined station table.
Reads a whitespace-delimited file (header line skipped) whose columns are:
STAT LAT LON LEV alt(m)
and sets
datastore["level"]to the model level index (column 4, 0-based Python indexing) for each matching station name. Observations from stations not listed in the file retainNaN.- Parameters:
datastore (pd.DataFrame) – observation dataframe with a
"station"column (station names, lower-case).file_lev (str) – path to the station-level file.
**kwargs – unused; accepted for interface consistency.
- Returns:
datastore with the
"level"column updated in-place.- Return type:
pd.DataFrame
- pycif.plugins.obsvects.standard.utils.vcoord.vcoordfrommeteo(workdir, datastore, **kwargs)[source]#
Assign model levels to observations by matching altitudes to LMDZ mid-layers.
Uses a hard-coded array of LMDZ mid-layer altitudes (39 levels, metres above the surface) and assigns each observation to the nearest level by minimising \(|\text{alt}_{obs} - \text{alt}_{level}|\).
Warning
This function is provisional and LMDZ-specific. The altitude array is hard-coded and the meteo directory (
$workdir/meteo/) is not actually used in the current implementation. A commented-out block shows the intended xarray-based generalisation.- Parameters:
workdir (str) – pyCIF working directory (currently unused; reserved for the future generalised implementation).
datastore (pd.DataFrame) – observation dataframe with an
"alt"column (altitude in metres above the surface).**kwargs – unused.
- Returns:
datastore with the
"level"column filled with 1-based LMDZ level indices (closest level wins).- Return type:
pd.DataFrame