Select Git revision
helpers.py 2.90 KiB
"""Collection of different help functions."""
__author__ = 'Lukas Leufen, Felix Kleinert'
__date__ = '2019-10-21'
import inspect
import math
import xarray as xr
from typing import Dict, Callable, Union, List, Any
def to_list(obj: Any) -> List:
"""
Transform given object to list if obj is not already a list.
:param obj: object to transform to list
:return: list containing obj, or obj itself (if obj was already a list)
"""
if not isinstance(obj, list):
obj = [obj]
return obj
def dict_to_xarray(d: Dict, coordinate_name: str) -> xr.DataArray:
"""
Convert a dictionary of 2D-xarrays to single 3D-xarray. The name of new coordinate axis follows <coordinate_name>.
:param d: dictionary with 2D-xarrays
:param coordinate_name: name of the new created axis (2D -> 3D)
:return: combined xarray
"""
xarray = None
for k, v in d.items():
if xarray is None:
xarray = v
xarray.coords[coordinate_name] = k
else:
tmp_xarray = v
tmp_xarray.coords[coordinate_name] = k
xarray = xr.concat([xarray, tmp_xarray], coordinate_name)
return xarray
def float_round(number: float, decimals: int = 0, round_type: Callable = math.ceil) -> float:
"""
Perform given rounding operation on number with the precision of decimals.
:param number: the number to round
:param decimals: numbers of decimals of the rounding operations (default 0 -> round to next integer value)
:param round_type: the actual rounding operation. Can be any callable function like math.ceil, math.floor or python
built-in round operation.
:return: rounded number with desired precision
"""
multiplier = 10. ** decimals
return round_type(number * multiplier) / multiplier
def remove_items(obj: Union[List, Dict], items: Any):
"""
Remove item(s) from either list or dictionary.
:param obj: object to remove items from (either dictionary or list)
:param items: elements to remove from obj. Can either be a list or single entry / key
:return: object without items
"""
def remove_from_list(list_obj, item_list):
"""Remove implementation for lists."""
if len(items) > 1:
return [e for e in list_obj if e not in item_list]
else:
list_obj = list_obj.copy()
try:
list_obj.remove(item_list[0])
except ValueError:
pass
return list_obj
def remove_from_dict(dict_obj, key_list):
"""Remove implementation for dictionaries."""
return {k: v for k, v in dict_obj.items() if k not in key_list}
items = to_list(items)
if isinstance(obj, list):
return remove_from_list(obj, items)
elif isinstance(obj, dict):
return remove_from_dict(obj, items)
else:
raise TypeError(f"{inspect.stack()[0][3]} does not support type {type(obj)}.")