Source code for pycif.plugins.obsoperators.standard.transforms.utils.init_reindex

import numpy as np
from logging import debug
from . import add_default


[docs] def init_reindex( self, trid, tmp_dict, trid_dict, precursor_id, transform, param, all_transforms, mapper, backup_comps, precursors, do_pipe_entry=False ): """Insert a time-interpolation transform if the date indices differ. Compares the ``input_dates`` of ``tmp_dict`` (a precursor's output) against ``trid_dict`` (the target input), per sub-simulation. If they already match exactly for every sub-simulation, nothing is inserted. Otherwise, a ``time_interpolation`` transform is created via :func:`add_default.add_default` and spliced between ``precursor_id`` and ``transform``. Args: self: The parent object (obs operator) holding the transform pipe. trid: ``(component, parameter)`` tuple identifying the tracer. tmp_dict: Attribute dictionary of the source side (precursor's output), holding ``"input_dates"`` and ``"sparse_data"``. trid_dict: Attribute dictionary of the target side (this transform's input), holding ``"input_dates"`` to compare against. precursor_id: Id of the precursor transform providing the data. transform: Id of the transform whose input is being checked. param: Object holding an optional ``time_interpolation`` configuration block used to parametrize the inserted transform. all_transforms: Namespace holding all registered transform instances. mapper: Dictionary mapping each transform id to its inputs/outputs metadata, updated when a new transform is inserted. backup_comps: Backup of components used to restore/compare state. precursors: Precursors metadata, kept for interface consistency with related init functions. do_pipe_entry: Whether to run the pipe-entry initialization step for the newly inserted transform. Returns: str: The id of the transform now directly feeding ``transform`` for this trid — either the newly inserted ``time_interpolation`` transform, or the original ``precursor_id`` if indices already match. """ cmp, prm = trid # Differentiate sparse data versus matrix data if trid_dict.get("sparse_data", False): same_index = [ np.all( tmp_dict["input_dates"][ddi] == trid_dict["input_dates"].get(ddi, [ ]) ) if len(tmp_dict["input_dates"][ddi]) == len(trid_dict["input_dates"].get(ddi, [])) else False for ddi in tmp_dict["input_dates"] ] else: # For matrix data, check if the index in the outputs (tmp_dict) # is included in the input (trid_dict) # If there are more dates available in inputs, don't do the # interpolation prec_dates = tmp_dict.get("input_dates", []) ref_dates = trid_dict.get("input_dates", []) same_index = [ np.all(ref_dates[ddi] == prec_dates.get(ddi, [])) if len(ref_dates[ddi]) == len(prec_dates.get(ddi, [])) else False for ddi in ref_dates ] if sum(same_index) == len(same_index): return precursor_id debug(f' Temporal re-indexing if any: {prm} / {param}') tinterp = getattr(param, "time_interpolation", None) yml_dict = { "plugin": { "name": "time_interpolation", "version": "std", "type": "transform", }, "method": getattr(tinterp, "method", "bilinear"), "component": [cmp], "parameter": [prm], "successor": transform, "precursor": precursor_id, **{attr: getattr(tinterp, attr) for attr in getattr(tinterp, "attributes", []) if attr != "plugin"} } ref_precursor = {(cmp, prm): precursor_id} ref_successor = {(cmp, prm): transform} new_transf, new_id = add_default.add_default( self, all_transforms, yml_dict, position="index", index=all_transforms.attributes.index(transform), mapper=mapper, init=True, backup_comps=backup_comps, successor=ref_successor, precursor=ref_precursor, do_pipe_entry=do_pipe_entry ) return new_id