From 27efadbef41353aedfb95d05fb70b0198febc232 Mon Sep 17 00:00:00 2001 From: mikibonacci Date: Mon, 9 Dec 2024 12:38:19 +0000 Subject: [PATCH] Adding the model and view to the rendering. Putting init in the model, to inject correct traits. --- .../app/result/result.py | 10 +- .../app/widgets/euphonic/model.py | 2 +- .../app/widgets/euphonicmodel.py | 130 ++++++++----- .../app/widgets/euphonicwidget.py | 63 +++--- .../app/widgets/structurefactorwidget.py | 183 +++++++++++------- .../base_widgets/euphonic_base_widgets.py | 2 +- .../data/export_vibronic_to_euphonic.py | 9 +- .../utils/euphonic/data/phonopy_interface.py | 12 +- .../utils/euphonic/data/structure_factors.py | 20 +- .../euphonic/detached_app/uploadwidgets.py | 12 +- .../tab_widgets/euphonic_q_planes_widgets.py | 4 +- 11 files changed, 272 insertions(+), 175 deletions(-) diff --git a/src/aiidalab_qe_vibroscopy/app/result/result.py b/src/aiidalab_qe_vibroscopy/app/result/result.py index 8ad8d69..9548a2c 100644 --- a/src/aiidalab_qe_vibroscopy/app/result/result.py +++ b/src/aiidalab_qe_vibroscopy/app/result/result.py @@ -13,14 +13,10 @@ from aiidalab_qe_vibroscopy.app.widgets.phononwidget import PhononWidget from aiidalab_qe_vibroscopy.app.widgets.phononmodel import PhononModel -from aiidalab_qe_vibroscopy.app.widgets.euphonicwidget import ( - EuphonicSuperWidget as EuphonicWidget, -) +from aiidalab_qe_vibroscopy.app.widgets.euphonicwidget import EuphonicWidget from aiidalab_qe_vibroscopy.app.widgets.euphonicmodel import ( - EuphonicBaseResultsModel as EuphonicModel, + EuphonicResultsModel as EuphonicModel, ) -# from aiidalab_qe_vibroscopy.app.widgets.euphonic.model import EuphonicModel -# from aiidalab_qe_vibroscopy.app.widgets.euphonic.widget import EuphonicWidget class VibroResultsPanel(ResultsPanel[VibroResultsModel]): @@ -76,7 +72,7 @@ def render(self): ) tab_data.append(("Dielectric Properties", dielectric_widget)) - needs_euphonic_tab = False # self._model.needs_euphonic_tab() + needs_euphonic_tab = self._model.needs_euphonic_tab() if needs_euphonic_tab: euphonic_model = EuphonicModel() euphonic_widget = EuphonicWidget( diff --git a/src/aiidalab_qe_vibroscopy/app/widgets/euphonic/model.py b/src/aiidalab_qe_vibroscopy/app/widgets/euphonic/model.py index 264ca43..3859069 100644 --- a/src/aiidalab_qe_vibroscopy/app/widgets/euphonic/model.py +++ b/src/aiidalab_qe_vibroscopy/app/widgets/euphonic/model.py @@ -1,7 +1,7 @@ from aiidalab_qe.common.panel import ResultsModel from aiida.common.extendeddicts import AttributeDict import traitlets as tl -from aiidalab_qe_vibroscopy.utils.euphonic.data_manipulation.intensity_maps import ( +from aiidalab_qe_vibroscopy.utils.euphonic.data.export_vibronic_to_euphonic import ( export_euphonic_data, ) diff --git a/src/aiidalab_qe_vibroscopy/app/widgets/euphonicmodel.py b/src/aiidalab_qe_vibroscopy/app/widgets/euphonicmodel.py index 500bd65..2617e77 100644 --- a/src/aiidalab_qe_vibroscopy/app/widgets/euphonicmodel.py +++ b/src/aiidalab_qe_vibroscopy/app/widgets/euphonicmodel.py @@ -1,14 +1,21 @@ import numpy as np import traitlets as tl import copy +from IPython.display import display from aiidalab_qe_vibroscopy.utils.euphonic.data.structure_factors import ( AttrDict, produce_bands_weigthed_data, produce_powder_data, generated_curated_data, +) + +from aiidalab_qe_vibroscopy.utils.euphonic.data.phonopy_interface import ( + generate_force_constant_from_phonopy, +) + +from aiidalab_qe_vibroscopy.utils.euphonic.data.export_vibronic_to_euphonic import ( export_euphonic_data, - generate_force_constant_instance, ) from aiidalab_qe_vibroscopy.utils.euphonic.data.parameters import ( @@ -22,6 +29,7 @@ produce_Q_section_spectrum, ) + from aiidalab_qe.common.mvc import Model @@ -38,21 +46,33 @@ class EuphonicResultsModel(Model): # 2. powder average: pa # 3. Q planes: qp - spectra = {} - path = [] - q_path = None - spectrum_type = "single_crystal" - x_label = None - y_label = "Energy (meV)" - detached_app = False - # Settings for single crystal and powder average q_spacing = tl.Float(0.01) energy_broadening = tl.Float(0.05) energy_bins = tl.Int(200) temperature = tl.Float(0) weighting = tl.Unicode("coherent") - + + def __init__(self, node=None, spectrum_type: str = "single_crystal", **kwargs): + super().__init__(**kwargs) + + self.spectra = {} + self.path = [] + self.q_path = None + self.spectrum_type = spectrum_type + self.xlabel = None + self.ylabel = "Energy (meV)" + self.detached_app = False + if node: + self.vibro = node + + if self.spectrum_type == "single_crystal": + self._inject_single_crystal_settings() + elif self.spectrum_type == "powder": + self._inject_powder_settings() + elif self.spectrum_type == "q_planes": + self._inject_qsection_settings() + def set_model_state(self, parameters: dict): for k, v in parameters.items(): setattr(self, k, v) @@ -78,10 +98,10 @@ def fetch_data(self): """Fetch the data from the database or from the uploaded files.""" # 1. from aiida, so we have the node if hasattr(self, "fc"): - # we already have the data (this happens if I clone the model with already the data inside) - return - if self.node: - ins_data = export_euphonic_data(self.node) + # we already have the data (this happens if I clone the model with already the data inside) + return + if self.vibro: + ins_data = export_euphonic_data(self.vibro) self.fc = ins_data["fc"] self.q_path = ins_data["q_path"] # 2. from uploaded files... @@ -99,7 +119,7 @@ def _inject_single_crystal_settings( # we define specific parameters dictionary and callback function for the single crystal case self.parameters = copy.deepcopy(parameters_single_crystal) self._callback_spectra_generation = produce_bands_weigthed_data - + # Dynamically add a trait for single crystal settings self.add_traits(custom_kpath=tl.Unicode("")) @@ -108,7 +128,7 @@ def _inject_powder_settings( ): self.parameters = copy.deepcopy(parameters_powder) self._callback_spectra_generation = produce_powder_data - + # Dynamically add a trait for powder settings self.add_traits(q_min=tl.Float(0.0)) self.add_traits(q_max=tl.Float(1)) @@ -132,10 +152,7 @@ def get_spectra( self, ): # This is used to update the spectra when the parameters are changed - # and the - if not hasattr(self, "parameters"): - self._inject_single_crystal_settings() - + if self.spectrum_type == "q_planes": self._get_qsection_spectra() return @@ -164,7 +181,7 @@ def get_spectra( ) # curated spectra (labels and so on...) - if spectrum_type == "single_crystal": # single crystal case + if self.spectrum_type == "single_crystal": # single crystal case self.x, self.y = np.meshgrid( spectra[0].x_data.magnitude, spectra[0].y_data.magnitude ) @@ -174,15 +191,15 @@ def get_spectra( self.ticks_positions, self.ticks_labels, ) = generated_curated_data(spectra) - + self.z = final_zspectra.T - self.y = self.y[:,0] - self.x = None # we have the ticks positions and labels - + self.y = self.y[:, 0] + self.x = None # we have the ticks positions and labels + self.xlabel = "" self.ylabel = "Energy (meV)" - - elif spectrum_type == "powder": # powder case + + elif self.spectrum_type == "powder": # powder case # Spectrum2D as output of the powder data self.x, self.y = np.meshgrid( spectra.x_data.magnitude, spectra.y_data.magnitude @@ -191,8 +208,10 @@ def get_spectra( # we don't need to curate the powder data, at variance with the single crystal case. # We can directly use them: self.x = spectra.x_data.magnitude[0] - self.y = self.y[:,0] + self.y = self.y[:, 0] self.z = spectra.z_data.magnitude.T + else: + raise ValueError("Spectrum type not recognized:", self.spectrum_type) def _get_qsection_spectra( self, @@ -227,23 +246,21 @@ def _get_qsection_spectra( temperature=self.parameters_qplanes.temperature, ) - self.av_spec, self.z, self.x, self.y, self.labels = ( - produce_Q_section_spectrum( - modes, - q_array, - h_array, - k_array, - ecenter=self.parameters_qplanes.ecenter, - deltaE=self.parameters_qplanes.deltaE, - bins=self.parameters_qplanes.bins, - spectrum_type=self.parameters_qplanes.spectrum_type, - dw=dw, - labels=labels, - ) + self.av_spec, self.z, self.x, self.y, self.labels = produce_Q_section_spectrum( + modes, + q_array, + h_array, + k_array, + ecenter=self.parameters_qplanes.ecenter, + deltaE=self.parameters_qplanes.deltaE, + bins=self.parameters_qplanes.bins, + spectrum_type=self.parameters_qplanes.spectrum_type, + dw=dw, + labels=labels, ) self.xlabel = "AAA" - self.ylabel = "AAA" - + self.ylabel = "AAA" + def _curate_path_and_labels( self, ): @@ -269,16 +286,33 @@ def _curate_path_and_labels( def produce_phonopy_files(self): # This is used to produce the phonopy files from # PhonopyCalculation data. The files are phonopy.yaml and force_constants.hdf5 - phonopy_yaml, fc_hdf5 = generate_force_constant_instance( + phonopy_yaml, fc_hdf5 = generate_force_constant_from_phonopy( self.node.phonon_bands.creator, mode="download" ) return phonopy_yaml, fc_hdf5 - + def prepare_data_for_download(self): raise NotImplementedError("Need to implement the download of a CSV file") - + # return data, filename + + @staticmethod + def _download(payload, filename): + from IPython.display import Javascript + + javas = Javascript( + """ + var link = document.createElement('a'); + link.href = 'data:text/json;charset=utf-8;base64,{payload}' + link.download = "{filename}" + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + """.format(payload=payload, filename=filename) + ) + display(javas) + def _clone(self): - # in case we want to clone the model. + # in case we want to clone the model. # This is the case when we have the same data and we inject in three # different models: we don't need to fetch three times. - return copy.deepcopy(self) \ No newline at end of file + return copy.deepcopy(self) diff --git a/src/aiidalab_qe_vibroscopy/app/widgets/euphonicwidget.py b/src/aiidalab_qe_vibroscopy/app/widgets/euphonicwidget.py index 8808fb3..a222f9f 100644 --- a/src/aiidalab_qe_vibroscopy/app/widgets/euphonicwidget.py +++ b/src/aiidalab_qe_vibroscopy/app/widgets/euphonicwidget.py @@ -1,19 +1,17 @@ -import pathlib -import tempfile import ipywidgets as ipw from IPython.display import display from aiidalab_qe.common.widgets import LoadingWidget -from aiidalab_qe_vibroscopy.utils.euphonic.data.structure_factors import ( - generate_force_constant_instance, +from aiidalab_qe_vibroscopy.app.widgets.structurefactorwidget import ( + EuphonicStructureFactorWidget, ) - -from aiidalab_qe_vibroscopy.app.widgets.structurefactorwidget import EuphonicStructureFactorWidget +from aiidalab_qe_vibroscopy.app.widgets.euphonicmodel import EuphonicResultsModel ##### START OVERALL WIDGET TO DISPLAY EVERYTHING: + class EuphonicWidget(ipw.VBox): """ Widget that will include everything, @@ -22,7 +20,11 @@ class EuphonicWidget(ipw.VBox): """ def __init__( - self, model: EuphonicResultsModel, node=None, detached_app = False, **kwargs, + self, + model: EuphonicResultsModel, + node=None, + detached_app=False, + **kwargs, ): """ Initialize the Euphonic utility class. @@ -50,11 +52,11 @@ def __init__( fc : optional Force constants if provided. """ - + super().__init__() - + self._model = model # this is the single crystal model. - if node: self._model.vibro = node + self._model.vibro = node self._model.detached_app = detached_app self._model.fc_hdf5_content = None @@ -63,7 +65,7 @@ def __init__( def render(self): if self.rendered: return - + self.tab_widget = ipw.Tab() self.tab_widget.layout.display = "none" self.tab_widget.set_title(0, "Single crystal") @@ -86,13 +88,18 @@ def render(self): if not self._model.detached_app: self.plot_button.disabled = False else: - from aiidalab_qe_vibroscopy.utils.euphonic.detached_app.uploadwidgets import UploadPhonopyWidget + from aiidalab_qe_vibroscopy.utils.euphonic.detached_app.uploadwidgets import ( + UploadPhonopyWidget, + ) + self.upload_widget = UploadPhonopyWidget() - self.upload_widget.reset_uploads.on_click(self._on_reset_uploads_button_clicked) + self.upload_widget.reset_uploads.on_click( + self._on_reset_uploads_button_clicked + ) self.upload_widget.children[0].observe(self._on_upload_yaml, "_counter") self.upload_widget.children[1].observe(self._on_upload_hdf5, "_counter") self.children += (self.upload_widget,) - + self.download_widget = DownloadYamlHdf5Widget(model=self._model) self.download_widget.layout.display = "none" @@ -101,8 +108,8 @@ def render(self): self.tab_widget, self.download_widget, self.loading_widget, - ) - + ) + self.rendered = True def _render_for_real(self, change=None): @@ -111,22 +118,23 @@ def _render_for_real(self, change=None): self.loading_widget.layout.display = "block" self._model.fetch_data() # should be in the model, but I can do it here once for all and then clone the model. - powder_model = self._model._clone() - qsection_model = self._model._clone() + powder_model = EuphonicResultsModel(spectum_type="powder") + qsection_model = EuphonicResultsModel(spectum_type="q_planes") + + for data in ["fc", "q_path"]: + setattr(powder_model, data, getattr(self._model, data)) + setattr(qsection_model, data, getattr(self._model, data)) # I first initialise this widget, to then have the 0K ref for the other two. # the model is passed to the widget. For the other two, I need to generate the model. - singlecrystalwidget = SingleCrystalFullWidget(model=self._model) - - # I need to generate the models for the other two widgets. - self._model._inject_single_crystal_settings() - powder_model._inject_powder_settings() - qsection_model._inject_qsection_settings() + singlecrystalwidget = EuphonicStructureFactorWidget( + node=self._model.vibro, model=self._model, spectrum_type="single_crystal" + ) self.tab_widget.children = ( singlecrystalwidget, - PowderFullWidget(model=powder_model), - QSectionFullWidget(model=qsection_model), + # EuphonicStructureFactorWidget(node=self._model.vibro, model=powder_model, spectrum_type="powder"), + # EuphonicStructureFactorWidget(node=self._model.vibro, model=qsection_model, spectrum_type="q_planes"), ) for widget in self.tab_widget.children: @@ -168,7 +176,8 @@ def _on_upload_hdf5(self, change): self._model.fc_hdf5_content = self.upload_widget.children[1].value[ fname ]["content"] - + + class DownloadYamlHdf5Widget(ipw.HBox): def __init__(self, model): self._model = model diff --git a/src/aiidalab_qe_vibroscopy/app/widgets/structurefactorwidget.py b/src/aiidalab_qe_vibroscopy/app/widgets/structurefactorwidget.py index 51857fc..1fee1f1 100644 --- a/src/aiidalab_qe_vibroscopy/app/widgets/structurefactorwidget.py +++ b/src/aiidalab_qe_vibroscopy/app/widgets/structurefactorwidget.py @@ -1,21 +1,40 @@ +import ipywidgets as ipw +from IPython.display import display + +import numpy as np + # ADD ALL THE IMPORTS. +import plotly.graph_objs as go + +from aiidalab_qe_vibroscopy.app.widgets.euphonicmodel import EuphonicResultsModel + +COLORSCALE = "Viridis" +COLORBAR_DICT = dict(orientation="v", showticklabels=False, x=1, thickness=10, len=0.4) class EuphonicStructureFactorWidget(ipw.VBox): """Description. - + Collects all the button and widget used to define settings for Neutron dynamic structure factor, in all the three cases: single crystal, powder, and q-section.... """ - def __init__(self, model, node=None, spectrum_type = "single_crystal", detached_app = False, **kwargs): + def __init__( + self, + model: EuphonicResultsModel, + node=None, + spectrum_type="single_crystal", + detached_app=False, + **kwargs, + ): super().__init__() self._model = model - if node: self._model.vibro = node + if node: + self._model.vibro = node self._model.spectrum_type = spectrum_type self._model.detached_app = detached_app self.rendered = False - + def render(self): """Render the widget. @@ -23,9 +42,9 @@ def render(self): """ if self.rendered: return - + self._init_view() - + slider_intensity = ipw.FloatRangeSlider( value=[1, 100], # Default selected interval min=1, @@ -67,7 +86,7 @@ def render(self): ) ipw.link( (self._model, "q_spacing"), - (self.q_spacing, "value"), + (q_spacing, "value"), ) q_spacing.observe(self._on_setting_change, names="value") @@ -148,10 +167,32 @@ def render(self): layout=ipw.Layout(width="auto"), ) download_button.on_click(self._download_data) - + + self.children += ( + ipw.HBox( + [ + slider_intensity, + specification_intensity, + ], + layout=ipw.Layout( + justify_content="space-between", + margin="10px 0", + ), + ), + E_units_button, + q_spacing, + energy_broadening, + energy_bins, + temperature, + weight_button, + plot_button, + reset_button, + download_button, + ) + if self._model.spectrum_type == "single_crystal": self.custom_kpath_description = ipw.HTML( - """ + """
Custom q-points path for the structure factor:
we can provide it via a specific format:
@@ -176,18 +217,23 @@ def render(self): (self._model, "custom_kpath"), (self.custom_kpath_text, "value"), ) - self.custom_kpath_text.observe(self._on_setting_changed, names="value") + self.custom_kpath_text.observe(self._on_setting_change, names="value") + + self.children += ( + self.custom_kpath_description, + self.custom_kpath_text, + ) # fi self._model.spectrum_type == "single_crystal" elif self._model.spectrum_type == "powder": self.qmin = ipw.FloatText( - value=0, - description="|q|min (1/A)", + value=0, + description="|q|min (1/A)", ) ipw.link( (self._model, "q_min"), (self.qmin, "value"), ) - self.qmin.observe(self._on_setting_changed, names="value") + self.qmin.observe(self._on_setting_change, names="value") self.qmax = ipw.FloatText( step=0.01, @@ -198,7 +244,7 @@ def render(self): (self._model, "q_max"), (self.qmax, "value"), ) - self.qmax.observe(self._on_setting_changed, names="value") + self.qmax.observe(self._on_setting_change, names="value") self.int_npts = ipw.IntText( value=100, @@ -209,18 +255,18 @@ def render(self): (self._model, "npts"), (self.int_npts, "value"), ) - self.int_npts.observe(self._on_setting_changed, names="value") + self.int_npts.observe(self._on_setting_change, names="value") # fi self._model.spectrum_type == "powder" elif self._model.spectrum_type == "q_planes": self.ecenter = ipw.FloatText( - value=0, - description="E (meV)", + value=0, + description="E (meV)", ) ipw.link( (self._model, "center_e"), (self.ecenter, "value"), ) - self.ecenter.observe(self._on_setting_changed, names="value") + self.ecenter.observe(self._on_setting_change, names="value") self.plane_description_widget = ipw.HTML( """ @@ -266,7 +312,7 @@ def render(self): for vec in [self.Q0_vec, self.h_vec, self.k_vec]: for child in vec.children: - child.observe(self._on_setting_changed, names="value") + child.observe(self._on_setting_change, names="value") child.observe(self._on_vector_changed, names="value") self.Q0_widget = ipw.HBox( @@ -288,24 +334,24 @@ def render(self): (self._model, "energy_broadening"), (self.energy_broadening, "value"), ) - self.energy_broadening.observe(self._on_setting_changed, names="value") + self.energy_broadening.observe(self._on_setting_change, names="value") self.plot_button.disabled = False self.plot_button.description = "Plot" # self.reset_button.disabled = True self.download_button.disabled = True # fi self._model.spectrum_type == "q_planes" - - self.children += ( - ... - ) - + + self.children += (self.fig,) + self.rendered = True - + def _init_view(self, _=None): self._model.fetch_data() + if not hasattr(self, "fig"): + self.fig = go.FigureWidget() self._update_plot() - + def _on_plot_button_change(self, change): self.download_button.disabled = not change["new"] @@ -318,34 +364,35 @@ def _on_setting_change( self, change ): # think if we want to do something more evident... self.plot_button.disabled = False - + def _update_plot(self): # update the spectra, i.e. the data contained in the _model. # TODO: we need to treat differently the update of intensity and units. # they anyway need to modify the data, but no additional spectra re-generation is really needed. # so the update_spectra need some more logic, or we call another method. self._model.get_spectra() - + if not self.rendered: # First time we render, we set several layout settings. # Layout settings - self.fig["layout"]["xaxis"].update( - title=self._model.xlabel, - range=[min(self._model.x), max(self._model.x)], - ) + if self._model.x: + self.fig["layout"]["xaxis"].update( + title=self._model.xlabel, + range=[min(self._model.x), max(self._model.x)], + ) self.fig["layout"]["yaxis"].update( title=self._model.ylabel, range=[min(self._model.y), max(self._model.y)], ) - + if self.fig.layout.images: for image in self.fig.layout.images: image["scl"] = 2 # Set the scale for each image - + self.fig.update_layout( - height=500, - width=700, - margin=dict(l=15, r=15, t=15, b=15), + height=500, + width=700, + margin=dict(l=15, r=15, t=15, b=15), ) # Update x-axis and y-axis to enable autoscaling self.fig.update_xaxes(autorange=True) @@ -354,17 +401,18 @@ def _update_plot(self): # Update the layout to enable autoscaling self.fig.update_layout(autosize=True) - heatmap_trace = go.Heatmap( - z=self._model.z, - y=(self._model.y), - x=self._model.x, - colorbar=COLORBAR_DICT, - colorscale=COLORSCALE, # imported from euphonic_base_widgets - ) + z=self._model.z, + y=(self._model.y), + x=self._model.x, + colorbar=COLORBAR_DICT, + colorscale=COLORSCALE, # imported from euphonic_base_widgets + ) # change the path wants also a change in the labels - if "ticks_positions" in self._model and "ticks_labels" in self._model: + if hasattr(self._model, "ticks_positions") and hasattr( + self._model, "ticks_labels" + ): self.fig.update_layout( xaxis=dict( tickmode="array", @@ -380,30 +428,35 @@ def _update_plot(self): # Add heatmap trace to figure self.fig.add_trace(heatmap_trace) - self.fig.data = [self.fig.data[1]] + self.fig.data = [self.fig.data[-1]] + + def _update_intensity_filter(self, change): + # the value of the intensity slider is in fractions of the max. + if change["new"] != change["old"]: + self.fig.data[0].zmax = ( + change["new"][1] * np.max(self.fig.data[0].z) / 100 + ) # above this, it is all yellow, i.e. max intensity. + self.fig.data[0].zmin = ( + change["new"][0] * np.max(self.fig.data[0].z) / 100 + ) # below this, it is all blue, i.e. zero intensity + + def _update_energy_units(self, change): + # the value of the intensity slider is in fractions of the max. + if change["new"] != change["old"]: + self.fig.data[0].y = ( + self.fig.data[0].y * self.THz_to_meV + if change["new"] == "meV" + else self.fig.data[0].y / self.THz_to_meV + ) + + self.fig["layout"]["yaxis"].update(title=change["new"]) def _reset_settings(self, _): self._model.reset() - + def _download_data(self, _=None): data, filename = self._model.prepare_data_for_download() - self._download(data, filename) - - @staticmethod - def _download(payload, filename): - from IPython.display import Javascript - - javas = Javascript( - """ - var link = document.createElement('a'); - link.href = 'data:text/json;charset=utf-8;base64,{payload}' - link.download = "{filename}" - document.body.appendChild(link); - link.click(); - document.body.removeChild(link); - """.format(payload=payload, filename=filename) - ) - display(javas) + self._model._download(data, filename) def _on_vector_changed(self, change=None): """ diff --git a/src/aiidalab_qe_vibroscopy/utils/euphonic/base_widgets/euphonic_base_widgets.py b/src/aiidalab_qe_vibroscopy/utils/euphonic/base_widgets/euphonic_base_widgets.py index b0daf63..8655a6e 100644 --- a/src/aiidalab_qe_vibroscopy/utils/euphonic/base_widgets/euphonic_base_widgets.py +++ b/src/aiidalab_qe_vibroscopy/utils/euphonic/base_widgets/euphonic_base_widgets.py @@ -3,7 +3,7 @@ import plotly.graph_objects as go # from ..euphonic.bands_pdos import * -from aiidalab_qe_vibroscopy.utils.euphonic.data_manipulation.intensity_maps import * # noqa: F403 +from aiidalab_qe_vibroscopy.utils.euphonic.data.structure_factors import * # noqa: F403 # sys and os used to prevent euphonic to print in the stdout. diff --git a/src/aiidalab_qe_vibroscopy/utils/euphonic/data/export_vibronic_to_euphonic.py b/src/aiidalab_qe_vibroscopy/utils/euphonic/data/export_vibronic_to_euphonic.py index 7254e93..c5a4f75 100644 --- a/src/aiidalab_qe_vibroscopy/utils/euphonic/data/export_vibronic_to_euphonic.py +++ b/src/aiidalab_qe_vibroscopy/utils/euphonic/data/export_vibronic_to_euphonic.py @@ -1,6 +1,7 @@ -from aiida.orm import Dict -from aiida_phonopy.common.raw_parsers import get_force_constants_from_phonopy -from aiida_phonopy.workflows.phonon import generate_force_constant_instance +from aiidalab_qe_vibroscopy.utils.euphonic.data.phonopy_interface import ( + generate_force_constant_from_phonopy, +) + def export_euphonic_data(output_vibronic, fermi_energy=None): if "phonon_bands" not in output_vibronic: @@ -32,7 +33,7 @@ def export_euphonic_data(output_vibronic, fermi_energy=None): q_path = None phonopy_calc = output_set.creator - fc = generate_force_constant_instance(phonopy_calc) + fc = generate_force_constant_from_phonopy(phonopy_calc) # bands = compute_bands(fc) # pdos = compute_pdos(fc) return { diff --git a/src/aiidalab_qe_vibroscopy/utils/euphonic/data/phonopy_interface.py b/src/aiidalab_qe_vibroscopy/utils/euphonic/data/phonopy_interface.py index 048257f..b580d65 100644 --- a/src/aiidalab_qe_vibroscopy/utils/euphonic/data/phonopy_interface.py +++ b/src/aiidalab_qe_vibroscopy/utils/euphonic/data/phonopy_interface.py @@ -3,9 +3,15 @@ import base64 from typing import Optional import euphonic -from euphonic.io.phonopy import write_force_constants_to_hdf5 +from phonopy.file_IO import write_force_constants_to_hdf5 -def generate_force_constant_instance( +from aiidalab_qe_vibroscopy.utils.euphonic.data.structure_factors import ( + blockPrint, + enablePrint, +) + + +def generate_force_constant_from_phonopy( phonopy_calc=None, path: str = None, summary_name: str = None, @@ -115,4 +121,4 @@ def generate_force_constant_instance( # print(filename) # print(dirpath) enablePrint() - return fc \ No newline at end of file + return fc diff --git a/src/aiidalab_qe_vibroscopy/utils/euphonic/data/structure_factors.py b/src/aiidalab_qe_vibroscopy/utils/euphonic/data/structure_factors.py index 6634dd4..edfeb6e 100644 --- a/src/aiidalab_qe_vibroscopy/utils/euphonic/data/structure_factors.py +++ b/src/aiidalab_qe_vibroscopy/utils/euphonic/data/structure_factors.py @@ -1,8 +1,5 @@ from typing import List, Optional -import pathlib -import tempfile -import base64 import matplotlib.style import numpy as np @@ -42,7 +39,11 @@ from euphonic.styles import intensity_widget_style import euphonic.util -from phonopy.file_IO import write_force_constants_to_hdf5 + +from aiidalab_qe_vibroscopy.utils.euphonic.data.parameters import ( + parameters_single_crystal, + parameters_powder, +) # Dummy tqdm function if tqdm progress bars unavailable try: @@ -199,11 +200,9 @@ def produce_bands_weigthed_data( """ # args = get_args(get_parser(), params) if not params: - args = AttrDict(copy.deepcopy(parameters)) + args = AttrDict(copy.deepcopy(parameters_single_crystal)) else: - args = copy.deepcopy(parameters) - args.update(params) - args = AttrDict(args) + args = AttrDict(params) # redundancy with args... calc_modes_kwargs = _calc_modes_kwargs(args) @@ -356,7 +355,7 @@ def produce_bands_weigthed_data( ######################## -#parameters_powder = AttrDict(par_dict_powder) +# parameters_powder = AttrDict(par_dict_powder) def produce_powder_data( @@ -369,11 +368,10 @@ def produce_powder_data( """Read the description of the produce_bands_weigthed_data function for more details. """ - # args = get_args(get_parser(), params) if not params: args = AttrDict(copy.deepcopy(parameters_powder)) else: - args = AttrDict(copy.deepcopy(params)) + args = AttrDict(params) # redundancy with args calc_modes_kwargs = _calc_modes_kwargs(args) diff --git a/src/aiidalab_qe_vibroscopy/utils/euphonic/detached_app/uploadwidgets.py b/src/aiidalab_qe_vibroscopy/utils/euphonic/detached_app/uploadwidgets.py index 2a3ad09..c2a086d 100644 --- a/src/aiidalab_qe_vibroscopy/utils/euphonic/detached_app/uploadwidgets.py +++ b/src/aiidalab_qe_vibroscopy/utils/euphonic/detached_app/uploadwidgets.py @@ -7,10 +7,7 @@ import ipywidgets as ipw # from ..euphonic.bands_pdos import * -from aiidalab_qe_vibroscopy.utils.euphonic.data_manipulation.intensity_maps import ( - generate_force_constant_instance, - export_euphonic_data, # noqa: F401 -) + from aiidalab_qe_vibroscopy.utils.euphonic.tab_widgets.euphonic_single_crystal_widgets import ( SingleCrystalFullWidget, ) @@ -21,6 +18,9 @@ QSectionFullWidget, ) +from aiidalab_qe_vibroscopy.utils.euphonic.data.phonopy_interface import ( + generate_force_constant_from_phonopy, +) from aiidalab_qe.common.widgets import LoadingWidget ###### START for detached app: @@ -81,7 +81,7 @@ def _read_phonopy_files(self, fname, phonopy_yaml_content, fc_hdf5_content=None) temp_hdf5_name = temp_file.name try: - fc = generate_force_constant_instance( + fc = generate_force_constant_from_phonopy( path=pathlib.Path(fname), summary_name=temp_yaml.name, fc_name=temp_hdf5_name, @@ -94,7 +94,7 @@ def _read_phonopy_files(self, fname, phonopy_yaml_content, fc_hdf5_content=None) temp_hdf5_name = None try: - fc = generate_force_constant_instance( + fc = generate_force_constant_from_phonopy( path=pathlib.Path(fname), summary_name=temp_yaml.name, # fc_name=temp_hdf5_name, diff --git a/src/aiidalab_qe_vibroscopy/utils/euphonic/tab_widgets/euphonic_q_planes_widgets.py b/src/aiidalab_qe_vibroscopy/utils/euphonic/tab_widgets/euphonic_q_planes_widgets.py index 6fa8a5f..eca0af8 100644 --- a/src/aiidalab_qe_vibroscopy/utils/euphonic/tab_widgets/euphonic_q_planes_widgets.py +++ b/src/aiidalab_qe_vibroscopy/utils/euphonic/tab_widgets/euphonic_q_planes_widgets.py @@ -21,7 +21,7 @@ from monty.json import jsanitize import plotly.graph_objects as go -from aiidalab_qe_vibroscopy.utils.euphonic.data_manipulation.intensity_maps import ( +from aiidalab_qe_vibroscopy.utils.euphonic.data.structure_factors import ( blockPrint, enablePrint, ) @@ -101,7 +101,7 @@ def produce_Q_section_spectrum( dw=None, labels=None, ): - from aiidalab_qe_vibroscopy.utils.euphonic.data_manipulation.intensity_maps import ( + from aiidalab_qe_vibroscopy.utils.euphonic.data.structure_factors import ( blockPrint, enablePrint, )