From 1ea22a04c020dc3edbaead6d9f4ef0c77f2b236b Mon Sep 17 00:00:00 2001 From: AndresOrtegaGuerrero Date: Fri, 29 Nov 2024 10:49:07 +0000 Subject: [PATCH] setting logic for size and resent hint buttons --- src/aiidalab_qe_vibroscopy/app/model.py | 64 ++++++++++++++++--- src/aiidalab_qe_vibroscopy/app/settings.py | 73 ++++------------------ 2 files changed, 68 insertions(+), 69 deletions(-) diff --git a/src/aiidalab_qe_vibroscopy/app/model.py b/src/aiidalab_qe_vibroscopy/app/model.py index a200736..8191e0b 100644 --- a/src/aiidalab_qe_vibroscopy/app/model.py +++ b/src/aiidalab_qe_vibroscopy/app/model.py @@ -1,6 +1,6 @@ import traitlets as tl - +import numpy as np from aiidalab_qe.common.mixins import HasInputStructure from aiidalab_qe.common.panel import ConfigurationSettingsModel @@ -26,7 +26,7 @@ class VibroConfigurationSettingsModel(ConfigurationSettingsModel, HasInputStruct supercell_y = tl.Int(2) supercell_z = tl.Int(2) - #Control for disable the supercell widget + # Control for disable the supercell widget disable_x = tl.Bool(False) disable_y = tl.Bool(False) @@ -37,30 +37,80 @@ class VibroConfigurationSettingsModel(ConfigurationSettingsModel, HasInputStruct default_value=[2, 2, 2], ) + def get_model_state(self): + return { + "simulation_type": self.simulation_type, + "symmetry_symprec": self.symmetry_symprec, + "supercell": self.supercell, + } + + def set_model_state(self, parameters: dict): + self.simulation_type = parameters.get("simulation_type", 1) + self.symmetry_symprec = parameters.get("symmetry_symprec", 1e-5) + self.supercell = parameters.get("supercell", [2, 2, 2]) + self.supercell_x, self.supercell_y, self.supercell_z = self.supercell + + def reset(self): + with self.hold_trait_notifications(): + self.simulation_type = 1 + self.symmetry_symprec = 1e-5 + self.supercell = [2, 2, 2] + self.supercell_x, self.supercell_y, self.supercell_z = self.supercell + def _get_default(self, trait): return self._defaults.get(trait, self.traits()[trait].default_value) - - def on_input_structure_change(self, _=None): + def on_input_structure_change(self, _=None): if not self.input_structure: self._get_default() else: - self.disable_x, self.disable_y, self.disable_z = True, True, True pbc = self.input_structure.pbc - if pbc == (False,False, False): + if pbc == (False, False, False): # No periodicity; fully disable and reset supercell self.supercell_x = self.supercell_y = self.supercell_z = 1 elif pbc == (True, False, False): self.supercell_y = self.supercell_z = 1 self.disable_x = False + self.symmetry_symprec = 1e-3 elif pbc == (True, True, False): self.supercell_z = 1 self.disable_x = self.disable_y = False elif pbc == (True, True, True): self.disable_x = self.disable_y = self.disable_z = False - self.supercell = [self.supercell_x, self.supercell_y, self.supercell_z] + + def suggest_supercell(self, _=None): + """ + minimal supercell size for phonons, imposing a minimum lattice parameter of 15 A. + """ + if self.input_structure and self.input_structure.pbc != (False, False, False): + ase_structure = self.input_structure.get_ase() + suggested_3D = 15 // np.array(ase_structure.cell.cellpar()[:3]) + 1 + + # Update only dimensions that are not disabled + if not self.disable_x: + self.supercell_x = int(suggested_3D[0]) + if not self.disable_y: + self.supercell_y = int(suggested_3D[1]) + if not self.disable_z: + self.supercell_z = int(suggested_3D[2]) + + # Sync the updated values to the supercell list + self.supercell = [self.supercell_x, self.supercell_y, self.supercell_z] + + # self._activate_estimate_supercells() + else: + return + + def supercell_reset(self, _=None): + if not self.disable_x: + self.supercell_x = self._get_default("supercell_x") + if not self.disable_y: + self.supercell_y = self._get_default("supercell_x") + if not self.disable_z: + self.supercell_z = self._get_default("supercell_x") + self.supercell = [self.supercell_x, self.supercell_y, self.supercell_z] diff --git a/src/aiidalab_qe_vibroscopy/app/settings.py b/src/aiidalab_qe_vibroscopy/app/settings.py index 52039e5..4dec097 100644 --- a/src/aiidalab_qe_vibroscopy/app/settings.py +++ b/src/aiidalab_qe_vibroscopy/app/settings.py @@ -131,6 +131,10 @@ def render(self): (self._model, "simulation_type"), (self.simulation_type, "value"), ) + self.simulation_type.observe( + self._on_change_simulation_type, + "value", + ) self.symmetry_symprec = ipw.FloatText( max=1, @@ -182,37 +186,6 @@ def render(self): (self.supercell_z, "disabled"), ) - # self.simulation_type.observe(self._display_supercell, names="value") - # self.supercell = [2, 2, 2] - - # def change_supercell(_=None): - # self.supercell = [ - # self._sc_x.value, - # self._sc_y.value, - # self._sc_z.value, - # ] - - # if self.input_structure: - # pbc = self.input_structure.pbc - # else: - # pbc = (True, True, True) - - # for elem, periodic in zip(["x", "y", "z"], pbc): - # # periodic allows support of hints also for 2D, 1D. - # setattr( - # self, - # "_sc_" + elem, - # ipw.BoundedIntText( - # value=2 if periodic else 1, - # min=1, - # layout={"width": "40px"}, - # disabled=False if periodic else True, - # ), - # ) - # for elem in [self._sc_x, self._sc_y, self._sc_z]: - # elem.observe(change_supercell, names="value") - # elem.observe(self._activate_estimate_supercells, names="value") - self.supercell_selector = ipw.HBox( children=[ ipw.HTML( @@ -236,8 +209,9 @@ def render(self): layout=ipw.Layout(width="100px"), button_style="info", ) + # supercell hint (15A lattice params) - # self.supercell_hint_button.on_click(self._suggest_supercell) + self.supercell_hint_button.on_click(self._model.suggest_supercell) # reset supercell self.supercell_reset_button = ipw.Button( @@ -247,7 +221,7 @@ def render(self): button_style="warning", ) # supercell reset reaction - # self.supercell_reset_button.on_click(self._reset_supercell) + self.supercell_reset_button.on_click(self._model.supercell_reset) # Estimate supercell button self.supercell_estimate_button = ipw.Button( @@ -337,6 +311,10 @@ def _on_input_structure_change(self, _): self.refresh(specific="structure") self._model.on_input_structure_change() + def _on_change_simulation_type(self, _): + self.supercell_widget.layout.display = ( + "block" if self._model.simulation_type in [1, 3] else "none" + ) # we define a block for the estimation of the supercell if we ask for hint, # so that we call the estimator only at the end of the supercell hint generator, @@ -363,13 +341,6 @@ def _on_input_structure_change(self, _): # self.supercell_number_estimator.layout.display = "none" # self.supercell_estimate_button.layout.display = "none" - # def _display_supercell(self, change): - # selected = change["new"] - # if selected in [1, 3]: - # self.supercell_widget.layout.display = "block" - # else: - # self.supercell_widget.layout.display = "none" - # def _suggest_supercell(self, _=None): # """ # minimal supercell size for phonons, imposing a minimum lattice parameter of 15 A. @@ -468,25 +439,3 @@ def _on_input_structure_change(self, _): # self.symmetry_symprec.value = 1e-5 # self._activate_estimate_supercells() # return - - # def get_panel_value(self): - # """Return a dictionary with the input parameters for the plugin.""" - # return { - # "simulation_mode": self.calc_options.value, - # "supercell_selector": self.supercell, - # "symmetry_symprec": self.symmetry_symprec.value, - # } - - # def set_panel_value(self, input_dict): - # """Load a dictionary with the input parameters for the plugin.""" - # self.calc_options.value = input_dict.get("simulation_mode", 1) - # self.supercell = input_dict.get("supercell_selector", [2, 2, 2]) - # self.symmetry_symprec.value = input_dict.get("symmetry_symprec", 1e-5) - # self._sc_x.value, self._sc_y.value, self._sc_z.value = self.supercell - - # def reset(self): - # """Reset the panel""" - # self.calc_options.value = 1 - # self.supercell = [2, 2, 2] - # self.symmetry_symprec.value = 1e-5 - # self._sc_x.value, self._sc_y.value, self._sc_z.value = self.supercell