You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Jul 4, 2025. It is now read-only.
Copy file name to clipboardExpand all lines: README.md
+53-4Lines changed: 53 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -42,6 +42,8 @@ In addition to manipulating the gui with buttons in the toolbar (hover the curso
42
42
- Add a new node of the selected type by double-clicking on empty space
43
43
- Delete a node by double-clicking on it
44
44
- Collapse or expand a node by clicking on the little triangle on its body (has no effect on functionality, just makes it take less space)
45
+
- Reset an (unconnected) input port's value to its default by clicking the refresh button in the node controller window.
46
+
- Change an input port to "batched" mode by clicking the corresponding button in the node controller window.
45
47
46
48
In the default `data` execution mode (we don't currently do anything with the `exec` mode, so don't worry about it), nodes will update their output whenever their input data changes.
47
49
You'll see the node body change color when it's performing this update.
@@ -50,9 +52,43 @@ These can be triggered by a signal from another node's exec-type output port, or
50
52
51
53
In addition to the workflows screen, ironflow also incorporates the browser from [`pyiron_gui`](https://github.com/pyiron/pyiron_gui), as well as a log tab that allows you to turn the underlying ryven logger on/off and choose whether stdout gets routed to ironflow or its original context.
52
54
53
-
### Adding custom nodes
55
+
##Differences to Ryven
54
56
55
-
The tools needed for extending your graphs with new custom nodes can be imported from `ironflow.custom_nodes`.
57
+
Ironflow is built on top of ryvencore 0.3.1.1.
58
+
There are a number of minor differences between ryven nodes and ironflow nodes discussed in the next section, but at a
59
+
high level there are two significant differences:
60
+
61
+
### Typing
62
+
63
+
All node ports are typed, and connection perform type-checking to ensure validity prior to establishing a connection.
64
+
By default, a special `Untyped` data type is used, which performs *all* validity checks by value, and thus does not allow pre-wiring of a graph without full data.
65
+
Further, the validity of the current value for each IO port is indicated by the port color: green for valid, red for invalid.
66
+
67
+
You can read the full spec for the typing rules the `ironflow.model.dtypes` module, but at a high level each port has
68
+
one or more classes whose instances are valid input.
69
+
An output port can be connected to an input port as long as its valid classes are a strict subset of the input port's valid classes, and as long as the output port won't allow the the input port to be surprised by a `None` value.
70
+
71
+
This type checking is still under development and may be somewhat brittle.
72
+
Our goal is to extend this system to be dynamically informed by an ontology on top of the graph: instead of statically insisting that input be of type `float`, we instead demand that the ontological type of the energy be `surface energy`_dynamically_ because the output value of that port is used, e.g., to calculate a grain boundary interface energy.
73
+
74
+
### Batching
75
+
76
+
Many ports can be "batched" by selecting them to open the node controller window and pressing the "batched" button.
77
+
This changes the expected input for the port from a single value to a list of values.
78
+
The node operation is then iterated over the entire list, and output values are correspondingly also turned to a list.
79
+
80
+
You can quickly see which ports are batched in the graph because their labels are converted to `ALL_CAPS` while unbatched ports are `all_lower_case`.
81
+
82
+
Any number of input ports can be batched on the same node as long as _all batches are of the same length_.
83
+
84
+
Batching impacts the type checking in a (hopefully) intuitive way: a batched output port of type `float` can be fed to a batched input port of type `float` but *not* to an _unbatched_ input port of type `float`.
85
+
Similarly, an unbatched port of type `list[float]` can be passed to an input port of type `float` only if that port is batched.
86
+
Only single values and 1D lists are supported right now, although support for higher order matrices of data is planned.
87
+
88
+
89
+
## Adding custom nodes
90
+
91
+
The tools needed for extending your graphs with new custom nodes can be imported as `from ironflow import node_tools`.
56
92
New nodes can be registered either from a list of nodes, or from a python module or .py file.
57
93
In the latter two cases, only those nodes that inherit from `Node`*and* have a class name ending in `_Node` will be registered (this allows you to have your own node class templates and avoid loading the template itself by simply using regular python CamelCase naming conventions and avoiding ending in `_Node`).
58
94
@@ -86,20 +122,33 @@ Ironflow nodes differ from standard ryven (version 0.3.1.1) nodes in four ways:
86
122
- Input/output ports and the port values are directly accessible as attributes *if* those ports were labeled, e.g. `node.inputs.ports.foo` or `node.outputs.values.bar`.
87
123
- They have a `representation` dictionary, which is used by the IPython gui front-end to give a richer look at nodes. By default, this includes all the outputs and the source code for the node, but you can append to or overwrite these values by specifying an `extra_representations` dictionary on your custom nodes.
88
124
- They have two new events: `before_update` and `after_update`, to which you can connect (e.g. `node.after_update.connect`) or disconnect (`...disconnect`) methods to fire before and/or after updates occur -- such methods must take the node instance itself as the first argument, and the canonical input integer (specifying which input value it is that's updating) as the second argument. (You can see an example of this in our base `Node` class, where we use it to force an update of the `representation` attribute after each node update.)
125
+
- It is strongly advised to specify a `dtype` for each of your nodes from among `node_tools.dtypes`.
89
126
90
127
Otherwise, they are just standard ryven nodes, and all the ryven documentation applies.
91
128
129
+
### Special nodes
130
+
131
+
We also have a number of special parent node classes available based of the meta-parent `BatchingNode`.
132
+
Instead of specifying the `update_event`, children of `BatchingNode` specify other functions so that the update can be automatically batched over.
133
+
134
+
The simples of these is `DataNode`, for which children specify the `node_function` method, which must take arguments based on the labels of input ports and returns a dictionary with keys based on the labels of output ports.
135
+
Nodes of this type attempt to update themselves on placement, and will automatically update or clear (set to `None` their output ports based on whether or not all of their input ports report valid input values.
136
+
137
+
The others are `TakesJob` and `MakesJob`, children of which must specify `_modify_job` or `_generate_job` methods, respectively.
138
+
These nodes are designed to interact with pyiron's `GenericJob` objects in a functional way.
139
+
They also support batching, and will automatically populate `run` and `remove` buttons on the node widget, and lock the input after their owned job(s) are `run`.
140
+
141
+
92
142
## Structure
93
143
94
144
The code is broken into three main submodules:
95
145
-`model`, which provides and interface to and extensions of the ryven back-end
96
146
-`gui`, which has all the code for driving the back-end from the IPython visual interface
97
147
-`nodes`, which stores all the nodes that get included by default when you instantiate the gui/model
98
148
99
-
There is also a `custom_nodes` submodule, but this just exposes other parts of the code base in one easy-to-improt-from spot.
149
+
The `node_tools` submodule is just a wrapper to expose other parts of the code base in one easy-to-import-from spot.
100
150
101
151
The model itself, `HasSession`, is just a driver for a single ryven `Session`, with some helpful tools like the ability to easily register new nodes.
102
-
The only ryven element we currently extend is the `Node` class, as discussed above; other components are just imported directly from `ryvencore` in `ironflow.model.__init__`.
103
152
104
153
The gui inherits from and drives the model, and is broken down into three screens: workflows (which allow you to manipulate the model), browser (which wraps the project browser from `pyiron_gui`), and a log.
105
154
Inside the workflows screen, visual elements of the gui are broken down into subcomponents like the toolbar, a panel with a visual representation of the graph, a place to show the node representations, etc.
0 commit comments