Skip to content

Commit

Permalink
Merge pull request #199 from pyiron/split_node_packages
Browse files Browse the repository at this point in the history
Split node packages
  • Loading branch information
liamhuber authored May 16, 2023
2 parents dcc5287 + ef639d9 commit 2ae8a53
Show file tree
Hide file tree
Showing 17 changed files with 590 additions and 569 deletions.
1 change: 1 addition & 0 deletions ironflow/gui/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ def __init__(
)

self.workflows = WorkflowsGUI(gui=self)
self.workflows.flow_box.node_selector.select_module(self._starting_module)
self.browser = BrowserGUI()

try:
Expand Down
3 changes: 3 additions & 0 deletions ironflow/gui/workflows/boxes/flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ def module_options(self) -> list[str]:
def nodes_options(self) -> list[str]:
return sorted(self._nodes_dictionary[self.modules_dropdown.value].keys())

def select_module(self, module_name):
self.modules_dropdown.value = module_name

def update(self, nodes_dictionary: dict) -> None:
self._nodes_dictionary = nodes_dictionary
self.modules_dropdown.options = self.module_options
Expand Down
18 changes: 6 additions & 12 deletions ironflow/model/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,16 @@ def __init__(
self.session.info_messenger().enable()

self.nodes_dictionary = {"recommended": {}}
from ironflow.nodes import built_in
from ironflow.nodes.pyiron import atomistics_nodes
from ironflow.nodes.std import (
basic_operators,
control_structures,
special_nodes,
)
from ironflow.nodes import array, plot, pyiron_atomistics, standard

for module in [
built_in,
atomistics_nodes,
basic_operators,
control_structures,
special_nodes,
array,
plot,
pyiron_atomistics,
standard,
]:
self.register_nodes_from_module(module)
self._starting_module = pyiron_atomistics.__name__.split(".")[-1]

if extra_nodes_packages is not None:
for package in extra_nodes_packages:
Expand Down
140 changes: 140 additions & 0 deletions ironflow/nodes/array.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
from __future__ import annotations

import numpy as np

from ironflow.model import dtypes
from ironflow.model.node import DataNode
from ironflow.model.port import NodeInputBP, NodeOutputBP


class Select_Node(DataNode):
"""
Select a single elemnt of an iterable input.
"""

title = "Select"
init_inputs = [
NodeInputBP(dtype=dtypes.List(valid_classes=object), label="array"),
NodeInputBP(dtype=dtypes.Integer(default=0), label="i"),
]
init_outputs = [
NodeOutputBP(label="item", dtype=dtypes.Data(valid_classes=object)),
]
color = "#aabb44"

def node_function(self, array, i, **kwargs) -> dict:
return {"item": array[i]}


class Slice_Node(DataNode):
"""
Slice a numpy array, list, or tuple, and return it as a numpy array.
When both `i` and `j` are `None`: Return the input whole.
When `i` is not `None` and `j` is: Return the slice `[i:]`
When `i` is `None` and `j` isn't: Return the slice `[:j]`
When neither are `None`: Return the slice `[i:j]`
"""

title = "Slice"
init_inputs = [
NodeInputBP(dtype=dtypes.List(valid_classes=object), label="array"),
NodeInputBP(dtype=dtypes.Integer(default=None, allow_none=True), label="i"),
NodeInputBP(dtype=dtypes.Integer(default=None, allow_none=True), label="j"),
]
init_outputs = [
NodeOutputBP(label="sliced", dtype=dtypes.List(valid_classes=object)),
]
color = "#aabb44"

def node_function(self, array, i, j, **kwargs) -> dict:
converted = np.array(array)
if i is None and j is None:
sliced = converted
elif i is not None and j is None:
sliced = converted[i:]
elif i is None and j is not None:
sliced = converted[:j]
else:
sliced = converted[i:j]
return {"sliced": sliced}


class Transpose_Node(DataNode):
"""
Interprets list-like input as a numpy array and transposes it.
"""

title = "Transpose"
init_inputs = [
NodeInputBP(dtype=dtypes.List(valid_classes=object), label="array"),
]
init_outputs = [
NodeOutputBP(dtype=dtypes.List(valid_classes=object), label="transposed"),
]
color = "#aabb44"

def node_function(self, array, **kwargs) -> dict:
array = np.array(array) # Ensure array
if len(array.shape) < 2:
array = np.array([array]) # Ensure transposable
return {"transposed": np.array(array).T}


class IntRand_Node(DataNode):
"""
Generate a random non-negative integer.
Inputs:
high (int): Biggest possible integer. (Default is 1).
length (int): How many random numbers to generate. (Default is 1.)
Outputs:
randint (int|numpy.ndarray): The randomly generated value(s).
"""

# this __doc__ string will be displayed as tooltip in the editor

title = "IntRandom"
init_inputs = [
NodeInputBP(dtype=dtypes.Integer(default=0), label="low"),
NodeInputBP(dtype=dtypes.Integer(default=1), label="high"),
NodeInputBP(dtype=dtypes.Integer(default=1), label="length"),
]
init_outputs = [
NodeOutputBP(dtype=dtypes.List(valid_classes=np.integer), label="randint"),
]
color = "#aabb44"

def node_function(self, low, high, length, *args, **kwargs) -> dict:
return {"randint": np.random.randint(low, high=high, size=length)}


class Linspace_Node(DataNode):
"""
Generate a linear mesh in a given range using `np.linspace`.
Inputs:
min (int): The lower bound (inclusive). (Default is 1.)
max (int): The upper bound (inclusive). (Default is 2.)
steps (int): How many samples to take inside (min, max). (Default is 10.)
Outputs:
linspace (numpy.ndarray): A uniform sampling over the requested range.
"""

# this __doc__ string will be displayed as tooltip in the editor

title = "Linspace"
init_inputs = [
NodeInputBP(dtype=dtypes.Float(default=1.0), label="min"),
NodeInputBP(dtype=dtypes.Float(default=2.0), label="max"),
NodeInputBP(dtype=dtypes.Integer(default=10), label="steps"),
]
init_outputs = [
NodeOutputBP(dtype=dtypes.List(valid_classes=np.floating), label="linspace")
]
color = "#aabb44"

def node_function(self, min, max, steps, **kwargs) -> dict:
return {"linspace": np.linspace(min, max, steps)}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
73 changes: 73 additions & 0 deletions ironflow/nodes/deprecated/flow_control.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from __future__ import annotations

from ironflow.model import dtypes
from ironflow.model.node import Node
from ironflow.model.port import NodeInputBP, NodeOutputBP
from ironflow.node_tools import main_widgets
from ironflow.nodes.deprecated.special_nodes import DualNodeBase


class ForEach_Node(Node):
title = "ForEach"
version = "v0.1"
init_inputs = [
NodeInputBP(type_="exec", label="start"),
NodeInputBP(type_="exec", label="reset"),
NodeInputBP(dtype=dtypes.List(), label="elements"),
]
init_outputs = [
NodeOutputBP(label="loop", type_="exec"),
NodeOutputBP(label="e", type_="data"),
NodeOutputBP(label="finished", type_="exec"),
]
color = "#b33a27"

_count = 0

def update_event(self, inp=-1):
if inp == 0:
self._count += 1
if len(self.inputs.values.elements) > self._count:
e = self.inputs.values.elements[self._count]
self.set_output_val(1, e)
self.exec_output(0)
else:
self.exec_output(2)
elif inp > 0:
self._count = 0
self.val = self._count


class ExecCounter_Node(DualNodeBase):
title = "ExecCounter"
version = "v0.1"
init_inputs = [
NodeInputBP(type_="exec"),
]
init_outputs = [
NodeOutputBP(type_="exec"),
]
color = "#5d95de"

def __init__(self, params):
super().__init__(params, active=True)
self._count = 0

def update_event(self, inp=-1):
if self.active and inp == 0:
self._count += 1
self.val = self._count
elif not self.active:
self.val = self.input(0)


class Click_Node(Node):
title = "Click"
version = "v0.1"
main_widget_class = main_widgets.ButtonNodeWidget
init_inputs = []
init_outputs = [NodeOutputBP(type_="exec")]
color = "#99dd55"

def update_event(self, inp=-1):
self.exec_output(0)
File renamed without changes.
Loading

0 comments on commit 2ae8a53

Please sign in to comment.