diff --git a/aiidalab_widgets_base/elns.py b/aiidalab_widgets_base/elns.py index d496b5630..b68f09967 100644 --- a/aiidalab_widgets_base/elns.py +++ b/aiidalab_widgets_base/elns.py @@ -148,10 +148,39 @@ def _observe_node(self, _=None): ) info = q.all(flat=True)[0] except IndexError: - info = {} + structures, _ = self.get_all_structures_and_geoopts(self.node) + info = structures[-1].base.extras.all["eln"] self.eln.set_sample_config(**info) + def get_all_structures_and_geoopts(self, node): + """Get all atomistic models that led to the one used in the simulation""" + current_node = node + all_structures = [] + all_geoopts = [] + + while current_node is not None: + if isinstance(current_node, orm.StructureData): + all_structures.append(current_node) + current_node = current_node.creator + + elif isinstance(current_node, orm.CalcJobNode): + current_node = current_node.caller + + elif isinstance(current_node, orm.CalcFunctionNode): + current_node = current_node.inputs.source_structure + + elif isinstance(current_node, orm.WorkChainNode): + if "GeoOpt" in current_node.label: + all_geoopts.append(current_node) + current_node = current_node.inputs.structure + elif "ORBITALS" in current_node.label or "STM" in current_node.label: + current_node = current_node.inputs.structure + else: + current_node = current_node.caller + + return all_structures, all_geoopts + def send_to_eln(self, _=None): import requests_cache diff --git a/aiidalab_widgets_base/nodes.py b/aiidalab_widgets_base/nodes.py index f08b9af84..c709a581b 100644 --- a/aiidalab_widgets_base/nodes.py +++ b/aiidalab_widgets_base/nodes.py @@ -35,6 +35,13 @@ "parameter_name": "structure_uuid", "description": "Optimize atomic positions and/or unit cell employing Quantum ESPRESSO. Quantum ESPRESSO is preferable for small structures with no cell dimensions larger than 15 Å. Additionally, you can choose to compute electronic properties of the material such as band structure and density of states.", }, + { + "name": "surfaces", + "calculation_type": "geo_opt", + "notebook": "submit_geometry_optimization.ipynb", + "parameter_name": "structure_uuid", + "description": "Optimize atomic positions and/or unit cell employing CP2K. CP2K is preferable for large structures with cell dimensions larger than 15 Å.", + }, { "name": "aiidalab-lsmo", "calculation_type": "geo_opt", diff --git a/notebooks/eln_import.ipynb b/notebooks/eln_import.ipynb index e3863c868..332f4a969 100644 --- a/notebooks/eln_import.ipynb +++ b/notebooks/eln_import.ipynb @@ -42,15 +42,14 @@ "metadata": {}, "outputs": [], "source": [ + "import json\n", + "import os\n", "import urllib.parse as urlparse\n", "\n", - "from traitlets import dlink\n", + "import traitlets as tr\n", + "from pyld import jsonld\n", "\n", - "from aiidalab_widgets_base import (\n", - " AiidaNodeViewWidget,\n", - " ElnImportWidget,\n", - " OpenAiidaNodeInAppWidget,\n", - ")" + "import aiidalab_widgets_base as awb" ] }, { @@ -60,29 +59,83 @@ "metadata": {}, "outputs": [], "source": [ + "# sys.path.append(os.path.dirname(\"/home/jovyan/aiida-openbis/Notebooks/Metadata_Schemas_LinkML/\"))\n", + "# from materialMLinfo import Molecule, slots\n", + "# def extract_molecule_data_with_linkml(molecule_jsonld):\n", + "# expanded = jsonld.expand(molecule_jsonld)\n", + "# molecule_data = {}\n", + "# for obj in jsonld_object:\n", + "# if '@type' in obj and str(Molecule.class_class_uri) in obj['@type']:\n", + "# molecule_data['name'] = obj.get(str(slots.name.uri), [None])[0]['@value']\n", + "# molecule_data['smiles'] = obj.get(str(slots.smiles.uri), [None])[0]['@value']\n", + "# return molecule_data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5", + "metadata": {}, + "outputs": [], + "source": [ + "# Extract data from the converted JSON-LD\n", + "def extract_molecule_data(jsonld_object, context): # noqa: ARG001\n", + " expanded = jsonld.expand(molecule_jsonld)\n", + " compacted = jsonld.compact(expanded, context)\n", + " return {\"name\": compacted[\"name\"], \"smiles\": compacted[\"smiles\"]}\n", + "\n", + "\n", + "def read_json(filepath: str) -> dict:\n", + " return json.load(open(filepath))\n", + "\n", + "\n", "url = urlparse.urlsplit(jupyter_notebook_url) # noqa: F821\n", "parsed_url = urlparse.parse_qs(url.query)\n", "params = {key: value[0] for key, value in parsed_url.items()}\n", - "eln_widget = ElnImportWidget(**params)" + "molecule_jsonld = json.loads(params[\"molecule_info\"])\n", + "\n", + "molecule_info_valid = False\n", + "\n", + "jsonld_context_filename = os.path.join(\n", + " os.sep,\n", + " \"home\",\n", + " \"jovyan\",\n", + " \"aiida-openbis\",\n", + " \"Notebooks\",\n", + " \"Metadata_Schemas_LinkML\",\n", + " \"materialMLinfoContext.jsonld\",\n", + ")\n", + "\n", + "\n", + "aiida_context = read_json(jsonld_context_filename)\n", + "\n", + "try:\n", + " molecule_data = extract_molecule_data(molecule_jsonld, aiida_context)\n", + " params[\"molecule_info\"] = json.dumps(molecule_data)\n", + " eln_widget = awb.ElnImportWidget(path_to_root=\"../../\", **params)\n", + " molecule_info_valid = True\n", + "except ValueError as e:\n", + " print(e)" ] }, { "cell_type": "code", "execution_count": null, - "id": "5", + "id": "6", "metadata": {}, "outputs": [], "source": [ - "object_displayed = AiidaNodeViewWidget()\n", - "open_in_app = OpenAiidaNodeInAppWidget()\n", + "if molecule_info_valid:\n", + " object_displayed = awb.AiidaNodeViewWidget()\n", + " open_in_app = awb.OpenAiidaNodeInAppWidget(path_to_root=\"../../\")\n", "\n", - "_ = dlink((eln_widget, \"node\"), (object_displayed, \"node\"))\n", - "_ = dlink((eln_widget, \"node\"), (open_in_app, \"node\"))" + " _ = tr.dlink((eln_widget, \"node\"), (object_displayed, \"node\"))\n", + " _ = tr.dlink((eln_widget, \"node\"), (open_in_app, \"node\"))" ] }, { "cell_type": "markdown", - "id": "6", + "id": "7", "metadata": {}, "source": [ "## Selected object:" @@ -91,17 +144,18 @@ { "cell_type": "code", "execution_count": null, - "id": "7", + "id": "8", "metadata": {}, "outputs": [], "source": [ - "display(object_displayed)\n", - "display(eln_widget)" + "if molecule_info_valid:\n", + " display(object_displayed)\n", + " display(eln_widget)" ] }, { "cell_type": "markdown", - "id": "8", + "id": "9", "metadata": {}, "source": [ "## What's next?" @@ -110,11 +164,12 @@ { "cell_type": "code", "execution_count": null, - "id": "9", + "id": "10", "metadata": {}, "outputs": [], "source": [ - "display(open_in_app)" + "if molecule_info_valid:\n", + " display(open_in_app)" ] } ],