diff --git a/src/aiidalab_qe_vibroscopy/app/settings.py b/src/aiidalab_qe_vibroscopy/app/settings.py
index b400fe7..be88215 100644
--- a/src/aiidalab_qe_vibroscopy/app/settings.py
+++ b/src/aiidalab_qe_vibroscopy/app/settings.py
@@ -14,14 +14,49 @@
from aiidalab_qe.common.panel import Panel
from IPython.display import clear_output, display
+
import sys
import os
+
+from aiida.plugins import CalculationFactory, DataFactory, WorkflowFactory
+
+HubbardStructureData = DataFactory("quantumespresso.hubbard_structure")
+
+# spinner for waiting time (supercell estimations)
+spinner_html = """
+
+
+"""
+
+
def disable_print(func):
def wrapper(*args, **kwargs):
# Save the current standard output
original_stdout = sys.stdout
# Redirect standard output to os.devnull
- sys.stdout = open(os.devnull, 'w')
+ sys.stdout = open(os.devnull, "w")
try:
# Call the function
result = func(*args, **kwargs)
@@ -30,6 +65,7 @@ def wrapper(*args, **kwargs):
sys.stdout.close()
sys.stdout = original_stdout
return result
+
return wrapper
@@ -149,7 +185,7 @@ def change_supercell(_=None):
)
# supercell hint (15A lattice params)
self.supercell_hint_button.on_click(self._suggest_supercell)
-
+
# reset supercell
self.supercell_reset_button = ipw.Button(
description="Reset",
@@ -159,13 +195,13 @@ def change_supercell(_=None):
)
# supercell reset reaction
self.supercell_reset_button.on_click(self._reset_supercell)
-
+
# Estimate the number of supercells for frozen phonons.
self.supercell_number_estimator = ipw.HTML(
- description="Number of supercells to be computed:",
- value = "0",
- style={"description_width": "initial"},
- )
+ description="Number of supercells to be computed:",
+ value="0",
+ style={"description_width": "initial"},
+ )
## end supercell hint.
@@ -174,11 +210,11 @@ def change_supercell(_=None):
self.hint_button_help,
ipw.HBox(
[
- self.supercell_selector,
- self.supercell_hint_button,
+ self.supercell_selector,
+ self.supercell_hint_button,
self.supercell_number_estimator,
self.supercell_reset_button,
- ],
+ ],
),
]
)
@@ -213,6 +249,11 @@ def change_supercell(_=None):
super().__init__(**kwargs)
+ # we define a block for the estimation of the supercell if we ask for hint,
+ # so that we call the estimator at the end (we don't lose time).
+ # see the methods below.
+ self.block = False
+
@tl.observe("input_structure")
def _update_input_structure(self, change):
if self.input_structure is not None:
@@ -238,13 +279,18 @@ def _suggest_supercell(self, _=None):
suggested_3D = 15 // np.array(s.cell.cellpar()[:3]) + 1
# if disabled, it means that it is a non-periodic direction.
+ # here we manually unobserve the `_estimate_supercells`, so it is faster
+ # and only compute when all the three directions are updated
+ self.block = True
for direction, suggested, original in zip(
[self._sc_x, self._sc_y, self._sc_z], suggested_3D, s.cell.cellpar()[:3]
):
direction.value = suggested if not direction.disabled else 1
+ self.block = False
+ self._estimate_supercells()
else:
return
-
+
@tl.observe("input_structure")
@disable_print
def _estimate_supercells(self, _=None):
@@ -252,28 +298,66 @@ def _estimate_supercells(self, _=None):
Estimate the number of supercells to be computed for frozen phonon calculation.
"""
+ if self.block:
+ return
+
+ self.supercell_number_estimator.value = spinner_html
+
from aiida_phonopy.data.preprocess import PreProcessData
-
- supercells = PreProcessData(
- structure=self.input_structure,
- supercell_matrix=[
- [self._sc_x.value, 0, 0],
- [0, self._sc_y.value, 0],
- [0, 0, self._sc_z.value]],
- symprec=1e-5,
- distinguish_kinds=False,
- is_symmetry=True,
- ).get_supercells_with_displacements()
-
- self.supercell_number_estimator.value = f"{len(supercells)}"
-
- return
+
+ if self.input_structure:
+ preprocess_data = PreProcessData(
+ structure=self.input_structure,
+ supercell_matrix=[
+ [self._sc_x.value, 0, 0],
+ [0, self._sc_y.value, 0],
+ [0, 0, self._sc_z.value],
+ ],
+ symprec=1e-5,
+ distinguish_kinds=False,
+ is_symmetry=True,
+ )
+
+ supercells = preprocess_data.get_supercells_with_displacements()
+
+ # for now, we comment the following part, as the HubbardSD is generated in the submission step.
+ """if isinstance(self.input_structure, HubbardStructureData):
+ from aiida_vibroscopy.calculations.spectra_utils import get_supercells_for_hubbard
+ from aiida_vibroscopy.workflows.phonons.base import get_supercell_hubbard_structure
+ supercell = get_supercell_hubbard_structure(
+ self.input_structure,
+ self.input_structure,
+ metadata={"store_provenance": False},
+ )
+ supercells = get_supercells_for_hubbard(
+ preprocess_data=preprocess_data,
+ ref_structure=supercell,
+ metadata={"store_provenance": False},
+ )
+
+ else:
+ supercells = preprocess_data.get_supercells_with_displacements()
+ """
+ self.supercell_number_estimator.value = f"{len(supercells)}"
+
+ return
def _reset_supercell(self, _=None):
- for direction in [self._sc_x, self._sc_y, self._sc_z]:
- direction.value = 2
+ if self.input_structure is not None:
+ reset_supercell = []
+ self.block = True
+ for direction, periodic in zip(
+ [self._sc_x, self._sc_y, self._sc_z], self.input_structure.pbc
+ ):
+ if periodic:
+ reset_supercell.append(2)
+ else:
+ reset_supercell.append(1)
+ (self._sc_x.value, self._sc_y.value, self._sc_z.value) = reset_supercell
+ self.block = False
+ self._estimate_supercells()
return
-
+
def get_panel_value(self):
"""Return a dictionary with the input parameters for the plugin."""
return {