Skip to content

Commit

Permalink
Merge branch 'main' into release_blog_202404
Browse files Browse the repository at this point in the history
  • Loading branch information
superstar54 authored Apr 24, 2024
2 parents 411af3e + ae79e3e commit fec1601
Show file tree
Hide file tree
Showing 6 changed files with 392 additions and 1 deletion.
135 changes: 135 additions & 0 deletions delete.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# AiiDAlab QuantumESPRESSO App\n",
"\n",
"<font color=\"red\"><b>Caution!</b></font> Deleting this job will also remove <b>all associated nodes</b>, including every calculation initiated by this job and their respective results. This action is <b>irreversible</b>.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import urllib.parse as urlparse\n",
"\n",
"import ipywidgets as widgets\n",
"from aiida import load_profile\n",
"from aiida.orm import load_node\n",
"from aiida.tools import delete_nodes\n",
"from IPython.display import Markdown, display\n",
"\n",
"# Load AiiDA profile\n",
"load_profile()\n",
"\n",
"# Parse the primary key from the Jupyter notebook URL\n",
"url = urlparse.urlsplit(jupyter_notebook_url) # noqa F821\n",
"query = urlparse.parse_qs(url.query)\n",
"pk = int(query['pk'][0])\n",
"\n",
"\n",
"def display_node_details(pk):\n",
" try:\n",
" node = load_node(pk)\n",
" print(f\"Node ID: {node.pk}\")\n",
" print(f\"Node Type: {node.process_label}\")\n",
" print(f\"Label: {node.label}\")\n",
" print(f\"Description: {node.description}\")\n",
" print(f\"Creation Time: {node.ctime}\")\n",
" except Exception as e:\n",
" print(f\"Error loading node: {str(e)}\")\n",
" return False\n",
" return True\n",
"\n",
"\n",
"def delete_node(pk, dry_run=True):\n",
" if dry_run:\n",
" _, was_deleted = delete_nodes([pk], dry_run=True)\n",
" if was_deleted:\n",
" print(f'Dry run: Node {pk} can be deleted.')\n",
" return\n",
" \n",
" _, was_deleted = delete_nodes([pk], dry_run=False)\n",
" if was_deleted:\n",
" print(f'Node {pk} deleted successfully.')\n",
"\n",
"\n",
"def confirm_deletion(b):\n",
" if delete_confirmation.value.lower() in ['y', 'yes']:\n",
" delete_node(pk, dry_run=False)\n",
" else:\n",
" print('Deletion aborted.')\n",
"\n",
"\n",
"def find_linked_qeapp_jobs(root_node_pk, process_label='QeAppWorkChain'):\n",
" \"\"\"Query all linked node with process_label = QeAppWorkChain.\"\"\"\n",
" from aiida.orm import Node, QueryBuilder\n",
" from aiida.orm.nodes.process.workflow.workchain import WorkChainNode\n",
" qb = QueryBuilder()\n",
" qb.append(WorkChainNode, filters={'id': root_node_pk}, tag='root')\n",
" qb.append(Node, with_incoming='root', tag='calcjob')\n",
" # There are seems a bug with `with_ancestors` in the QueryBuilder, so we have to use `with_incoming` instead.\n",
" # For the moment, it's safe to use `with_incoming` since we check it very time we delete a QEApp \n",
" qb.append(WorkChainNode, filters={'attributes.process_label': 'QeAppWorkChain'}, with_incoming='calcjob')\n",
" results = qb.all()\n",
" if len(results) == 0:\n",
" return None\n",
" return results\n",
"\n",
"\n",
"if display_node_details(pk):\n",
" linked_qeapp_jobs = find_linked_qeapp_jobs(pk)\n",
" if linked_qeapp_jobs:\n",
" warning_html = f\"\"\"\n",
"<div style='margin: 10px; padding: 10px; border: 1px solid red; border-radius: 5px; background-color: #ffcccc;'>\n",
" <strong style='color: red;'>Critical:</strong> Unable to delete the requested node due to dependencies.\n",
" There are <strong>{len(linked_qeapp_jobs)}</strong> QEApp jobs linked to this node. Please delete them first:\n",
" <ul>\n",
"\"\"\"\n",
" for node in linked_qeapp_jobs[0]:\n",
" warning_html += f\"\"\"<a href=\"./delete.ipynb?pk={node.pk}\" target=\"_blank\">{node.pk}</a><br>\"\"\"\n",
" display(widgets.HTML(value=warning_html))\n",
" else:\n",
" # Ask for confirmation\n",
" nodes, _ = delete_nodes([pk], dry_run=True)\n",
" display(Markdown(f'**YOU ARE ABOUT TO DELETE `{len(nodes)}` NODES! THIS CANNOT BE UNDONE!**'))\n",
" delete_confirmation = widgets.Text(\n",
" value='',\n",
" placeholder='Type \"yes\" to confirm',\n",
" description='Confirm:',\n",
" disabled=False\n",
" )\n",
" confirm_button = widgets.Button(description=\"Delete Node\")\n",
" confirm_button.on_click(confirm_deletion)\n",
" display(delete_confirmation, confirm_button)\n",
"else:\n",
" print(\"No valid node found for deletion.\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.13"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
65 changes: 65 additions & 0 deletions job_list.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# AiiDAlab QuantumESPRESSO App"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%capture\n",
"from aiida import load_profile\n",
"\n",
"load_profile()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from aiidalab_qe.app.utils.search_jobs import QueryInterface\n",
"\n",
"qi = QueryInterface()\n",
"qi.filters_layout"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"qi.table"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.13"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
10 changes: 10 additions & 0 deletions qe.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
"except Exception:\n",
" pass\n",
"\n",
"import urllib.parse as urlparse\n",
"\n",
"import ipywidgets as ipw\n",
"from aiidalab_widgets_base.bug_report import (\n",
" install_create_github_issue_exception_handler,\n",
Expand Down Expand Up @@ -65,7 +67,15 @@
" f'<p style=\"text-align:right;\">Copyright (c) 2023 AiiDAlab team (EPFL)&#8195Version: {__version__}</p>'\n",
")\n",
"\n",
"url = urlparse.urlsplit(jupyter_notebook_url) # noqa F821\n",
"query = urlparse.parse_qs(url.query)\n",
"\n",
"\n",
"app_with_work_chain_selector = App(qe_auto_setup=True)\n",
"# if a pk is provided in the query string, set it as the value of the work_chain_selector\n",
"if 'pk' in query:\n",
" pk = int(query['pk'][0])\n",
" app_with_work_chain_selector.work_chain_selector.value = pk\n",
"\n",
"output = ipw.Output()\n",
"install_create_github_issue_exception_handler(\n",
Expand Down
1 change: 1 addition & 0 deletions src/aiidalab_qe/app/submission/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ def submit(self, _=None):
process.base.extras.set("ui_parameters", serialize(self.ui_parameters))
# store the workchain name in extras, this will help to filter the workchain in the future
process.base.extras.set("workchain", self.ui_parameters["workchain"])
process.base.extras.set("structure", self.input_structure.get_formula())
self.process = process

self._update_state()
Expand Down
Loading

0 comments on commit fec1601

Please sign in to comment.