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