Skip to content

Commit

Permalink
Define structure results panel based on relaxation property
Browse files Browse the repository at this point in the history
  • Loading branch information
edan-bainglass committed Dec 22, 2024
1 parent 4411ab9 commit c28bbb9
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from .model import StructureResultsModel
from .structure import StructureResults
from .structure import StructureResultsPanel

__all__ = [
"StructureResultsModel",
"StructureResults",
"StructureResultsPanel",
]
18 changes: 15 additions & 3 deletions src/aiidalab_qe/app/result/components/viewer/structure/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ class StructureResultsModel(ResultsModel):

_this_process_label = "PwRelaxWorkChain"

@property
def include(self):
return "relax" in self.properties
source = None

def update(self):
super().update()
is_relaxed = "relax" in self.properties
self.title = "Relaxed structure" if is_relaxed else "Initial structure"
self.source = self.outputs if is_relaxed else self.inputs
self.auto_render = not is_relaxed # auto-render initial structure

def get_structure(self):
try:
return self.source.structure if self.source else None
except AttributeError:
# If source is outputs but job failed, there may not be a structure
return None
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
from .model import StructureResultsModel


class StructureResults(ResultsPanel[StructureResultsModel]):
class StructureResultsPanel(ResultsPanel[StructureResultsModel]):
def _render(self):
if not hasattr(self, "widget"):
self.widget = StructureDataViewer(structure=self._model.outputs.structure)
structure = self._model.get_structure()
self.widget = StructureDataViewer(structure=structure)
self.children = [self.widget]

# HACK to resize the NGL viewer in cases where it auto-rendered when its
Expand Down
12 changes: 5 additions & 7 deletions src/aiidalab_qe/app/result/components/viewer/viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
from aiidalab_qe.common.panel import ResultsPanel

from .model import WorkChainResultsViewerModel
from .structure import StructureResults, StructureResultsModel
from .structure import StructureResultsModel, StructureResultsPanel


class WorkChainResultsViewer(ResultsComponent[WorkChainResultsViewerModel]):
def __init__(self, model: WorkChainResultsViewerModel, **kwargs):
super().__init__(model=model, **kwargs)
self.panels: dict[str, ResultsPanel] = {}
self._add_structure_panel() # TODO consider refactoring structure panel as a plugin
self._fetch_plugin_results()

def _on_process_change(self, _):
Expand Down Expand Up @@ -42,10 +43,6 @@ def _render(self):
"selected_index",
)

# TODO consider refactoring structure relaxation panel as a plugin
if "relax" in self._model.properties:
self._add_structure_panel()

self.children = [
self.title,
self.tabs,
Expand All @@ -60,7 +57,8 @@ def _update_panels(self):
self.panels = {
identifier: panel
for identifier, panel in self.panels.items()
if identifier in properties
if identifier == "structure"
or identifier in properties
or (identifier == "electronic_structure" and need_electronic_structure)
}

Expand All @@ -82,7 +80,7 @@ def _set_tabs(self):
def _add_structure_panel(self):
structure_model = StructureResultsModel()
structure_model.process_uuid = self._model.process_uuid
self.structure_results = StructureResults(model=structure_model)
self.structure_results = StructureResultsPanel(model=structure_model)
identifier = structure_model.identifier
self._model.add_model(identifier, structure_model)
self.panels = {
Expand Down
14 changes: 10 additions & 4 deletions src/aiidalab_qe/common/panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,8 @@ class ResultsModel(PanelModel, HasProcess):
_this_process_label = ""
_this_process_uuid = None

auto_render = False

CSS_MAP = {
"finished": "success",
"failed": "danger",
Expand All @@ -522,6 +524,10 @@ def has_results(self):
node = self._fetch_child_process_node()
return node and node.is_finished_ok

def update(self):
if self.has_results:
self.auto_render = True

def update_process_status_notification(self):
self.process_status_notification = self._get_child_process_status()

Expand Down Expand Up @@ -616,13 +622,13 @@ def render(self):
return
if self.has_controls or not self._model.has_process:
return
if not self._model.has_results:
self._render_controls()
else:
if self._model.auto_render:
self._load_results()
else:
self._render_controls()

def _on_process_change(self, _):
pass
self._model.update()

def _on_monitor_counter_change(self, _):
self._model.update_process_status_notification()
Expand Down
2 changes: 1 addition & 1 deletion tests/test_plugins_electronic_structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def test_electronic_structure(generate_qeapp_workchain):
model = ElectronicStructureResultsModel()
model.process_uuid = workchain.node.uuid
result = ElectronicStructureResultsPanel(model=model)
result.render()
result._render()

widget = result.children[0]
model = widget._model
Expand Down
22 changes: 21 additions & 1 deletion tests/test_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
WorkChainResultsViewer,
WorkChainResultsViewerModel,
)
from aiidalab_qe.app.result.components.viewer.structure import StructureResultsModel
from aiidalab_qe.app.result.components.viewer.structure.structure import (
StructureResultsPanel,
)


def test_result_step(app_to_submit, generate_qeapp_workchain):
Expand Down Expand Up @@ -37,7 +41,7 @@ def test_workchainview(generate_qeapp_workchain):
model.process_uuid = workchain.node.uuid
viewer.render()
assert len(viewer.tabs.children) == 4
assert viewer.tabs._titles["0"] == "Final Geometry" # type: ignore
assert viewer.tabs._titles["0"] == "Relaxed structure" # type: ignore


def test_summary_report(data_regression, generate_qeapp_workchain):
Expand Down Expand Up @@ -76,3 +80,19 @@ def test_summary_view(generate_qeapp_workchain):
for key, value in parameters.items():
td = parsed.find("td", text=key).find_next_sibling("td")
assert td.text == value


def test_structure_results_panel(generate_qeapp_workchain):
"""Test the structure results panel can be properly generated."""
model = StructureResultsModel()
_ = StructureResultsPanel(model=model)

wc = generate_qeapp_workchain(relax_type="none")
model.process_uuid = wc.node.uuid
assert model.title == "Initial structure"
assert "properties" in model.source # source should be inputs

wc = generate_qeapp_workchain(relax_type="positions_cell")
model.process_uuid = wc.node.uuid
assert model.title == "Relaxed structure"
assert "properties" not in model.source # source should be outputs

0 comments on commit c28bbb9

Please sign in to comment.