Source code for finam.adapters.base
"""
Basic data transformation adapters.
"""
import numpy as np
from ..data.grid_spec import NoGrid
from ..data.tools import Mask, get_magnitude, mask_specified
from ..errors import FinamMetaDataError
from ..sdk import Adapter
from ..tools.log_helper import ErrorLogger
__all__ = [
"Callback",
"Scale",
"ValueToGrid",
"GridToValue",
]
[docs]
class Callback(Adapter):
"""Transform data using a callback.
Examples
--------
.. testcode:: constructor
import finam as fm
adapter = fm.adapters.Callback(
callback=lambda data, t: data * 2,
)
Parameters
----------
callback : callable
A callback ``callback(data, time)``, returning the transformed data.
"""
def __init__(self, callback):
super().__init__()
self.callback = callback
[docs]
def _get_data(self, time, target):
"""Get the output's data-set for the given time.
Parameters
----------
time : datetime
Simulation time to get the data for.
Returns
-------
array_like
data-set for the requested time.
"""
d = self.pull_data(time, target)
return self.callback(d, time)
[docs]
class Scale(Adapter):
"""Scales the input.
Examples
--------
.. testcode:: constructor
import finam as fm
adapter = fm.adapters.Scale(scale=0.5)
Parameters
----------
scale : float
Scale factor.
"""
def __init__(self, scale):
super().__init__()
self.scale = scale
[docs]
def _get_data(self, time, target):
"""Get the output's data-set for the given time.
Parameters
----------
time : datetime
simulation time to get the data for.
Returns
-------
array_like
data-set for the requested time.
"""
d = self.pull_data(time, target)
return d * self.scale
[docs]
class ValueToGrid(Adapter):
"""Convert a scalar value to a Matrix filled with that value.
Examples
--------
.. testcode:: constructor
import finam as fm
adapter = fm.adapters.ValueToGrid(
grid=fm.UniformGrid(dims=(10, 20))
)
adapter = fm.adapters.ValueToGrid(grid=None)
Parameters
----------
grid: :any:`Grid`, optional
Grid specification to create grid for.
Will be ``None`` by default to get it from the target.
mask : :any:`Mask` value or valid boolean mask for :any:`MaskedArray`, optional
masking specification of the data. Options:
* :any:`Mask.FLEX`: data can be masked or unmasked
* :any:`Mask.NONE`: data is unmasked and given as plain numpy array
* valid boolean mask for MaskedArray
Will be ``None`` by default to get it from the target.
"""
def __init__(self, grid=None, mask=None):
super().__init__()
self.grid = grid
self.mask = mask
[docs]
def _get_data(self, time, target):
"""Get the output's data-set for the given time.
Parameters
----------
time : datetime
simulation time to get the data for.
Returns
-------
array_like
data-set for the requested time.
"""
value = self.pull_data(time, target)
data = np.full(self.info.grid_shape, get_magnitude(value))
if mask_specified(self.info.mask):
return np.ma.array(data, mask=self.info.mask)
return data
[docs]
def _get_info(self, info):
up_info = info.copy_with(grid=NoGrid(), mask=Mask.FLEX)
in_info = self.exchange_info(up_info)
out_info = in_info.copy_with(
grid=self.grid or info.grid, mask=self.mask or info.mask, use_none=False
)
if info.grid is not None and info.grid != out_info.grid:
with ErrorLogger(self.logger):
raise FinamMetaDataError(
f"Grid specifications don't match. Target has {info.grid}, expected {out_info.grid}"
)
return out_info
[docs]
class GridToValue(Adapter):
"""Convert a matrix to a scalar value using an aggregation function, e.g. ``numpy.mean``.
Examples
--------
.. testcode:: constructor
import numpy as np
import finam as fm
adapter = fm.adapters.GridToValue(func=np.mean)
Parameters
----------
func : callable
A function ``func(data)``, returning the transformed data.
"""
def __init__(self, func):
super().__init__()
self.func = func
[docs]
def _get_data(self, time, target):
"""Get the output's data-set for the given time.
Parameters
----------
time : datetime
simulation time to get the data for.
Returns
-------
array_like
data-set for the requested time.
"""
grid = self.pull_data(time, target)
return self.func(get_magnitude(grid))
[docs]
def _get_info(self, info):
info = info.copy_with(grid=None)
in_info = self.exchange_info(info)
out_info = in_info.copy_with(grid=NoGrid(), mask=Mask.NONE)
return out_info