Source code for pycif.plugins.modes.footprint.execute
from logging import info
[docs]
def execute(self, **kwargs):
"""Run the observation operator in adjoint (footprint / backward) mode.
Sets the observation-vector increment ``dy`` to the configured value (or
to the existing ``sim_tl`` column when no explicit increment is given),
zeros out non-observed locations, then calls the obs-operator in adjoint
mode to propagate the sensitivity back to the control space.
Args:
self (Plugin): mode plugin providing ``workdir``, ``datei``,
``datef``, ``use_xb``, and optionally ``increments``.
**kwargs: forwarded verbatim to the observation operator.
Returns:
ControlVect: the control vector populated with adjoint sensitivities.
"""
# Working directory
workdir = self.workdir
# Observation operator
obsoper = self.obsoperator
# Control vector
controlvect = obsoper.controlvect
# Observation vector
obsvect = obsoper.obsvect
# Simulation window
datei = self.datei
datef = self.datef
# Some verbose
info("Running a backward computation")
# Putting x at xb value if available
if hasattr(controlvect, "xb") and self.use_xb:
controlvect.x = controlvect.xb
# Check that x is defined
if not hasattr(controlvect, "x"):
raise ValueError(
"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"
)
# Set increments not in observation vector to 0
obsvect.dy[~obsvect.obsvect_mask] = 0
# Set increments in observation vector to the provided value
if hasattr(self, "increments"):
obsvect.dy[obsvect.obsvect_mask] = self.increments
# Running the observation operator
controlvect = obsoper.obsoper(
controlvect, obsvect,
"adj", datei=datei, datef=datef, workdir=workdir,
reload_results=self.reload_results,
**kwargs
)
info("The adjoint mode has been successfully executed")
return controlvect