示例#1
0
def test_xclim_translations(locale):
    registry_cp = registry.copy()
    loc, dic = xloc.get_local_dict(locale)
    assert "attrs_mapping" in dic
    assert "modifiers" in dic["attrs_mapping"]
    for translatable, translations in dic["attrs_mapping"].items():
        if translatable != "modifiers":
            assert isinstance(translations, list)
            assert len(translations) <= len(dic["attrs_mapping"]["modifiers"])
    assert set(dic["attrs_mapping"].keys()).symmetric_difference(
        default_formatter.mapping.keys()) == {"modifiers"}

    translated_inds = []
    # Remove unofficial indicators (as those created during the tests)
    for identifier, cls in registry.items():
        if not cls.__module__.startswith("xclim"):
            registry_cp.pop(identifier)

    for indicator, fields in dic.items():
        if indicator != "attrs_mapping":
            # Checking that the translated indicator does exist
            # For translations of children of MultiIndicators, only check that the indicator exists
            if "." in indicator:
                indicator = indicator.split(".")[0]
                assert indicator in registry_cp or indicator in translated_inds
            else:
                assert registry_cp.pop(indicator)
                translated_inds.append(indicator)
            # Only translatable attributes are translated
            assert set(fields.keys()).issubset(xloc.TRANSLATABLE_ATTRS)

    if bool(registry_cp):
        pytest.fail(
            f"Indicators {','.join(registry_cp.keys())} do not have translations for official locale {locale}."
        )
示例#2
0
def generate_local_dict(locale: str, init_english: bool = False) -> dict:
    """Generate a dictionary with keys for each indicator and translatable attributes.

    Parameters
    ----------
    locale : str
        Locale in the IETF format
    init_english : bool
        If True, fills the initial dictionary with the english versions of the attributes.
        Defaults to False.
    """
    from xclim.core.indicator import registry

    if locale in _LOCALES:
        locname, attrs = get_local_dict(locale)
        for ind_name in attrs.copy().keys():
            if ind_name != "attrs_mapping" and ind_name not in registry:
                attrs.pop(ind_name)
    else:
        attrs = {}

    attrs_mapping = attrs.setdefault("attrs_mapping", {})
    attrs_mapping.setdefault("modifiers", [""])
    for key, value in default_formatter.mapping.items():
        attrs_mapping.setdefault(key, [value[0]])

    eng_attr = ""
    for ind_name, indicator in registry.items():
        ind_attrs = attrs.setdefault(ind_name, {})
        for translatable_attr in set(TRANSLATABLE_ATTRS).difference(
                set(indicator._cf_names)  # noqa
        ):
            if init_english:
                eng_attr = getattr(indicator, translatable_attr)
                if not isinstance(eng_attr, str):
                    eng_attr = ""
            ind_attrs.setdefault(f"{translatable_attr}", eng_attr)

        for cf_attrs in indicator.cf_attrs:
            # In the case of single output, put var attrs in main dict
            if len(indicator.cf_attrs) > 1:
                ind_attrs = attrs.setdefault(
                    f"{ind_name}.{cf_attrs['var_name']}", {})

            for translatable_attr in set(TRANSLATABLE_ATTRS).intersection(
                    set(indicator._cf_names)  # noqa
            ):
                if init_english:
                    eng_attr = cf_attrs.get(translatable_attr)
                    if not isinstance(eng_attr, str):
                        eng_attr = ""
                ind_attrs.setdefault(f"{translatable_attr}", eng_attr)
    return attrs
示例#3
0
def list_input_variables(submodules: Sequence[str] = None,
                         realms: Sequence[str] = None) -> dict:
    """List all possible variables names used in xclim's indicators.

    Made for development purposes. Parses all indicator parameters with the
    :py:attribute:`xclim.core.utils.InputKind.VARIABLE` or `OPTIONAL_VARIABLE` kinds.

    Parameters
    ----------
    realms: Sequence of str, optional
      Restrict the output to indicators of a list of realms only. Default None, which parses all indicators.
    submodules: str, optional
      Restrict the output to indicators of a list of submodules only. Default None, which parses all indicators.

    Returns
    -------
    dict
      A mapping from variable name to indicator class.
    """
    from collections import defaultdict

    from xclim import indicators
    from xclim.core.indicator import registry
    from xclim.core.utils import InputKind

    submodules = submodules or [
        sub for sub in dir(indicators) if not sub.startswith("__")
    ]
    realms = realms or ["atmos", "ocean", "land", "seaIce"]

    variables = defaultdict(list)
    for name, ind in registry.items():
        if "." in name:
            # external submodule, sub module name is prepened to registry key
            if name.split(".")[0] not in submodules:
                continue
        elif ind.realm not in submodules:
            # official indicator : realm == submodule
            continue
        if ind.realm not in realms:
            continue

        # ok we want this one.
        for varname, meta in ind.iter_parameters():
            if meta["kind"] in [
                    InputKind.VARIABLE, InputKind.OPTIONAL_VARIABLE
            ]:
                var = meta.get("default") or varname
                variables[var].append(ind)

    return variables
示例#4
0
def get_indicators(realms=["atmos"], exclude=()):
    """For all modules or classes listed, return the children that are instances of registered Indicator classes.

    module : A xclim module.
    """
    from collections import OrderedDict
    from xclim.core.indicator import registry

    def filter_func(elem):
        name, ind = elem
        return (ind.realm in realms and ind.identifier is not None
                and name not in exclude and ind.identifier.upper()
                == ind._registry_id  # official indicator
                )

    out = OrderedDict(filter(filter_func, registry.items()))
    return [ind.get_instance() for ind in out.values()]