diff --git a/environment.yml b/environment.yml index 7f83e11..314af7b 100644 --- a/environment.yml +++ b/environment.yml @@ -8,4 +8,5 @@ dependencies: - ase=3.24.0 - matplotlib=3.10.1 - xmlschema=3.4.3 -- jobflow=0.1.19 \ No newline at end of file +- jobflow=0.1.19 +- pygraphviz=1.14 \ No newline at end of file diff --git a/python_workflow_definition/src/python_workflow_definition/pyiron_base.py b/python_workflow_definition/src/python_workflow_definition/pyiron_base.py index 6bc5d40..299f265 100644 --- a/python_workflow_definition/src/python_workflow_definition/pyiron_base.py +++ b/python_workflow_definition/src/python_workflow_definition/pyiron_base.py @@ -1,3 +1,6 @@ +import json +from importlib import import_module + from pyiron_base import job from pyiron_base.project.delayed import DelayedObject @@ -107,7 +110,7 @@ def get_unique_objects(nodes_dict, edges_lst): # I need a pre-filter before thi delayed_object_dict[k] = v elif isinstance(v, list) and any([isinstance(el, DelayedObject) for el in v]): # currently this replaces any list - what I need instead is some kind of virtual node - mixed nodes delayed_object_dict[k] = DelayedObject(function=get_list) - delayed_object_dict[k]._input = {i: el for el in enumerate(v)} + delayed_object_dict[k]._input = {i: el for i, el in enumerate(v)} delayed_object_dict[k]._python_function = get_list elif isinstance(v, dict) and any([isinstance(el, DelayedObject) for el in v.values()]): delayed_object_dict[k] = DelayedObject(function=get_dict, **v,) @@ -187,3 +190,27 @@ def get_edges_dict(edges_lst, nodes_dict, connection_dict, lookup_dict): return edges_dict_lst +def load_workflow_json(project, file_name): + with open(file_name, "r") as f: + content = json.load(f) + + edges_new_lst = content["edges"] + nodes_new_dict = {} + for k, v in content["nodes"].items(): + if isinstance(v, str) and "." in v: + p, m = v.rsplit('.', 1) + mod = import_module(p) + nodes_new_dict[int(k)] = getattr(mod, m) + else: + nodes_new_dict[int(k)] = v + + total_lst = group_edges(edges_new_lst) + total_new_lst = resort_total_lst(total_lst=total_lst, nodes_dict=nodes_new_dict) + source_handle_dict = get_source_handles(edges_new_lst) + delayed_object_dict = get_delayed_object_dict( + total_lst=total_new_lst, + nodes_dict=nodes_new_dict, + source_handle_dict=source_handle_dict, + pyiron_project=project, + ) + return delayed_object_dict[list(delayed_object_dict.keys())[-1]] diff --git a/universal_qe_to_pyiron_base.ipynb b/universal_qe_to_pyiron_base.ipynb index f5f027d..71819fe 100644 --- a/universal_qe_to_pyiron_base.ipynb +++ b/universal_qe_to_pyiron_base.ipynb @@ -17,130 +17,7 @@ "metadata": {}, "outputs": [], "source": [ - "from python_workflow_definition.pyiron_base import (get_dict, get_list, group_edges, resort_total_lst, get_source_handles, get_delayed_object_dict)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d694b477-d4f7-45a9-97a1-3a4b5a8ca4fb", - "metadata": {}, - "outputs": [], - "source": [ - "from quantum_espresso_workflow import calculate_qe, generate_structures, get_bulk_structure, plot_energy_volume_curve" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c9d48f4f-5593-43ad-9b98-e69bc74d36cc", - "metadata": {}, - "outputs": [], - "source": [ - "nodes_new_dict = { # from jobflow\n", - " 0: get_bulk_structure,\n", - " 1: calculate_qe,\n", - " 2: generate_structures,\n", - " 3: calculate_qe,\n", - " 4: calculate_qe,\n", - " 5: calculate_qe,\n", - " 6: calculate_qe,\n", - " 7: calculate_qe,\n", - " 8: plot_energy_volume_curve,\n", - " 9: 'Al',\n", - " 10: 4.05,\n", - " 11: True,\n", - " 12: 'mini',\n", - " 13: get_dict,\n", - " 14: {'Al': 'Al.pbe-n-kjpaw_psl.1.0.0.UPF'},\n", - " 15: [3, 3, 3],\n", - " 16: 'vc-relax',\n", - " 17: 0.02,\n", - " 18: [0.9, 0.95, 1.0, 1.05, 1.1],\n", - " 19: 'strain_0',\n", - " 20: get_dict,\n", - " 21: 'scf',\n", - " 22: 'strain_1',\n", - " 23: get_dict,\n", - " 24: 'strain_2',\n", - " 25: get_dict,\n", - " 26: 'strain_3',\n", - " 27: get_dict,\n", - " 28: 'strain_4',\n", - " 29: get_dict,\n", - " 30: get_list,\n", - " 31: get_list,\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "31a2fec8-4d83-41c3-8dc3-5964e0a07732", - "metadata": {}, - "outputs": [], - "source": [ - "edges_new_lst = [\n", - " {'target': 0, 'targetHandle': 'name', 'source': 9, 'sourceHandle': None},\n", - " {'target': 0, 'targetHandle': 'a', 'source': 10, 'sourceHandle': None},\n", - " {'target': 0, 'targetHandle': 'cubic', 'source': 11, 'sourceHandle': None},\n", - " {'target': 1, 'targetHandle': 'working_directory', 'source': 12, 'sourceHandle': None},\n", - " {'target': 13, 'targetHandle': 'structure', 'source': 0, 'sourceHandle': None},\n", - " {'target': 13, 'targetHandle': 'pseudopotentials', 'source': 14, 'sourceHandle': None},\n", - " {'target': 13, 'targetHandle': 'kpts', 'source': 15, 'sourceHandle': None},\n", - " {'target': 13, 'targetHandle': 'calculation', 'source': 16, 'sourceHandle': None},\n", - " {'target': 13, 'targetHandle': 'smearing', 'source': 17, 'sourceHandle': None},\n", - " {'target': 1, 'targetHandle': 'input_dict', 'source': 13, 'sourceHandle': None},\n", - " {'target': 2, 'targetHandle': 'structure', 'source': 1, 'sourceHandle': 'structure'},\n", - " {'target': 2, 'targetHandle': 'strain_lst', 'source': 18, 'sourceHandle': None},\n", - " {'target': 3, 'targetHandle': 'working_directory', 'source': 19, 'sourceHandle': None},\n", - " {'target': 20, 'targetHandle': 'structure', 'source': 2, 'sourceHandle': '0'},\n", - " {'target': 20, 'targetHandle': 'pseudopotentials', 'source': 14, 'sourceHandle': None},\n", - " {'target': 20, 'targetHandle': 'kpts', 'source': 15, 'sourceHandle': None},\n", - " {'target': 20, 'targetHandle': 'calculation', 'source': 21, 'sourceHandle': None},\n", - " {'target': 20, 'targetHandle': 'smearing', 'source': 17, 'sourceHandle': None},\n", - " {'target': 3, 'targetHandle': 'input_dict', 'source': 20, 'sourceHandle': None},\n", - " {'target': 4, 'targetHandle': 'working_directory', 'source': 22, 'sourceHandle': None},\n", - " {'target': 23, 'targetHandle': 'structure', 'source': 2, 'sourceHandle': '1'},\n", - " {'target': 23, 'targetHandle': 'pseudopotentials', 'source': 14, 'sourceHandle': None},\n", - " {'target': 23, 'targetHandle': 'kpts', 'source': 15, 'sourceHandle': None},\n", - " {'target': 23, 'targetHandle': 'calculation', 'source': 21, 'sourceHandle': None},\n", - " {'target': 23, 'targetHandle': 'smearing', 'source': 17, 'sourceHandle': None},\n", - " {'target': 4, 'targetHandle': 'input_dict', 'source': 23, 'sourceHandle': None},\n", - " {'target': 5, 'targetHandle': 'working_directory', 'source': 24, 'sourceHandle': None},\n", - " {'target': 25, 'targetHandle': 'structure', 'source': 2, 'sourceHandle': '2'},\n", - " {'target': 25, 'targetHandle': 'pseudopotentials', 'source': 14, 'sourceHandle': None},\n", - " {'target': 25, 'targetHandle': 'kpts', 'source': 15, 'sourceHandle': None},\n", - " {'target': 25, 'targetHandle': 'calculation', 'source': 21, 'sourceHandle': None},\n", - " {'target': 25, 'targetHandle': 'smearing', 'source': 17, 'sourceHandle': None},\n", - " {'target': 5, 'targetHandle': 'input_dict', 'source': 25, 'sourceHandle': None},\n", - " {'target': 6, 'targetHandle': 'working_directory', 'source': 26, 'sourceHandle': None},\n", - " {'target': 27, 'targetHandle': 'structure', 'source': 2, 'sourceHandle': '3'},\n", - " {'target': 27, 'targetHandle': 'pseudopotentials', 'source': 14, 'sourceHandle': None},\n", - " {'target': 27, 'targetHandle': 'kpts', 'source': 15, 'sourceHandle': None},\n", - " {'target': 27, 'targetHandle': 'calculation', 'source': 21, 'sourceHandle': None},\n", - " {'target': 27, 'targetHandle': 'smearing', 'source': 17, 'sourceHandle': None},\n", - " {'target': 6, 'targetHandle': 'input_dict', 'source': 27, 'sourceHandle': None},\n", - " {'target': 7, 'targetHandle': 'working_directory', 'source': 28, 'sourceHandle': None},\n", - " {'target': 29, 'targetHandle': 'structure', 'source': 2, 'sourceHandle': '4'},\n", - " {'target': 29, 'targetHandle': 'pseudopotentials', 'source': 14, 'sourceHandle': None},\n", - " {'target': 29, 'targetHandle': 'kpts', 'source': 15, 'sourceHandle': None},\n", - " {'target': 29, 'targetHandle': 'calculation', 'source': 21, 'sourceHandle': None},\n", - " {'target': 29, 'targetHandle': 'smearing', 'source': 17, 'sourceHandle': None},\n", - " {'target': 7, 'targetHandle': 'input_dict', 'source': 29, 'sourceHandle': None},\n", - " {'target': 30, 'targetHandle': \"0\", 'source': 3, 'sourceHandle': 'volume'},\n", - " {'target': 30, 'targetHandle': \"1\", 'source': 4, 'sourceHandle': 'volume'},\n", - " {'target': 30, 'targetHandle': \"2\", 'source': 5, 'sourceHandle': 'volume'},\n", - " {'target': 30, 'targetHandle': \"3\", 'source': 6, 'sourceHandle': 'volume'},\n", - " {'target': 30, 'targetHandle': \"4\", 'source': 7, 'sourceHandle': 'volume'},\n", - " {'target': 8, 'targetHandle': 'volume_lst', 'source': 30, 'sourceHandle': None},\n", - " {'target': 31, 'targetHandle': \"0\", 'source': 3, 'sourceHandle': 'energy'},\n", - " {'target': 31, 'targetHandle': \"1\", 'source': 4, 'sourceHandle': 'energy'},\n", - " {'target': 31, 'targetHandle': \"2\", 'source': 5, 'sourceHandle': 'energy'},\n", - " {'target': 31, 'targetHandle': \"3\", 'source': 6, 'sourceHandle': 'energy'},\n", - " {'target': 31, 'targetHandle': \"4\", 'source': 7, 'sourceHandle': 'energy'},\n", - " {'target': 8, 'targetHandle': 'energy_lst', 'source': 31, 'sourceHandle': None},\n", - "]" + "from python_workflow_definition.pyiron_base import load_workflow_json" ] }, { @@ -157,30 +34,22 @@ { "cell_type": "code", "execution_count": null, - "id": "063b5e00-5afd-4388-889b-bf6c2f0a7957", + "id": "0c393ada-0eb9-4627-9f3a-25afdd30545e", "metadata": {}, "outputs": [], "source": [ - "total_lst = group_edges(edges_new_lst)\n", - "total_new_lst = resort_total_lst(total_lst=total_lst, nodes_dict=nodes_new_dict)\n", - "source_handle_dict = get_source_handles(edges_new_lst)\n", - "delayed_object_dict = get_delayed_object_dict(\n", - " total_lst=total_new_lst, \n", - " nodes_dict=nodes_new_dict, \n", - " source_handle_dict=source_handle_dict, \n", - " pyiron_project=pr\n", - ")\n", - "delayed_object_dict[list(delayed_object_dict.keys())[-1]].draw()" + "delayed_object = load_workflow_json(project=pr, file_name=\"workflow.json\")\n", + "delayed_object.draw()" ] }, { "cell_type": "code", "execution_count": null, - "id": "e2e2c44d-cb2e-4111-907e-c88ad671273b", + "id": "006f309a-d82c-457d-a77a-8771a72dc6d3", "metadata": {}, "outputs": [], "source": [ - "delayed_object_dict[list(delayed_object_dict.keys())[-1]].pull()" + "delayed_object.pull()" ] }, { diff --git a/workflow.json b/workflow.json new file mode 100644 index 0000000..347b93c --- /dev/null +++ b/workflow.json @@ -0,0 +1 @@ +{"nodes": {"0": "quantum_espresso_workflow.get_bulk_structure", "1": "quantum_espresso_workflow.calculate_qe", "2": "quantum_espresso_workflow.generate_structures", "3": "quantum_espresso_workflow.calculate_qe", "4": "quantum_espresso_workflow.calculate_qe", "5": "quantum_espresso_workflow.calculate_qe", "6": "quantum_espresso_workflow.calculate_qe", "7": "quantum_espresso_workflow.calculate_qe", "8": "quantum_espresso_workflow.plot_energy_volume_curve", "9": "Al", "10": 4.05, "11": true, "12": "mini", "13": "python_workflow_definition.pyiron_base.get_dict", "14": {"Al": "Al.pbe-n-kjpaw_psl.1.0.0.UPF"}, "15": [3, 3, 3], "16": "vc-relax", "17": 0.02, "18": [0.9, 0.95, 1.0, 1.05, 1.1], "19": "strain_0", "20": "python_workflow_definition.pyiron_base.get_dict", "21": "scf", "22": "strain_1", "23": "python_workflow_definition.pyiron_base.get_dict", "24": "strain_2", "25": "python_workflow_definition.pyiron_base.get_dict", "26": "strain_3", "27": "python_workflow_definition.pyiron_base.get_dict", "28": "strain_4", "29": "python_workflow_definition.pyiron_base.get_dict", "30": "python_workflow_definition.pyiron_base.get_list", "31": "python_workflow_definition.pyiron_base.get_list"}, "edges": [{"target": 0, "targetHandle": "name", "source": 9, "sourceHandle": null}, {"target": 0, "targetHandle": "a", "source": 10, "sourceHandle": null}, {"target": 0, "targetHandle": "cubic", "source": 11, "sourceHandle": null}, {"target": 1, "targetHandle": "working_directory", "source": 12, "sourceHandle": null}, {"target": 13, "targetHandle": "structure", "source": 0, "sourceHandle": null}, {"target": 13, "targetHandle": "pseudopotentials", "source": 14, "sourceHandle": null}, {"target": 13, "targetHandle": "kpts", "source": 15, "sourceHandle": null}, {"target": 13, "targetHandle": "calculation", "source": 16, "sourceHandle": null}, {"target": 13, "targetHandle": "smearing", "source": 17, "sourceHandle": null}, {"target": 1, "targetHandle": "input_dict", "source": 13, "sourceHandle": null}, {"target": 2, "targetHandle": "structure", "source": 1, "sourceHandle": "structure"}, {"target": 2, "targetHandle": "strain_lst", "source": 18, "sourceHandle": null}, {"target": 3, "targetHandle": "working_directory", "source": 19, "sourceHandle": null}, {"target": 20, "targetHandle": "structure", "source": 2, "sourceHandle": "0"}, {"target": 20, "targetHandle": "pseudopotentials", "source": 14, "sourceHandle": null}, {"target": 20, "targetHandle": "kpts", "source": 15, "sourceHandle": null}, {"target": 20, "targetHandle": "calculation", "source": 21, "sourceHandle": null}, {"target": 20, "targetHandle": "smearing", "source": 17, "sourceHandle": null}, {"target": 3, "targetHandle": "input_dict", "source": 20, "sourceHandle": null}, {"target": 4, "targetHandle": "working_directory", "source": 22, "sourceHandle": null}, {"target": 23, "targetHandle": "structure", "source": 2, "sourceHandle": "1"}, {"target": 23, "targetHandle": "pseudopotentials", "source": 14, "sourceHandle": null}, {"target": 23, "targetHandle": "kpts", "source": 15, "sourceHandle": null}, {"target": 23, "targetHandle": "calculation", "source": 21, "sourceHandle": null}, {"target": 23, "targetHandle": "smearing", "source": 17, "sourceHandle": null}, {"target": 4, "targetHandle": "input_dict", "source": 23, "sourceHandle": null}, {"target": 5, "targetHandle": "working_directory", "source": 24, "sourceHandle": null}, {"target": 25, "targetHandle": "structure", "source": 2, "sourceHandle": "2"}, {"target": 25, "targetHandle": "pseudopotentials", "source": 14, "sourceHandle": null}, {"target": 25, "targetHandle": "kpts", "source": 15, "sourceHandle": null}, {"target": 25, "targetHandle": "calculation", "source": 21, "sourceHandle": null}, {"target": 25, "targetHandle": "smearing", "source": 17, "sourceHandle": null}, {"target": 5, "targetHandle": "input_dict", "source": 25, "sourceHandle": null}, {"target": 6, "targetHandle": "working_directory", "source": 26, "sourceHandle": null}, {"target": 27, "targetHandle": "structure", "source": 2, "sourceHandle": "3"}, {"target": 27, "targetHandle": "pseudopotentials", "source": 14, "sourceHandle": null}, {"target": 27, "targetHandle": "kpts", "source": 15, "sourceHandle": null}, {"target": 27, "targetHandle": "calculation", "source": 21, "sourceHandle": null}, {"target": 27, "targetHandle": "smearing", "source": 17, "sourceHandle": null}, {"target": 6, "targetHandle": "input_dict", "source": 27, "sourceHandle": null}, {"target": 7, "targetHandle": "working_directory", "source": 28, "sourceHandle": null}, {"target": 29, "targetHandle": "structure", "source": 2, "sourceHandle": "4"}, {"target": 29, "targetHandle": "pseudopotentials", "source": 14, "sourceHandle": null}, {"target": 29, "targetHandle": "kpts", "source": 15, "sourceHandle": null}, {"target": 29, "targetHandle": "calculation", "source": 21, "sourceHandle": null}, {"target": 29, "targetHandle": "smearing", "source": 17, "sourceHandle": null}, {"target": 7, "targetHandle": "input_dict", "source": 29, "sourceHandle": null}, {"target": 30, "targetHandle": "0", "source": 3, "sourceHandle": "volume"}, {"target": 30, "targetHandle": "1", "source": 4, "sourceHandle": "volume"}, {"target": 30, "targetHandle": "2", "source": 5, "sourceHandle": "volume"}, {"target": 30, "targetHandle": "3", "source": 6, "sourceHandle": "volume"}, {"target": 30, "targetHandle": "4", "source": 7, "sourceHandle": "volume"}, {"target": 8, "targetHandle": "volume_lst", "source": 30, "sourceHandle": null}, {"target": 31, "targetHandle": "0", "source": 3, "sourceHandle": "energy"}, {"target": 31, "targetHandle": "1", "source": 4, "sourceHandle": "energy"}, {"target": 31, "targetHandle": "2", "source": 5, "sourceHandle": "energy"}, {"target": 31, "targetHandle": "3", "source": 6, "sourceHandle": "energy"}, {"target": 31, "targetHandle": "4", "source": 7, "sourceHandle": "energy"}, {"target": 8, "targetHandle": "energy_lst", "source": 31, "sourceHandle": null}]} \ No newline at end of file