Source code for pycif.plugins.datastreams.fluxes.dummy_txt.make.fromformula

import numpy as np
from ......utils.check.errclass import CifError


[docs] def makefromformula(formula, zlon, zlat, formula_type="sum"): """Recursively evaluate a nested-dict formula into a 2D flux array. The formula is a nested dictionary tree: a node either declares an aggregation operator (``"sum"`` or ``"product"`` of a list of sub-formulas), or a unary operator (``"cos"``, ``"sin"``, ``"exp"``, ``"log"`` or ``"square"``) applied to ``zlon`` or ``zlat`` (selected via a ``"variable"`` key), optionally divided by a ``"period"`` value (default 1) before the operator is applied. Args: formula (dict): the (sub-)formula to evaluate; either a leaf node with a ``"variable"`` key (``"zlon"`` or ``"zlat"``) and one operator key set to ``None``, plus an optional ``"period"`` key, or an aggregation node with a single key (``"sum"`` or ``"product"``) mapping to a list of sub-formulas. zlon (np.ndarray): 2D array of longitudes (grid centers). zlat (np.ndarray): 2D array of latitudes (grid centers). formula_type (str): aggregation operator to use when combining a list of sub-formula results (``"sum"`` or ``"product"``); only relevant for aggregation nodes. Returns: np.ndarray: the 2D array resulting from evaluating the formula, same shape as ``zlon``/``zlat``. Raises: CifError: if an unrecognized ``"variable"`` or operator is encountered. """ # If variable in formula, means applying an operator if "variable" in formula: if formula["variable"] == "zlat": var = zlat elif formula["variable"] == "zlon": var = zlon else: raise CifError("Not recognized variable type (only zlon and zlat):" + formula["variable"]) formula_type = [k for k in formula if formula[k] is None][0] period = formula.get("period", 1) if formula_type == "cos": return np.cos(var / period) elif formula_type == "sin": return np.sin(var / period) elif formula_type == "exp": return np.exp(var / period) elif formula_type == "log": return np.exp(var / period) elif formula_type == "square": return (var / period) ** 2 else: raise CifError("Not recognized operation:" + formula_type) # Otherwise formula_type = list(formula.keys())[0] tmp_vars = [ makefromformula(formula_tmp, zlon, zlat, formula_type=formula_type) for formula_tmp in formula[formula_type] ] if formula_type == "sum": out = 0. for var in tmp_vars: out += var return out elif formula_type == "product": out = 1. for var in tmp_vars: out *= var return out else: raise CifError("Not recognized operation:" + formula_type)