Source code for pycif.plugins.modes.forward.execute
import numpy as np
import copy
from logging import info
from ....utils.datastores.dump import dump_datastore
[docs]
def execute(self, **kwargs):
"""Run the observation operator in forward (or tangent-linear) mode.
Initialises the control vector from its background state when ``use_xb``
is set, validates that both ``x`` and at least one observation are defined,
then calls the obs-operator. Optionally perturbs the resulting simulated
observations with Gaussian noise (controlled by ``perturb_obsvect`` and
``obserror``) and dumps the resulting observation vector.
Args:
self (Plugin): mode plugin carrying all configuration attributes
(``workdir``, ``datei``, ``datef``, ``run_mode``, ``use_xb``,
``perturb_obsvect``, ``obserror``, ``reload_results``).
**kwargs: forwarded verbatim to the observation operator.
Returns:
ObsVect: the observation vector populated with simulated values.
"""
# Working directory
workdir = self.workdir
# Observation operator
obsoper = self.obsoperator
# Control vector
controlvect = obsoper.controlvect
# Simulation window
datei = self.datei
datef = self.datef
# Some verbose
info("Running a forward computation")
# Putting x at xb value if available
if hasattr(controlvect, "xb") and self.use_xb:
controlvect.x = copy.deepcopy(controlvect.xb)
# Check that x is defined
if not hasattr(controlvect, "x"):
raise Exception(
"Try running a forward simulation without x defined. This can "
"happen if use_xb is set to False, and/or reading a pre-defined "
"control vector: \n"
f" - use_xb = {self.use_xb}\n"
f" - controlvect.reload_xb = {controlvect.reload_xb}\n"
f" - controlvect.reload_file = {controlvect.reload_file}\n"
)
# Check that observations are defined
if obsoper.obsvect.dim == 0 and not obsoper.force_full_operator:
raise Exception(
"Trying to run a forward simulation with no observation. "
"Please check that this is the expected behaviour.\n"
"If you really want to run with no observation, please use the "
"parameter `force_full_operator` in the `obsoperator` paragraph "
"of your yml."
)
# Running the observation operator
obsvect = obsoper.obsoper(
controlvect, obsoper.obsvect,
self.run_mode, datei=datei, datef=datef, workdir=workdir,
reload_results=self.reload_results,
**kwargs
)
# Perturbs the output monitor if required in the Yaml
if self.perturb_obsvect:
# Altering obsvect and save data
obserror = self.obserror * np.nanstd(obsvect.ysim)
obsvect.yobs = (
np.random.normal(
loc=0, scale=obserror, size=obsvect.ysim.size
)
+ obsvect.ysim
)
obsvect.yobs_err[:] = obserror
# Dumping the datastore with reference data
obsvect.dump("{}/obsvect/".format(workdir))
info("The forward mode has been successfully executed")
return obsvect