Skip to content

Commit

Permalink
template of result tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
AndresOrtegaGuerrero committed Nov 30, 2024
1 parent 7486b06 commit 8ea879c
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 46 deletions.
6 changes: 6 additions & 0 deletions src/aiidalab_qe_vibroscopy/app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
VibroResourceSettingsModel,
VibroResourcesSettingsPanel,
)
from aiidalab_qe_vibroscopy.app.result.result import VibroResultsPanel
from aiidalab_qe_vibroscopy.app.result.model import VibroResultsModel

from aiidalab_qe_vibroscopy.app.workchain import workchain_and_builder

Expand All @@ -24,5 +26,9 @@ class VibroPluginOutline(PluginOutline):
"panel": VibroResourcesSettingsPanel,
"model": VibroResourceSettingsModel,
},
"result": {
"panel": VibroResultsPanel,
"model": VibroResultsModel,
},
"workchain": workchain_and_builder,
}
19 changes: 19 additions & 0 deletions src/aiidalab_qe_vibroscopy/app/result/model.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
from aiidalab_qe.common.panel import ResultsModel
import traitlets as tl

from aiidalab_qe_vibroscopy.utils.dielectric.result import export_dielectric_data
from aiidalab_qe_vibroscopy.utils.raman.result import export_iramanworkchain_data
from aiidalab_qe_vibroscopy.utils.phonons.result import export_phononworkchain_data
from aiidalab_qe_vibroscopy.utils.euphonic import export_euphonic_data


class VibroResultsModel(ResultsModel):
identifier = "vibronic"
Expand All @@ -11,3 +16,17 @@ class VibroResultsModel(ResultsModel):

def get_vibro_node(self):
return self._get_child_outputs()

def needs_dielectric_tab(self):
return export_dielectric_data(self.get_vibro_node())

def needs_raman_tab(self):
return export_iramanworkchain_data(self.get_vibro_node())

# Here we use _fetch_child_process_node() since the function needs the input_structure in inputs
def needs_phonons_tab(self):
return export_phononworkchain_data(self._fetch_child_process_node())

# Here we use _fetch_child_process_node() since the function needs the input_structure in inputs
def needs_euphonic_tab(self):
return export_euphonic_data(self._fetch_child_process_node())
31 changes: 31 additions & 0 deletions src/aiidalab_qe_vibroscopy/app/result/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from aiidalab_qe_vibroscopy.app.result.model import VibroResultsModel
from aiidalab_qe.common.panel import ResultsPanel

import ipywidgets as ipw


class VibroResultsPanel(ResultsPanel[VibroResultsModel]):
title = "Vibronic"
Expand All @@ -12,3 +14,32 @@ class VibroResultsPanel(ResultsPanel[VibroResultsModel]):
def render(self):
if self.rendered:
return

self.tabs = ipw.Tab(
layout=ipw.Layout(min_height="250px"),
selected_index=None,
)

tab_data = []
# vibro_node = self._model.get_vibro_node()

if self._model.needs_phonons_tab():
tab_data.append(("Phonons", ipw.HTML("phonon_data")))

if self._model.needs_raman_tab():
tab_data.append(("Raman", ipw.HTML("raman_data")))

if self._model.needs_dielectric_tab():
tab_data.append(("Dielectric", ipw.HTML("dielectric_data")))

if self._model.needs_euphonic_tab():
tab_data.append(("Euphonic", ipw.HTML("euphonic_data")))

# Assign children and titles dynamically
self.tabs.children = [content for _, content in tab_data]

for index, (title, _) in enumerate(tab_data):
self.tabs.set_title(index, title)

self.children = [self.tabs]
self.rendered = True
9 changes: 9 additions & 0 deletions src/aiidalab_qe_vibroscopy/app/widgets/dielectricmodel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from aiidalab_qe.common.mvc import Model
from aiida.common.extendeddicts import AttributeDict
import traitlets as tl


class DielectricModel(Model):
vibro = tl.Instance(AttributeDict, allow_none=True)

dielectric_data = {}
38 changes: 38 additions & 0 deletions src/aiidalab_qe_vibroscopy/app/widgets/dielectricwidget.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import ipywidgets as ipw
from aiidalab_qe_vibroscopy.app.widgets.dielectricmodel import DielectricModel
from aiidalab_qe.common.widgets import LoadingWidget


class DielectricWidget(ipw.VBox):
"""
Widget for displaying dielectric properties results
"""

def __init__(self, model: DielectricModel, dielectric_node: None, **kwargs):
super().__init__(
children=[LoadingWidget("Loading widgets")],
**kwargs,
)
self._model = model

def render(self):
if self.rendered:
return

self.dielectric_results_help = ipw.HTML(
"""<div style="line-height: 140%; padding-top: 0px; padding-bottom: 5px">
The DielectricWorkchain computes different properties: <br>
<em style="display: inline-block; margin-left: 20px;">-High Freq. Dielectric Tensor </em> <br>
<em style="display: inline-block; margin-left: 20px;">-Born Charges </em> <br>
<em style="display: inline-block; margin-left: 20px;">-Raman Tensors </em> <br>
<em style="display: inline-block; margin-left: 20px;">-The non-linear optical susceptibility tensor </em> <br>
All information can be downloaded as a JSON file. <br>
</div>"""
)

self.children = [
self.dielectric_results_help,
]

self.rendered = True
19 changes: 7 additions & 12 deletions src/aiidalab_qe_vibroscopy/utils/dielectric/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,23 +59,18 @@ def get_priority_tensor(filtered_node):


def export_dielectric_data(node):
if "vibronic" not in node.outputs:
return None

if not any(
key in node.outputs.vibronic for key in ["iraman", "dielectric", "harmonic"]
):
if not any(key in node for key in ["iraman", "dielectric", "harmonic"]):
return None

else:
if "iraman" in node.outputs.vibronic:
vibrational_data = node.outputs.vibronic.iraman.vibrational_data
if "iraman" in node:
vibrational_data = node.iraman.vibrational_data

elif "harmonic" in node.outputs.vibronic:
vibrational_data = node.outputs.vibronic.harmonic.vibrational_data
elif "harmonic" in node:
vibrational_data = node.harmonic.vibrational_data

elif "dielectric" in node.outputs.vibronic:
tensor_data = node.outputs.vibronic.dielectric
elif "dielectric" in node:
tensor_data = node.dielectric
output_data = get_priority_tensor(tensor_data)
dielectric_tensor = output_data.get_array("dielectric").round(
6
Expand Down
10 changes: 3 additions & 7 deletions src/aiidalab_qe_vibroscopy/utils/euphonic/intensity_maps.py
Original file line number Diff line number Diff line change
Expand Up @@ -759,17 +759,13 @@ def generate_force_constant_instance(


def export_euphonic_data(node, fermi_energy=None):
if "vibronic" not in node.outputs:
# Not a phonon calculation
if "phonon_bands" not in node.outputs:
return None
else:
if "phonon_bands" not in node.outputs.vibronic:
return None

output_set = node.outputs.vibronic.phonon_bands
output_set = node.outputs.phonon_bands

if any(not element for element in node.inputs.structure.pbc):
vibro_bands = node.inputs.vibronic.phonopy_bands_dict.get_dict()
vibro_bands = node.inputs.phonopy_bands_dict.get_dict()
# Group the band and band_labels
band = vibro_bands["band"]
band_labels = vibro_bands["band_labels"]
Expand Down
33 changes: 15 additions & 18 deletions src/aiidalab_qe_vibroscopy/utils/phonons/result.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Bands results view widgets"""

from aiidalab_qe.common.bandpdoswidget import cmap, get_bands_labeling
from aiidalab_qe.common.bands_pdos.utils import _cmap, _get_bands_labeling

import numpy as np
import json
Expand Down Expand Up @@ -34,25 +34,22 @@ def export_phononworkchain_data(node, fermi_energy=None):
}
parameters = {}

if "vibronic" not in node.outputs:
return None

if "phonon_bands" in node.outputs.vibronic:
if "phonon_bands" in node.outputs:
"""
copied and pasted from aiidalab_qe.common.bandsplotwidget.
adapted for phonon outputs
"""

data = json.loads(
node.outputs.vibronic.phonon_bands._exportcontent("json", comments=False)[0]
node.outputs.phonon_bands._exportcontent("json", comments=False)[0]
)
# The fermi energy from band calculation is not robust.
data["fermi_energy"] = 0
data["pathlabels"] = get_bands_labeling(data)
data["pathlabels"] = _get_bands_labeling(data)
replace_symbols_with_uppercase(data["pathlabels"])
data["Y_label"] = "Dispersion (THz)"

bands = node.outputs.vibronic.phonon_bands._get_bandplot_data(
bands = node.outputs.phonon_bands._get_bandplot_data(
cartesian=True, prettify_format=None, join_symbol=None, get_segments=True
)
parameters["energy_range"] = {
Expand All @@ -64,8 +61,8 @@ def export_phononworkchain_data(node, fermi_energy=None):
data["y"] = bands["y"]
full_data["bands"] = [data, parameters]

if "phonon_pdos" in node.outputs.vibronic:
phonopy_calc = node.outputs.vibronic.phonon_pdos.creator
if "phonon_pdos" in node.outputs:
phonopy_calc = node.outputs.phonon_pdos.creator

kwargs = {}
if "settings" in phonopy_calc.inputs:
Expand All @@ -75,7 +72,7 @@ def export_phononworkchain_data(node, fermi_energy=None):
kwargs.update({key: the_settings[key]})

symbols = node.inputs.structure.get_ase().get_chemical_symbols()
pdos = node.outputs.vibronic.phonon_pdos
pdos = node.outputs.phonon_pdos

index_dict, dos_dict = (
{},
Expand Down Expand Up @@ -119,8 +116,8 @@ def export_phononworkchain_data(node, fermi_energy=None):
"label": atom,
"x": pdos.get_x()[1].tolist(),
"y": dos_dict[atom].tolist(),
"borderColor": cmap(atom),
"backgroundColor": cmap(atom),
"borderColor": _cmap(atom),
"backgroundColor": _cmap(atom),
"backgroundAlpha": "40%",
"lineStyle": "solid",
}
Expand All @@ -140,27 +137,27 @@ def export_phononworkchain_data(node, fermi_energy=None):

full_data["pdos"] = [json.loads(json.dumps(data_dict)), parameters, "dos"]

if "phonon_thermo" in node.outputs.vibronic:
if "phonon_thermo" in node.outputs:
(
what,
T,
units_k,
) = node.outputs.vibronic.phonon_thermo.get_x()
) = node.outputs.phonon_thermo.get_x()
(
F_name,
F_data,
units_F,
) = node.outputs.vibronic.phonon_thermo.get_y()[0]
) = node.outputs.phonon_thermo.get_y()[0]
(
Entropy_name,
Entropy_data,
units_entropy,
) = node.outputs.vibronic.phonon_thermo.get_y()[1]
) = node.outputs.phonon_thermo.get_y()[1]
(
Cv_name,
Cv_data,
units_Cv,
) = node.outputs.vibronic.phonon_thermo.get_y()[2]
) = node.outputs.phonon_thermo.get_y()[2]

full_data["thermo"] = (
[T, F_data, units_F, Entropy_data, units_entropy, Cv_data, units_Cv],
Expand Down
15 changes: 6 additions & 9 deletions src/aiidalab_qe_vibroscopy/utils/raman/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,13 @@ def export_iramanworkchain_data(node):
We have multiple choices: IR, RAMAN.
"""

if "vibronic" not in node.outputs:
return None
if "iraman" in node:
output_node = node.iraman
elif "harmonic" in node:
output_node = node.harmonic
else:
if "iraman" in node.outputs.vibronic:
output_node = node.outputs.vibronic.iraman
elif "harmonic" in node.outputs.vibronic:
output_node = node.outputs.vibronic.harmonic
else:
# we have raman and ir only if we run IRamanWorkChain or HarmonicWorkChain
return None
# we have raman and ir only if we run IRamanWorkChain or HarmonicWorkChain
return None

if "vibrational_data" in output_node:
# We enable the possibility to provide both spectra.
Expand Down

0 comments on commit 8ea879c

Please sign in to comment.