diff --git a/src/xscen/utils.py b/src/xscen/utils.py index 2c3ba35f..da134f31 100644 --- a/src/xscen/utils.py +++ b/src/xscen/utils.py @@ -57,8 +57,9 @@ TRANSLATOR = defaultdict(lambda: lambda s: s) """Dictionary of translating objects. -Each key is a two letter locale code and values are functions that return the translated message as compiled in the gettext catalogs. -If a language is not defined or a message not translated, the function will return the raw message. +Each key is a two letter locale code and values are functions that return the translated message +as compiled in the gettext catalogs. If a language is not defined or a message not translated, +the function will return the raw message. """ try: @@ -69,7 +70,8 @@ ).gettext except FileNotFoundError as err: raise ImportError( - "Your xscen installation doesn't have compiled translations. Run `make translate` from the source directory to fix." + "Your xscen installation doesn't have compiled translations. " + "Run `make translate` from the source directory to fix." ) from err @@ -80,11 +82,11 @@ def update_attr( others: Optional[Sequence[Union[xr.Dataset, xr.DataArray]]] = None, **fmt, ) -> Union[xr.Dataset, xr.DataArray]: - """Format an attribute referencing itself in a translatable way. + r"""Format an attribute referencing itself in a translatable way. Parameters ---------- - ds: Dataset or DataArray + ds : Dataset or DataArray The input object with the attribute to update. attr : str Attribute name. @@ -96,7 +98,7 @@ def update_attr( These can be referenced as "{attrXX}" in `new`, where XX is the based-1 index of the other source in `others`. If they don't have the `attr` attribute, an empty string is sent to the string formatting. See notes. - fmt: + \*\*fmt Other formatting data. Returns @@ -176,7 +178,8 @@ def date_parser( # noqa: C901 Date to be converted end_of_period : bool or str If 'YE' or 'ME', the returned date will be the end of the year or month that contains the received date. - If True, the period is inferred from the date's precision, but `date` must be a string, otherwise nothing is done. + If True, the period is inferred from the date's precision, but `date` must be a string, + otherwise nothing is done. out_dtype : str Choices are 'datetime', 'period' or 'str' strtime_format : str @@ -267,8 +270,7 @@ def _parse_date(date, fmts): def minimum_calendar(*calendars) -> str: """Return the minimum calendar from a list. - Uses the hierarchy: 360_day < noleap < standard < all_leap, - and returns one of those names. + Uses the hierarchy: 360_day < noleap < standard < all_leap, and returns one of those names. """ if "360_day" in calendars: return "360_day" @@ -285,6 +287,8 @@ def minimum_calendar(*calendars) -> str: def translate_time_chunk(chunks: dict, calendar: str, timesize) -> dict: """Translate chunk specification for time into a number. + Notes + ----- -1 translates to `timesize` 'Nyear' translates to N times the number of days in a year of calendar `calendar`. """ @@ -488,8 +492,7 @@ def unstack_fill_nan( def natural_sort(_list: list[str]): - """ - For strings of numbers. alternative to sorted() that detects a more natural order. + """For strings of numbers. alternative to sorted() that detects a more natural order. e.g. [r3i1p1, r1i1p1, r10i1p1] is sorted as [r1i1p1, r3i1p1, r10i1p1] instead of [r10i1p1, r1i1p1, r3i1p1] """ @@ -507,18 +510,17 @@ def get_cat_attrs( Parameters ---------- - ds: xr.Dataset, dict + ds : xr.Dataset, dict Dataset to be parsed. If a dictionary, it is assumed to be the attributes of the dataset (ds.attrs). - prefix: str + prefix : str Prefix automatically generated by intake-esm. With xscen, this should be 'cat:' - var_as_str: bool + var_as_str : bool If True, 'variable' will be returned as a string if there is only one. Returns ------- dict Compilation of all attributes in a dictionary. - """ if isinstance(ds, (xr.Dataset, xr.DataArray)): attrs = ds.attrs @@ -592,31 +594,31 @@ def maybe_unstack( xs.utils.CV.frequency_to_timedelta.dict - .. literalinclude:: ../xscen/CVs/frequency_to_timedelta.json + .. literalinclude:: ../src/xscen/CVs/frequency_to_timedelta.json :language: json :caption: frequency_to_timedelta - .. literalinclude:: ../xscen/CVs/frequency_to_xrfreq.json + .. literalinclude:: ../src/xscen/CVs/frequency_to_xrfreq.json :language: json :caption: frequency_to_xrfreq - .. literalinclude:: ../xscen/CVs/infer_resolution.json + .. literalinclude:: ../src/xscen/CVs/infer_resolution.json :language: json :caption: infer_resolution - .. literalinclude:: ../xscen/CVs/resampling_methods.json + .. literalinclude:: ../src/xscen/CVs/resampling_methods.json :language: json :caption: resampling_methods - .. literalinclude:: ../xscen/CVs/variable_names.json + .. literalinclude:: ../src/xscen/CVs/variable_names.json :language: json :caption: variable_names - .. literalinclude:: ../xscen/CVs/xrfreq_to_frequency.json + .. literalinclude:: ../src/xscen/CVs/xrfreq_to_frequency.json :language: json :caption: xrfreq_to_frequency - .. literalinclude:: ../xscen/CVs/xrfreq_to_timedelta.json + .. literalinclude:: ../src/xscen/CVs/xrfreq_to_timedelta.json :language: json :caption: xrfreq_to_timedelta @@ -636,14 +638,14 @@ def __read_CVs(cvfile): Parameters ---------- - key: str - The value to translate.{regex} + key : str + The value to translate.{regex} default : 'pass', 'error' or Any - If the key is not found in the mapping, default controls the behaviour. + If the key is not found in the mapping, default controls the behaviour. - - "error", a KeyError is raised (default). - - "pass", the key is returned. - - another value, that value is returned. + - "error", a KeyError is raised (default). + - "pass", the key is returned. + - another value, that value is returned. """ def cvfunc(key, default="error"): @@ -764,22 +766,24 @@ def clean_up( # noqa: C901 ds : xr.Dataset Input dataset to clean up variables_and_units : dict, optional - Dictionary of variable to convert. eg. {'tasmax': 'degC', 'pr': 'mm d-1'} + Dictionary of variable to convert. e.g. {'tasmax': 'degC', 'pr': 'mm d-1'} convert_calendar_kwargs : dict, optional Dictionary of arguments to feed to xclim.core.calendar.convert_calendar. This will be the same for all variables. If missing_by_vars is given, it will override the 'missing' argument given here. Eg. {target': default, 'align_on': 'random'} missing_by_var : dict, optional Dictionary where the keys are the variables and the values are the argument to feed the `missing` - parameters of the xclim.core.calendar.convert_calendar for the given variable with the `convert_calendar_kwargs`. - When the value of an entry is 'interpolate', the missing values will be filled with NaNs, then linearly interpolated over time. + parameters of the xclim.core.calendar.convert_calendar for the given variable with the + `convert_calendar_kwargs`. When the value of an entry is 'interpolate', the missing values will be filled + with NaNs, then linearly interpolated over time. maybe_unstack_dict : dict, optional Dictionary to pass to xscen.common.maybe_unstack function. The format should be: {'coords': path_to_coord_file, 'rechunk': {'time': -1 }, 'stack_drop_nans': True}. round_var : dict, optional - Dictionary where the keys are the variables of the dataset and the values are the number of decimal places to round to + Dictionary where the keys are the variables of the dataset and the values are the number of + decimal places to round to. common_attrs_only : dict, list of datasets, or list of paths, optional - Dictionnary of datasets or list of datasets, or path to NetCDF or Zarr files. + Dictionary of datasets or list of datasets, or path to NetCDF or Zarr files. Keeps only the global attributes that are the same for all datasets and generates a new id. common_attrs_open_kwargs : dict, optional Dictionary of arguments for xarray.open_dataset(). Used with common_attrs_only if given paths. @@ -790,7 +794,7 @@ def clean_up( # noqa: C901 or use the same substring matching rules as intake_esm: - ending with a '*' means checks if the substring is contained in the string - starting with a '^' means check if the string starts with the substring. - eg. {'global': ['unnecessary note', 'cell*'], 'tasmax': 'old_name'} + e.g. {'global': ['unnecessary note', 'cell*'], 'tasmax': 'old_name'} remove_all_attrs_except : dict, optional Dictionary where the keys are the variables and the values are a list of the attrs that should NOT be removed, all other attributes will be deleted. If None (default), nothing will be deleted. @@ -799,11 +803,11 @@ def clean_up( # noqa: C901 or use the same substring matching rules as intake_esm: - ending with a '*' means checks if the substring is contained in the string - starting with a '^' means check if the string starts with the substring. - eg. {'global': ['necessary note', '^cat:'], 'tasmax': 'new_name'} + e.g. {'global': ['necessary note', '^cat:'], 'tasmax': 'new_name'} add_attrs : dict, optional Dictionary where the keys are the variables and the values are a another dictionary of attributes. For global attrs, use the key 'global'. - eg. {'global': {'title': 'amazing new dataset'}, 'tasmax': {'note': 'important info about tasmax'}} + e.g. {'global': {'title': 'amazing new dataset'}, 'tasmax': {'note': 'important info about tasmax'}} change_attr_prefix : str, optional Replace "cat:" in the catalog global attrs by this new string to_level : str, optional @@ -969,8 +973,7 @@ def publish_release_notes( Notes ----- - This function exists solely for development purposes. - Adapted from xclim.testing.utils.publish_release_notes. + This function exists solely for development purposes. Adapted from xclim.testing.utils.publish_release_notes. """ if isinstance(changes, (str, Path)): changes_file = Path(changes).absolute() @@ -1039,17 +1042,17 @@ def unstack_dates( Parameters ---------- - ds: xr.Dataset or DataArray + ds : xr.Dataset or DataArray The xarray object with a "time" coordinate. Only supports monthly or coarser frequencies. The time axis must be complete and regular (`xr.infer_freq(ds.time)` doesn't fail). - seasons: dict, optional + seasons : dict, optional A dictionary from month number (as int) to a season name. - If not given, it is guessed from the time coord's frequency. + If not given, it is guessed from the time coordinate frequency. See notes. - new_dim: str + new_dim : str The name of the new dimension. - winter_starts_year: bool + winter_starts_year : bool If True, the year of winter (DJF) is built from the year of January, not December. i.e. DJF made from [Dec 1980, Jan 1981, and Feb 1981] will be associated with the year 1981, not 1980. @@ -1250,8 +1253,7 @@ def show_versions( def ensure_correct_time(ds: xr.Dataset, xrfreq: str) -> xr.Dataset: - """ - Ensure a dataset has the correct time coordinate, as expected for the given frequency. + """Ensure a dataset has the correct time coordinate, as expected for the given frequency. Daily or finer datasets are "floored" even if `xr.infer_freq` succeeds. Errors are raised if the number of data points per period is not 1.