Source code for pycif.plugins.obsvects.standard.rinvprod

from __future__ import annotations

import numpy as np
from numpy.typing import NDArray


[docs] def rinvprod( obsvect, dy: NDArray[np.floating], inverse: bool = True, mask: NDArray[np.bool_] | None = None, ) -> NDArray[np.floating]: # At the moment, this is valid for diagonal observation matrices only # TODO: Include these lines into rinvprod.py, with option for # non-diagonal matrices, eventually # err = np.where(obsvect.yobs_err == 0, np.nan, obsvect.yobs_err) dy_out = dy.copy() yobs = obsvect.yobs yobs_err = obsvect.yobs_err # Raise exception if some errors are 0 or NaN if np.any((yobs_err == 0) | np.isnan(yobs_err)): raise ValueError( "Your observation errors have some zero or NaN values. " "If will make the departures infinite or NaNs in the cost " "function. Please check your observation errors in your monitor files." ) # Apply mask if any if mask is not None: if mask.shape != dy.shape: raise ValueError( f"Mask shape {mask.shape} does not match dy shape {dy.shape} in rinvprod" ) dy_out = dy_out[mask] yobs_err = yobs_err[mask] yobs = yobs[mask] if inverse: dy_out = dy_out / yobs_err**2 else: dy_out = dy_out * yobs_err + yobs # Filling masked values with zeros if mask is not None: dy_tmp = np.zeros_like(dy) dy_tmp[mask] = dy_out dy_out = dy_tmp return dy_out