Skip to content
Snippets Groups Projects
Commit c070e2cf authored by Martin Lange's avatar Martin Lange
Browse files

add tests for chapter on connect phase

parent 480d462b
No related branches found
No related tags found
1 merge request!127Doc-tests
Pipeline #123365 passed with stages
in 4 minutes and 17 seconds
This commit is part of merge request !127. Comments created here will be created in the context of that merge request.
...@@ -136,20 +136,62 @@ Simple case - no dependencies ...@@ -136,20 +136,62 @@ Simple case - no dependencies
In the most simple case, all metadata is known in :meth:`.Component._initialze`, and data is pushed in :attr:`.Component._connect()`: In the most simple case, all metadata is known in :meth:`.Component._initialze`, and data is pushed in :attr:`.Component._connect()`:
.. code-block:: Python .. testcode:: simple-connect
import finam as fm
class SimpleConnect(TimeComponent): class SimpleConnect(fm.TimeComponent):
def __init__(self, time):
super().__init__()
self.time = time
def _initialize(self): def _initialize(self):
self.inputs.add(name="A", grid=NoGrid(), units="m") self.inputs.add(name="A", time=self.time, grid=fm.NoGrid(), units="m")
self.inputs.add(name="B", grid=NoGrid(), units="m") self.inputs.add(name="B", time=self.time, grid=fm.NoGrid(), units="m")
self.outputs.add(name="Area", grid=NoGrid(), units="m2") self.outputs.add(name="Area", time=self.time, grid=fm.NoGrid(), units="m2")
self.create_connector() self.create_connector()
def _connect(self): def _connect(self):
push_data = {"Area": 0} push_data = {"Area": 0}
self.try_connect(time=self.time, push_data=push_data) self.try_connect(push_data=push_data)
def _validate(self):
pass
# etc...
.. testcode:: simple-connect
:hide:
from datetime import datetime, timedelta
generator = fm.modules.CallbackGenerator(
{
"Output1": (lambda t: t.day, fm.Info(time=None, grid=fm.NoGrid())),
"Output2": (lambda t: t.day, fm.Info(time=None, grid=fm.NoGrid())),
},
start=datetime(2000, 1, 1),
step=timedelta(days=30),
)
simple_conn = SimpleConnect(datetime(2000, 1, 1))
consumer = fm.modules.DebugConsumer(
{"Input": fm.Info(None, grid=fm.NoGrid())},
start=datetime(2000, 1, 1),
step=timedelta(days=1),
)
comp = fm.Composition([generator, simple_conn, consumer])
comp.initialize()
generator.outputs["Output1"] >> simple_conn.inputs["A"]
generator.outputs["Output2"] >> simple_conn.inputs["B"]
simple_conn.outputs["Area"] >> consumer.inputs["Input"]
comp.connect()
In :meth:`.Component._initialize`, we create inputs and outputs with metadata (here ``grid`` and ``units``). In :meth:`.Component._initialize`, we create inputs and outputs with metadata (here ``grid`` and ``units``).
Then, we create the connector with ``self.create_connector()``. No arguments required here, as there are no dependencies. Then, we create the connector with ``self.create_connector()``. No arguments required here, as there are no dependencies.
...@@ -163,13 +205,19 @@ In this example, we want to get a grid specification from an input. ...@@ -163,13 +205,19 @@ In this example, we want to get a grid specification from an input.
This grid specification should then be used for the metadata of the output, This grid specification should then be used for the metadata of the output,
and the initial data should be generated from it. and the initial data should be generated from it.
.. code-block:: Python .. testcode:: complex-connect
class ComplexConnect(TimeComponent): import finam as fm
class ComplexConnect(fm.TimeComponent):
def __init__(self, time):
super().__init__()
self.time = time
def _initialize(self): def _initialize(self):
self.inputs.add(name="A", grid=None, units="m") self.inputs.add(name="A", time=self.time, grid=None, units="m")
self.inputs.add(name="B", grid=NoGrid(), units="m") self.inputs.add(name="B", time=self.time, grid=fm.NoGrid(), units="m")
self.outputs.add(name="Area") self.outputs.add(name="Area")
self.create_connector() self.create_connector()
...@@ -188,6 +236,45 @@ and the initial data should be generated from it. ...@@ -188,6 +236,45 @@ and the initial data should be generated from it.
push_infos=push_infos, push_infos=push_infos,
push_data=push_data) push_data=push_data)
def _validate(self):
pass
# etc...
.. testcode:: complex-connect
:hide:
from datetime import datetime, timedelta
def _generate_data(info):
return 0
generator = fm.modules.CallbackGenerator(
{
"Output1": (lambda t: t.day, fm.Info(time=None, grid=fm.NoGrid())),
"Output2": (lambda t: t.day, fm.Info(time=None, grid=fm.NoGrid())),
},
start=datetime(2000, 1, 1),
step=timedelta(days=30),
)
complex_conn = ComplexConnect(datetime(2000, 1, 1))
consumer = fm.modules.DebugConsumer(
{"Input": fm.Info(None, grid=fm.NoGrid())},
start=datetime(2000, 1, 1),
step=timedelta(days=1),
)
comp = fm.Composition([generator, complex_conn, consumer])
comp.initialize()
generator.outputs["Output1"] >> complex_conn.inputs["A"]
generator.outputs["Output2"] >> complex_conn.inputs["B"]
complex_conn.outputs["Area"] >> consumer.inputs["Input"]
comp.connect()
In :meth:`.Component._initialize`, we set the ``grid`` of input ``"A"`` to ``None``. In :meth:`.Component._initialize`, we set the ``grid`` of input ``"A"`` to ``None``.
It will be filled from the connected output, and becomes available in It will be filled from the connected output, and becomes available in
:attr:`connector.in_infos <.ConnectHelper.in_infos>` after successful exchange. :attr:`connector.in_infos <.ConnectHelper.in_infos>` after successful exchange.
...@@ -215,20 +302,27 @@ The process works in both directions. ...@@ -215,20 +302,27 @@ The process works in both directions.
Any metadata field that is initialized with ``None`` will be filled with the value from the other end of the connection. Any metadata field that is initialized with ``None`` will be filled with the value from the other end of the connection.
This can happen in the initialization of inputs and outputs: This can happen in the initialization of inputs and outputs:
.. code-block:: Python .. testsetup:: no-metadata
from finam import Component, Info, NoGrid
from datetime import datetime
self = Component()
.. testcode:: no-metadata
self.inputs.add(name="A", grid=None, units=None) self.inputs.add(name="A", time=None, grid=None, units=None)
self.outputs.add(name="Area", grid=NoGrid(), units=None) self.outputs.add(name="Area", time=None, grid=NoGrid(), units=None)
Here, ``grid`` and ``units`` of the input would be filled from a connected output. Here, ``time``, ``grid`` and ``units`` of the input would be filled from a connected output.
For the output, ``units`` would be filled from a connected input. For the output, ``time`` and ``units`` would be filled from a connected input.
The same mechanism can also be applied in :meth:`.Component._connect`: The same mechanism can also be applied in :meth:`.Component._connect`:
.. code-block:: Python .. code-block:: Python
info = Info(grid=None, units="m") info = Info(time=None, grid=None, units="m")
self.try_connect(time=self.time, in_infos={"A": info}) self.try_connect(exchange_infos={"A": info})
Summary metadata initialization Summary metadata initialization
------------------------------- -------------------------------
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment