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
In a live discussion around #203, @JNmpi and I both agreed that we like the use of dataclasses to package together related sets of variable, e.g. for input to different functions/codes. From a technical perspective, "input injection" is tricky.
The solution we were both content with was to allow users to turn data classes into nodes with a decorator. Stealing from his phonopy work as an example, you might write something like this:
This would then produce a new node class InputPhonopyGenerateSupercells(DataNode(SingleValue)), which holds a .dataclass: type[InputPhonopyGenerateSupercellsDataclass] as a class-attribute, similar to how Function and Macro (will) have node_function and graph_creator as class attributes. InputPhonopyGenerateSupercellsDataclass is just a dynamically created class that is (nearly) @dataclasses.dataclass applied to the wrapped class above -- the difference being that we pull in some QoL improvement's from Joerg's pyiron_workflow.node_library.dev_tools.wf_data_class, like the ability to ** unpack instances of the dataclass into kwargs. This node would have an input for each field, and return and instance of the dataclass as its single value.
This allows us to take snippets like this, which are either totally broken due to the impossibility of input injection, or which suffer from incorrect connections and off-time run calls:
Where InputPhonopyGenerateSupercells is a (modified) dataclass, displacement.run() returns a float, and displacement is a single-value node (UserInput in this case)
Where InputPhonopyGenerateSupercells is a DataNode, displacement is also a node, and everything works as expected.
We could introduce some associated generic nodes like wf.create.standard.dict({"some_input_channel_name": some_value_or_SVN_or_output_channel}) that dynamically creates a node class and instantiates it, similarly for things like wf.create.standard.list, but let's do the dataclass first and see how it feels.
The text was updated successfully, but these errors were encountered:
For posterity, the example and code references are from this commit point, and are in pyiron_workflow/node_library/atomistic/property/phonons.py, notebooks/phonopy_wf.ipynb, and pyiron_workflow/node_library/dev_tools.py
In a live discussion around #203, @JNmpi and I both agreed that we like the use of dataclasses to package together related sets of variable, e.g. for input to different functions/codes. From a technical perspective, "input injection" is tricky.
The solution we were both content with was to allow users to turn data classes into nodes with a decorator. Stealing from his phonopy work as an example, you might write something like this:
This would then produce a new node class
InputPhonopyGenerateSupercells(DataNode(SingleValue))
, which holds a.dataclass: type[InputPhonopyGenerateSupercellsDataclass]
as a class-attribute, similar to howFunction
andMacro
(will) havenode_function
andgraph_creator
as class attributes.InputPhonopyGenerateSupercellsDataclass
is just a dynamically created class that is (nearly)@dataclasses.dataclass
applied to the wrapped class above -- the difference being that we pull in some QoL improvement's from Joerg'spyiron_workflow.node_library.dev_tools.wf_data_class
, like the ability to**
unpack instances of the dataclass intokwargs
. This node would have an input for each field, and return and instance of the dataclass as its single value.This allows us to take snippets like this, which are either totally broken due to the impossibility of input injection, or which suffer from incorrect connections and off-time
run
calls:Where
InputPhonopyGenerateSupercells
is a (modified) dataclass,displacement.run()
returns a float, anddisplacement
is a single-value node (UserInput
in this case)Into functioning, connected graph code like this:
Where
InputPhonopyGenerateSupercells
is aDataNode
,displacement
is also a node, and everything works as expected.We could introduce some associated generic nodes like
wf.create.standard.dict({"some_input_channel_name": some_value_or_SVN_or_output_channel})
that dynamically creates a node class and instantiates it, similarly for things likewf.create.standard.list
, but let's do the dataclass first and see how it feels.The text was updated successfully, but these errors were encountered: