from types import MethodType
from ...utils.check.errclass import PluginError
from .baseclass import Plugin
[docs]
class ControlVect(Plugin):
"""Plugin type for control vector operations in the inversion system.
Handles transformations between control space (optimised parameters),
native space (physical model units), and model input files, as well as
background error covariance (B-matrix) products.
Concrete implementations live in ``pycif/plugins/controlvects/``.
"""
def __init__(self, **kwargs):
"""Initialise a ControlVect plugin with an empty datastore."""
super(ControlVect, self).__init__(**kwargs)
# Default attributes
self.datastore = {}
[docs]
def initiate_template(self):
"""Initialise the ControlVect plugin template.
Loads the registered control-vector module and attaches all standard
methods (``state2inputs``, ``outputs2state``, ``control2native``,
``native2control``, ``sqrtbprod``, ``sqrtbprod_ad``, ``dump``,
``load``, ``init_structure``, ``init_xb``, ``init_bprod``, ``crop``)
as bound methods on this instance.
"""
super(ControlVect, self).initiate_template(
plg_type="controlvect",
default_functions={
k: True for k in [
"state2inputs", "outputs2state", "control2native",
"native2control", "sqrtbprod", "sqrtbprod_ad", "dump", "load",
"init_structure", "init_xb", "init_bprod", "crop"]
}
)
[docs]
@classmethod
def register_plugin(cls, name, version, module, subtype="", **kwargs):
"""Register a module for a plugin and version with possibly options
Args:
name (str): name of the plugin
version (str): version of the plugin
module (types.ModuleType): module defining the interface
between pyCIF and the plugin
plugin_type (str): type of plugin
**kwargs (dictionary): default options for module
"""
super(ControlVect, cls).register_plugin(
name, version, module, plugin_type="controlvect", subtype=subtype
)
[docs]
def outputs2state(self, *args, **kwargs):
"""Convert model outputs back into the state vector (control space).
Inverse of :meth:`state2inputs`. Must be overridden.
Raises:
PluginError: Always, in this default implementation.
"""
raise PluginError("This is the default empty outputs2state method")
[docs]
def control2native(self, *args, **kwargs):
"""Convert the state vector from control space to physical (native) model units.
Applies any scaling or change of variable needed to go from the
optimised parameters to the units used inside the model.
Must be overridden.
Raises:
PluginError: Always, in this default implementation.
"""
raise PluginError("This is the default empty control2native method")
[docs]
def native2control(self, *args, **kwargs):
"""Convert model-unit quantities back to control space.
Inverse of :meth:`control2native`. Must be overridden.
Raises:
PluginError: Always, in this default implementation.
"""
raise PluginError("This is the default empty native2control method")
[docs]
def sqrtbprod(self, *args, **kwargs):
"""Apply the square-root of the background error covariance: sqrt(B)·v.
Used in variational DA to precondition the minimisation.
Must be overridden.
Raises:
PluginError: Always, in this default implementation.
"""
raise PluginError("This is the default empty sqrtbprod method")
[docs]
def sqrtbprod_ad(self, *args, **kwargs):
"""Apply the adjoint of the sqrt(B) operator: sqrt(B)ᵀ·v.
Adjoint counterpart of :meth:`sqrtbprod`, required for gradient
computation in variational DA. Must be overridden.
Raises:
PluginError: Always, in this default implementation.
"""
raise PluginError("This is the default empty sqrtbprod_ad method")
[docs]
def dump(self, *args, **kwargs):
"""Serialise the control vector to disk. Must be overridden.
Raises:
PluginError: Always, in this default implementation.
"""
raise PluginError("This is the default empty dump method")
[docs]
def crop(self, *args, **kwargs):
"""Crop the control vector to a sub-domain or time window. Must be overridden.
Raises:
PluginError: Always, in this default implementation.
"""
raise PluginError("This is the default empty crop method")
[docs]
def load(self, *args, **kwargs):
"""Deserialise the control vector from disk. Must be overridden.
Raises:
PluginError: Always, in this default implementation.
"""
raise PluginError("This is the default empty load method")