Source code for abipy.panels.electrons

""""
AbiPy panels for electronic properties.
"""
from __future__ import annotations

import param
import panel as pn
import panel.widgets as pnw

from abipy.panels.core import AbipyParameterized, ActiveBar, Loading, ply, mpl, depends_on_btn_click


[docs] class CompareEbandsWithMP(AbipyParameterized): with_gaps = param.Boolean(True) ylims_ev = param.Range(default=(-10, +10), doc="Energy window around the Fermi energy.") info_str = """ This app alllows users to upload two files with KS energies. """ def __init__(self, **params): super().__init__(**params) help_md = pn.pane.Markdown(f""" ## Description {self.info_str} """) self.main_area = pn.Column(help_md, self.get_alert_data_transfer(), sizing_mode="stretch_width") self.replot_btn = pnw.Button(name="Replot", button_type='primary') self.file_input = pnw.FileInput(height=60, css_classes=["pnx-file-upload-area"]) self.file_input.param.watch(self.on_file_input, "value") self.mp_progress = pn.indicators.Progress(name='Fetching data from the MP website', bar_color="warning", active=False, width=200, height=10, align="center")
[docs] def on_file_input(self, event): self.abinit_ebands = self.get_ebands_from_file_input(self.file_input) # Match Abinit structure with MP mp = self.abinit_ebands.structure.mp_match() if not mp.structures: raise RuntimeError("No structure found in the MP database") # Get structures from MP as AbiPy ElectronBands. from abipy.electrons.ebands import ElectronBands self.mp_ebands_list = [] with ActiveBar(self.mp_progress): for mp_id in mp.ids: if mp_id == "this": continue eb = ElectronBands.from_mpid(mp_id) self.mp_ebands_list.append(eb) self.update_main()
[docs] def update_main(self): with Loading(self.main_area): col = self.pws_col(["## Plot options", "with_gaps", "ylims_ev", "replot_btn"]) ca = col.append ca("## Abinit Electronic band structure:") ylims = self.ylims_ev ca(ply(self.abinit_ebands.plotly(e0="fermie", ylims=ylims, with_gaps=self.with_gaps, show=False))) for mp_ebands in self.mp_ebands_list: ca("## MP Electronic band structure:") ca(ply(mp_ebands.plotly(e0="fermie", ylims=ylims, with_gaps=self.with_gaps, show=False))) #self.main_area.objects = [col] self.main_area.objects = col.objects
[docs] @depends_on_btn_click('replot_btn') def on_replot_btn(self): self.update_main()
[docs] def get_panel(self): col = pn.Column( "## Upload a *nc* file with energies along a **k**-path (possibly a *GSR.nc* file):", self.get_fileinput_section(self.file_input), pn.Row("## Fetching data from the MP website: ", self.mp_progress, sizing_mode="stretch_width"), sizing_mode="stretch_width") main = pn.Column(col, self.main_area, sizing_mode="stretch_width") cls, kwds = self.get_abinit_template_cls_kwds() return cls(main=main, title="Compare with MP Ebands", **kwds)
[docs] class SkwPanelWithFileInput(AbipyParameterized): lpratio = param.Integer(default=5, bounds=(1, None), doc="Ratio between number of k-points and number of star-functions") info_str = """ This app allows users to upload two files with KS energies. The first file contains the energies in the IBZ used for the SKW interpolation (NB: this file is required). The second (optional) file contains the energies along a k-path. The interpolated energies are then compared with the ab-initio ones on the k-path. The user can change the SKW intepolation parameters to gauge the quality of the SKW fit. """ def __init__(self, **params): super().__init__(**params) help_md = pn.pane.Markdown(f""" ## Description {self.info_str} """) self.main_area = pn.Column(help_md, self.get_alert_data_transfer(), sizing_mode="stretch_width") self.ibz_file_input = pnw.FileInput(height=60, css_classes=["pnx-file-upload-area"]) self.ibz_file_input.param.watch(self.on_ibz_file_input, "value") self.ebands_ibz = None self.kpath_file_input = pnw.FileInput(height=60, css_classes=["pnx-file-upload-area"]) self.kpath_file_input.param.watch(self.on_kpath_file_input, "value") self.ebands_kpath = None
[docs] def on_ibz_file_input(self, event): self.ebands_ibz = self.get_ebands_from_file_input(self.ibz_file_input) self.update_main_area()
[docs] def on_kpath_file_input(self, event): self.ebands_kpath = self.get_ebands_from_file_input(self.kpath_file_input) self.update_main_area()
[docs] def update_main_area(self) -> None: with Loading(self.main_area): if self.ebands_kpath is None or self.ebands_ibz is None: return # SKW interpolation r = self.ebands_ibz.interpolate(lpratio=self.lpratio, filter_params=None) # Build plotter. plotter = self.ebands_kpath.get_plotter_with("Ab-initio", "SKW interp", r.ebands_kpath) mpl_pane = mpl(plotter.combiplot(**self.mpl_kwargs)) col = pn.Column(mpl_pane, sizing_mode="stretch_width") self.main_area.objects = [col]
[docs] def get_panel(self): col = pn.Column( "## Upload (or drag & drop) any *nc* file with energies in the IBZ (_possibly a *GSR.nc* file_):", self.get_fileinput_section(self.ibz_file_input), "## Upload (or drag & drop) any *nc* file with energies along a **k**-path (_possibly a *GSR.nc* file_):", self.get_fileinput_section(self.kpath_file_input), sizing_mode="stretch_width") main = pn.Column(col, self.main_area, sizing_mode="stretch_width") cls, kwds = self.get_abinit_template_cls_kwds() return cls(main=main, title="SKW Analyzer", **kwds)