Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New decorator: data_node #208

Closed
liamhuber opened this issue Feb 16, 2024 · 2 comments
Closed

New decorator: data_node #208

liamhuber opened this issue Feb 16, 2024 · 2 comments
Labels
enhancement New feature or request

Comments

@liamhuber
Copy link
Member

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:

@Workflow.wrap_as.data_node()
class InputPhonopyGenerateSupercells:
    distance: float = 0.01
    is_plusminus: Union[str, bool] = "auto"
    is_diagonal: bool = True
    is_trigonal: bool = False
    number_of_snapshots: Optional[int] = None
    random_seed: Optional[int] = None
    temperature: Optional[float] = None
    cutoff_frequency: Optional[float] = None
    max_distance: Optional[float] = None

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:

@Workflow.wrap_as.macro_node(...)
def run_phonopy(wf, ..., displacement: float = 0.01):
    ...
    wf.phonopy = wf.create.atomistic.property.phonons.create_phonopy(
        ...
        parameters=InputPhonopyGenerateSupercells(distance=displacement.run()),
        ...
    )

Where InputPhonopyGenerateSupercells is a (modified) dataclass, displacement.run() returns a float, and displacement is a single-value node (UserInput in this case)

Into functioning, connected graph code like this:

@Workflow.wrap_as.macro_node(...)
def run_phonopy(wf, ..., displacement: float = 0.01):
    ...
    wf.phonopy = wf.create.atomistic.property.phonons.create_phonopy(
        ...
        parameters=wf.create.atomistic.property.phonons.InputPhonopyGenerateSupercells(distance=displacement),
        ...
    )

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.

@liamhuber liamhuber added the enhancement New feature or request label Feb 16, 2024
@liamhuber
Copy link
Member Author

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

@liamhuber
Copy link
Member Author

Done in #308

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant