# AUTOGENERATED! DO NOT EDIT! File to edit: Widgets.ipynb (unless otherwise specified).
__all__ = ['light_style', 'dark_style', 'get_files_gui', 'get_input_gui', 'read_data', 'click_data', 'tabulate_data',
'save_data', 'color_toggle', 'clear_cache', 'matplotlib_code', 'generate_summary', 'show_app']
# Cell
import os
import json
from time import sleep
# Widgets Imports
from IPython.display import display, Markdown
import ipywidgets as ipw
from ipywidgets import Layout,Label,Button, Box,HBox,VBox
from ipywidgets.embed import embed_minimal_html, dependency_state
# More exports
import numpy as np
import pandas as pd
import plotly.graph_objects as go
import pivotpy.vr_parser as vp
import pivotpy.g_utils as gu
import pivotpy.i_plots as ip
# Cell
light_style = """<style>
.widget-text input {
background-color:white !important;
border-radius:20px !important;
padding: 0px 10px 0px 10px !important;
border: 1px solid #e0e8e8 !important;
color: gray !important;
}
.widget-text input:focus {
border: 1px solid skyblue !important;
}
.widget-text input:hover {
border: 1px solid skyblue !important;
}
.widget-dropdown > select {
background-color: transparent !important;
border:none !important;
border-bottom: 1px solid skyblue !important;
box-shadow: inset 0 -20px 10px -20px skyblue;
}
.widget-dropdown > select:hover {
background-color: white !important;
}
.widget-dropdown > select > option {
color: gray !important;
background-color: #eaf0f0 !important;
}
.widget-dropdown > select > option:focus {
background-color: red !important;
}
.widget-box {
background-color:#eaf0f0 !important;
border-radius:5px !important;
padding:1px !important;
border: 1px solid whitesmoke !important;
box-shadow: 1px 1px 1px 1px gray !important;
}
.p-Collapse {
display: flex;
flex-direction: row;
align-items: stretch;
}
.p-Accordion .p-Collapse + .p-Collapse {
margin-top: 0px;
}
.borderless {
border: 1px solid transparent !important;
box-shadow: none !important;
border-radius: 0px !important;
margin:4px !important;
}
.marginless {
margin: 0px !important;
border-radius: 0px !important;
}
.output {
color: black !important;
background-color:inherit !important;
}
.widget-tab {
background-color:#eaf0f0 !important;
border: 1px solid whitesmoke !important;
box-shadow: 1px 1px 1px 1px gray !important;
padding: 0px 2px 2px 2px !important;
}
.widget-tab-contents, .widget-tab > .widget-tab-contents {
width: 100%;
box-sizing: border-box;
margin: 0px !important;
padding: 0px !important;
flex-grow: 1;
overflow: auto;
background-color:#eaf0f0 !important;
border: none !important;
}
.widget-tab > .p-TabBar .p-TabBar-tab {
background-color:#eaf0f0 !important;
border: none !important;
color: #00aaff !important;
font-weight: bold !important;
font-size: 16px !important;
font-family: "Times","serif" !important;
text-align: center !important;
}
.widget-html, .widget-html-content {
margin: 0 !important;
padding: 2px !important;
}
table { color:black !important;}
tr:nth-child(odd) {background-color: #eaf0f0 !important;}
tr:nth-child(even) {background-color: white !important;}
.widget-button,.widget-toggle-button {
color: black !important;
min-width: max-content !important;
background-color: #c3d4d4;
border-radius: 5px !important;
}
tr:hover{
background-color: #abe4ff !important;
}
</style>"""
dark_style = """<style>
.widget-text input {
background-color:black !important;
border-radius:20px !important;
padding: 0px 10px 0px 10px !important;
border: 1px solid #404040 !important;
color: #abb2bf !important;
}
.widget-text input:focus {
border: 1px solid skyblue !important;
}
.widget-text input:hover {
border: 1px solid skyblue !important;
}
.widget-dropdown > select {
background-color: transparent !important;
border:none !important;
border-bottom: 1px solid skyblue !important;
box-shadow: inset 0 -20px 10px -20px skyblue;
color: white !important;
}
.widget-dropdown > select:hover {
background-color: black !important;
}
.widget-dropdown > select > option {
color: whitesmoke !important;
background-color: black !important;
}
.widget-dropdown > select > option:focus {
background-color: red !important;
}
.widget-label {
color: white !important;
}
.widget-html {
color: white !important;
}
.widget-box {
background-color:#282c34 !important;
border-radius:5px !important;
padding:1px !important;
border: 1px solid black !important;
box-shadow: 1px 1px 1px 1px black !important;
}
.borderless {
border: 1px solid transparent !important;
box-shadow: none !important;
border-radius: 4px !important;
margin:4px !important;
}
.marginless {
margin: 0px !important;
border-radius: 0px !important;
}
.output {
color: white !important;
background-color:inherit !important;
}
.widget-tab {
background-color:black !important;
border: none !important;
box-shadow: 1px 1px 1px 1px gray !important;
padding: 0px 2px 2px 2px !important;
}
.widget-tab-contents, .widget-tab > .widget-tab-contents {
width: 100%;
box-sizing: border-box;
margin: 0px !important;
padding: 0px !important;
flex-grow: 1;
overflow: auto;
border: none !important;
background-color:black !important;
}
.widget-tab > .p-TabBar .p-TabBar-tab {
background-color:black !important;
border: none !important;
color: #00aaff !important;
font-weight: bold !important;
font-size: 16px !important;
font-family: "Times","serif" !important;
text-align: center !important;
}
table { color:white !important;}
tr:nth-child(odd) {background-color: #282c34 !important;}
tr:nth-child(even) {background-color: black !important;}
.widget-button,.widget-toggle-button {
color: whitesmoke !important;
min-width: max-content !important;
background-color: #3f5959;
border-radius: 5px !important;
}
tr:hover{
background-color: #196285 !important;
}
</style>"""
# Cell
[docs]def get_files_gui(auto_fill = 'vasprun.xml',html_style=None,height=320):
"""
- Creates a GUI interface for files/folders filtering.
- **Parmeters**
- auto_fill : Default is `vasprun.xml`, any file/folder.
- html_style : None,`dark_style` or `light_style`.
- height : Height of Grid box.
- **Returns**
- Tuple(GUI_gridbox,Files_Dropdown). Access second one by item itself.
"""
files_w = ipw.Dropdown(continuous_update=False)
pw = ipw.Text(value=os.getcwd())
incldue_w = ipw.Text(value=auto_fill)
excldue_w = ipw.Text()
d_layout = Layout(width='30%')
l_layout = Layout(width='19%')
depth_w = ipw.Dropdown(options=[None,1,2,3,4,5],value=4,layout=d_layout)
item_w = ipw.Dropdown(options=['Both','Files','Folders'],value='Files',layout=d_layout)
item_box = ipw.HBox([ipw.Label('Depth: ',layout=l_layout),depth_w,ipw.Label('Type: ',layout=l_layout),item_w])
item_box.add_class('borderless').add_class('marginless')
applybtn_w = ipw.Button(description='Apply Filters')
applybtn_w.style.button_color = 'skyblue'
gci_output = ipw.Output(layout=Layout(height='{}px'.format(height-70)))
label_head = ipw.HTML("<h3>Your Filtered Files List</h3>")
def filter_gci(applybtn_w):
applybtn_w.description = 'Applying...'
applybtn_w.disabled = True
if os.path.isdir(pw.value):
path = pw.value
else:
with gci_output:
print("Given path does not exists.")
print("Falling back to PWD: {}".format(os.getcwd()))
path = os.getcwd()
pw.value = path
gci = vp.Dict2Data({'children':[],'parent':path})
if 'Files' in item_w.value:
file_type = dict(filesOnly=True)
elif 'Folders' in item_w.value:
file_type = dict(dirsOnly=True)
else:
file_type = {}
try:
gci = gu.get_child_items(path=path, **file_type,
include= incldue_w.value,
exclude= excldue_w.value,
depth=depth_w.value)
except:
with gci_output:
print('Something went wrong')
# Enable before any error occur.
applybtn_w.disabled = False
files_w.options = {name: os.path.join(gci.parent,name) for name in gci.children}
applybtn_w.description = 'Successful!'
applybtn_w.style.button_color = 'green'
label_head.value = "<h3>From: {}</h3>".format(gci.parent)
with gci_output:
display(ipw.HTML("<h4>{} files found.</h4>".format(len(gci.children))))
display(ipw.HTML("<ol>{}<ol>".format(''.join(['<li>{}</li>'.format(i) for i in gci.children]))))
applybtn_w.description = 'Apply Filters'
applybtn_w.style.button_color = 'skyblue'
gci_output.clear_output(wait=True)
applybtn_w.on_click(filter_gci)
out_box = ipw.Box([gci_output])
right_box = ipw.VBox([label_head,out_box])
out_box.add_class('borderless')
right_box.add_class('borderless')
i_layout = Layout(width='99%')
incldue_w.layout = i_layout
excldue_w.layout = i_layout
pw.layout = i_layout
input_box = ipw.VBox([
ipw.Label('Path to Project Folder',layout=i_layout),pw,
ipw.Label('Items to Include (separate by |)',layout=i_layout),incldue_w,
ipw.Label('Items to Exclude (separate by |)',layout=i_layout),excldue_w,
item_box,
applybtn_w],layout=Layout(width='330px'))
if not html_style:
html_style = ''
full_box = ipw.HBox([ipw.HTML(html_style),input_box, right_box],
layout=Layout(height='{}px'.format(height)))
full_box.add_class('borderless')
full_box.add_class('marginless')
return full_box, files_w
# Cell
# Cell
# Reading data
def read_data(tabel_w,poscar=None,sys_info=None):
data_dict = json.loads(tabel_w.value)
if sys_info != None:
data_dict["sys"] = sys_info.SYSTEM
if poscar != None:
data_dict["V"] = np.round(poscar.volume,5)
a,b,c = np.round(np.linalg.norm(poscar.basis,axis=1),5)
data_dict["a"] = a
data_dict["b"] = b
data_dict["c"] = c
tabel_w.value = json.dumps(data_dict)
return data_dict # for reading in save_data
#mouse event handler
def click_data(sel_en_w,fermi_w,tabel_w,fig):
def handle_click(trace, points, state):
if(points.ys!=[]):
data_dict = json.loads(tabel_w.value)
e_fermi = (float(fermi_w.value) if fermi_w.value else 0)
val=np.round(float(points.ys[0])+e_fermi,4)
for key in sel_en_w.options:
if key in sel_en_w.value and key != 'None':
data_dict[key] = val # Assign value back
if 'Fermi' in sel_en_w.value:
fermi_w.value = str(val) # change fermi
tabel_w.value = json.dumps(data_dict,indent=1)
#data_send(None) #send data to Table
for i in range(len(fig.data)):
trace=fig.data[i]
trace.on_click(handle_click)
# Display Table
def tabulate_data(data_dict):
ls,ds,ud = [],[],{}
for k,v in data_dict.items():
if v and k not in ['Fermi','E_gap','Δ_SO','sys']:
if k not in ['so_max','so_min']: # No need to show in table, but difference required.
ls.append(k)
ds.append(v)
if v and 'VBM' in k and data_dict['CBM']:
ls.append('E_gap')
ds.append(np.round(data_dict['CBM']-v,5))
ud.update({'E_gap':ds[-1]})
if v and 'so_min' in k and data_dict['so_max']:
ls.append('Δ_SO')
ds.append(np.round(data_dict['so_max']-v,5))
ud.update({'Δ_SO':ds[-1]})
data_dict = {**data_dict,**ud}
if len(ls) % 2 != 0:
ls.append('')
ds.append('')
tab_data = [ls[:int(len(ls)/2)],ds[:int(len(ls)/2)],ls[int(len(ls)/2):],ds[int(len(ls)/2):]]
htm_string = """<style>table {border-collapse: collapse !important;
min-width: 100% !important;
border: 1px solid gray !important;
margin: 1px 1px 1px 1px !important;
font-size: small !important;
font-family: "Times New Roman", "Times", "serif" !important;}
th, td {text-align: center !important;
border: 1px solid gray !important;
padding: 0px 8px 0px 8px !important;}
tr {width: 100% !important;}
tr:nth-child(odd) {font-weight:bold !important;}
</style>"""
htm_string += "<table><tr>{}</tr></table>".format( '</tr><tr>'.join(
'<td>{}</td>'.format('</td><td>'.join(str(_) for _ in row)) for row in tab_data) )
return htm_string, data_dict
# Send Data
def save_data(out_w1,data_dict):
out_f = os.path.join(os.path.split(out_w1.value)[0],'result.json')
vp.dump_dict(data_dict,dump_to='json',outfile=out_f)
# Cell
def color_toggle(tog_w,fig,rd_btn):
if tog_w.description=='Colorize':
tog_w.description='Monochrome'
with fig.batch_animate():
if rd_btn.value == 'DOS':
for trace in fig.data:
trace.fill='tozeroy'
else:
for trace in fig.data[:1]:
trace.mode='markers+lines'
trace.line.color='rgba(222,222,220,0.1)'
else:
tog_w.description='Colorize'
with fig.batch_animate():
if rd_btn.value == 'DOS':
for trace in fig.data:
trace.fill=None
else:
for trace in fig.data[:1]:
trace.mode='lines'
trace.line.width=1.5
trace.line.color='skyblue'
# Cell
def clear_cache(out_w1,cache_w,tabel_w):
pwd = os.path.split(out_w1.value)[0]
if 'Table' in cache_w.value:
j_s = json.loads(tabel_w.value)
# Avoid deleting V,a,b,Fermi
for k in ['VBM','CBM','so_max','so_min']:
j_s[k] = ''
tabel_w.value = json.dumps(j_s)
if 'PWD' in cache_w.value:
try:
os.remove(os.path.join(pwd,'sys_info.pickle'))
os.remove(os.path.join(pwd,'vasprun.pickle'))
except: pass
if 'All' in cache_w.value:
for key,value in out_w1.options.items():
p_throw = os.path.split(out_w1.value)[0]
try:
os.remove(os.path.join(p_throw,'vasprun.pickle'))
os.remove(os.path.join(p_throw,'sys_info.pickle'))
except: pass
# Cell
def matplotlib_code(rd_btn,out_w1,dict_html):
if out_w1.value:
path = out_w1.value.replace('\\','/')
else:
path=''
if 'DOS' in rd_btn.value:
command = 'pp.quick_dos_lines'
else:
command = 'pp.quick_rgb_lines'
string = "import matplotlib.pyplot as plt, pivotpy as pp"
string += "\npath = '{}'\nargs_dict = {}\nax = pp.init_figure()".format(path,json.loads(dict_html.value))
string += "\n{}(path_evr=path,ax=ax,**args_dict)".format(command)
return string
# Cell
def generate_summary(paths_list=None):
# Make Data Frame
result_paths = []
common_prefix = '' #placeholder
if paths_list:
common_prefix = os.path.commonprefix(paths_list)
for item in paths_list:
if item and os.path.isdir(item):
result_paths.append(os.path.join(item,'result.json'))
elif item and os.path.isfile(item):
result_paths.append(os.path.join(os.path.split(item)[0],'result.json'))
result_dicts = []
for path in result_paths:
try: _p_ = os.path.split(path)[0].split(common_prefix)[1]
except: _p_ = '' #In current directory
try:
f = open(path,'r')
l_d = json.load(f)
l_d.update({'rel_path':_p_})
result_dicts.append(l_d)
f.close()
except: pass
out_dict = {} # placeholder
if result_dicts:
out_dict.update({k:[v] if v else np.nan for k,v in result_dicts[0].items()})
for i,d in enumerate(result_dicts):
if i != 0:
for k,v in d.items():
v = np.nan if not v else v
try: out_dict[k].append(v)
except:
out_dict.update({k:[np.nan for l in range(i)]}) #if not key before, add to all previous
out_dict[k].append(v) # Then append for current value
# If next dictionary does not have key
for k in out_dict.keys():
if k not in d.keys():
out_dict[k].append(np.nan)
try: out_dict.pop('Fermi',None) # Remove Fermi as not necessary
except: pass
df = pd.DataFrame(out_dict)
if common_prefix:
return df.style.set_caption("Root Path: {}".format(common_prefix)) # return with header
return df #return simple
# Cell
[docs]def show_app(height=600):
"""
Displays a GUI for visulaizing and manipulating output of vasp calculations. It only has one argument `height` which sets `min-height` of the app.
"""
tab = ipw.Tab(layout=Layout(min_height='{}px'.format(height),max_height='100vh',min_width='700px',max_width='100vw')
).add_class('marginless').add_class('borderless') # Main Tab
for i,item in enumerate(['Home','Graphs','STD(out/err)']):
tab.set_title(i,item)
l_btn = Layout(width='max-content') # For button
out_tab = ipw.Output()
out_tab.add_class('output')
gui1,out_w1 = get_files_gui()
load_btn = ipw.Button(description='Load Data',layout=l_btn)
graph_btn = ipw.Button(description='Load Graph',layout=l_btn)
rd_btn = ipw.Dropdown(options=['Bands','DOS'],value='Bands',layout= Layout(width='80px'))
tabel_w = ipw.HTML(json.dumps({'sys':'','V':'','a':'','b':'','c':'','Fermi': None,
'VBM':'','CBM':'','so_max':'','so_min':''}))
l_out = Layout(width='20%')
b_out = Layout(width='30%')
# RGB extra input
kticks_w = ipw.Text(value='',layout=b_out)
ktickv_w = ipw.Text(value='',layout=b_out)
kjoin_w = ipw.Text(value='',layout=b_out)
elim_w = ipw.Text(value='',layout=b_out)
sel_en_w = ipw.Dropdown(options=['Fermi','VBM','CBM','so_max','so_min','None'],value='None',layout=b_out)
fermi_w = ipw.Text(value='',layout=b_out)
theme_w = ipw.Dropdown(options=['Default','Light','Dark'],value='Light',layout=l_btn)
theme_html = ipw.HTML(light_style) # To change theme.
dict_html = ipw.HTML(json.dumps({})) # To store Fig args dictionary
view_tab_w = ipw.HTML()
@out_tab.capture(clear_output=True,wait=True)
def update_table(change):
data_dict = json.loads(tabel_w.value)
htm_string,data_dict = tabulate_data(data_dict)
view_tab_w.value = htm_string
save_data(out_w1,data_dict) # save data as well.
tabel_w.observe(update_table,'value')
# Also update when folder chnages for fast view
if rd_btn.value == 'DOS':
gui2,out_w2 = get_input_gui(rgb=False,height=None)
else:
gui2,out_w2 = get_input_gui(height=None)
# Load any previous computed result just by going into folder.
@out_tab.capture(clear_output=True,wait=True)
def load_previous(change):
try:
path = os.path.split(out_w1.value)[0]
r_f = os.path.join(path,'result.json')
with open(r_f,'r') as f:
tabel_w.value = '\n'.join(f.readlines())
f.close()
print('Previous Analysis loaded in Table for {}'.format(out_w1.value))
except:
print('Previous Analysis does not exist for {}'.format(out_w1.value))
tabel_w.value = json.dumps({'sys':'','V':'','a':'','b':'','c':'','Fermi': None,
'VBM':'','CBM':'','so_max':'','so_min':''})
out_w1.observe(load_previous,'value')
# Load Data on button click only
@out_tab.capture(clear_output=True,wait=True)
def on_load(btn):
tab.selected_index = 2
load_btn.description='Loading ...'
try:
path = os.path.split(out_w1.value)[0]
r_f = os.path.join(path,'result.json')
with open(r_f,'r') as f:
tabel_w.value = '\n'.join(f.readlines())
f.close()
file = os.path.join(path,'sys_info.pickle')
sys_info = vp.load_from_dump(file)
print('Cache Loaded')
except:
files = [os.path.join(os.path.split(out_w1.value)[0],f)
for f in ['Bands.txt','Projection.txt','SysInfo.py']]
logic = [os.path.isfile(f) for f in files]
if False in logic:
print('Loading from Python ...')
evr = vp.export_vasprun(out_w1.value)
print('Caching From: {}'.format(out_w1.value)) #Cache result
ifile = os.path.join(os.path.split(out_w1.value)[0],'sys_info.pickle')
vfile = os.path.join(os.path.split(out_w1.value)[0],'vasprun.pickle')
vp.dump_dict(evr.sys_info,outfile=ifile)
vp.dump_dict(evr,outfile=vfile)
else:
print('Loading from Powershell (No Cache Required)...')
evr = vp.load_export(out_w1.value)
sys_info = evr.sys_info # required here.
_rrdd_ = read_data(tabel_w,evr.poscar,sys_info) # Update Table data on load
print('Done')
tab.selected_index = 1
if rd_btn.value=='DOS':
tmp_ui,__ = get_input_gui(rgb=False,sys_info=sys_info,height=None)
else:
tmp_ui,__ = get_input_gui(rgb=True,sys_info=sys_info,height=None)
gui2.children = tmp_ui.children
__.value = out_w2.value # keep values
ipw.dlink((__,'value'),(out_w2,'value'))
load_btn.description='Load Data'
load_btn.on_click(on_load)
# Figure
fig = go.FigureWidget()
fig.update_layout(autosize=True)
xyt_w = ipw.Text()
@out_tab.capture(clear_output=True,wait=True)
def update_xyt(change):
if xyt_w.value:
xyt_text = xyt_w.value.split(',')
try:
fig.update_xaxes(title=xyt_text[0])
fig.update_yaxes(title=xyt_text[1])
fig.update_layout(title=xyt_text[2])
except: pass #do nothing else
xyt_w.observe(update_xyt,'value')
edit_box = HBox([Label('X,Y,Title:'),xyt_w]).add_class('borderless')
# Monochrome/ Colorize
tog_w=ipw.Button(description='Monochrome',button_style='primary',layout=l_btn)
@out_tab.capture(clear_output=True,wait=True)
def tog_b(tog_w):
color_toggle(tog_w,fig,rd_btn)
tog_w.on_click(tog_b)
# Save Offline
save_fig_w = ipw.Button(description='Save Fig',icon='fa-download',layout=l_btn)
@out_tab.capture(clear_output=True,wait=True)
def save_connected(btn):
s_p = os.path.split(out_w1.value)[0]
filename = os.path.join(s_p,'ConnectedFig.html')
views = VBox([theme_html,fig,view_tab_w],layout=Layout(width='500px',height='490px')).add_class('borderless')
embed_minimal_html(filename, views=[views], state=dependency_state([views]))
save_fig_w.on_click(save_connected)
fig_otions = HBox([Label('Options:'),save_fig_w,tog_w]).add_class('marginless')
# Habdle cache
cache_w = ipw.Dropdown(options=['Table Data','PWD Cache','All Cache','None'],value='None',layout=b_out)
confirm_btn = ipw.Button(description='Confirm Delete',button_style='danger',layout=l_btn)
@out_tab.capture(clear_output=True,wait=True)
def deleter(btn):
confirm_btn.description = 'Deleting ...'
if out_w1.value:
print('Deleting Selected Cache...')
clear_cache(out_w1,cache_w,tabel_w)
print('Done')
confirm_btn.description='Confirm Delete'
confirm_btn.on_click(deleter)
mpl_btn = ipw.Button(description='Grenerate Matplotib Code',layout=l_btn)
@out_tab.capture(clear_output=True,wait=True)
def mpl_code(btn):
tab.selected_index = 2
display(ipw.HTML("<h3>Copy code below and run</h3>"))
mpl_btn.description = 'Generating...'
string = matplotlib_code(rd_btn,out_w1,dict_html)
display(Markdown("```python\n{}\n```".format(string)))
mpl_btn.description = 'See STD(out/err) Tab'
mpl_btn.style.button_color = '#FFDAB9'
sleep(2)
mpl_btn.description = 'Grenerate Matplotib Code'
mpl_btn.style.button_color = 'skyblue'
mpl_btn.on_click(mpl_code)
#Summary generator
summary_btn = ipw.Button(description='Project Summary',layout=l_btn)
@out_tab.capture(clear_output=True,wait=True)
def df_out(btn):
tab.selected_index = 2
summary_btn.description = 'See STD(out/err) Tab'
paths = [v for k,v in out_w1.options.items()]
df = generate_summary(paths_list=paths)
display(df)
print('Generate above dataframe by code below:')
print('_______________________________________')
_code = "import pivotpy as pp\npaths = ['{}']\ndf = pp.generate_summary(paths_list=paths)\ndf".format(
"',\n '".join([str(p).replace('\\','/') for p in paths]))
_code += "\n#ax = pp.init_figure()\n#df.plot(ax=ax,x='sys',y=['V','a'])"
display(Markdown("```python\n{}\n```".format(_code)))
summary_btn.description = 'Project Summary'
summary_btn.on_click(df_out)
summary_box = HBox([summary_btn,mpl_btn]).add_class('marginless')
cache_box = HBox([Label('Delete Cache:'),cache_w,confirm_btn]).add_class('marginless')
style_w = ipw.Dropdown(options=["plotly", "plotly_white", "plotly_dark", "ggplot2", "seaborn", "simple_white", "none"],layout=l_btn)
def update_style(change):
fig.update_layout(template=style_w.value)
style_w.observe(update_style,'value')
points_box = HBox([Box([Label('E Type:',layout=l_out),sel_en_w,Label('E-Fermi:',layout=l_out),fermi_w
]).add_class('marginless').add_class('borderless'),graph_btn
],layout=Layout(width='100%')).add_class('marginless')
in_box = VBox([gui2]).add_class('marginless').add_class('borderless')
top_right = HBox([graph_btn,Label('Style:'),style_w,Label('Theme:'),theme_w
]).add_class('marginless')
fig_box = Box([fig],layout=Layout(min_height='380px')).add_class('marginless')
right_box = VBox([
top_right,fig_box
],layout=Layout(min_width='60%')).add_class('marginless').add_class('borderless')
def update_theme(change):
if 'Dark' in theme_w.value:
style_w.value = 'plotly_dark'
theme_html.value = dark_style
elif 'Light' in theme_w.value:
style_w.value = 'ggplot2'
theme_html.value = light_style
else:
style_w.value = 'plotly'
theme_html.value = ''
theme_w.observe(update_theme,'value')
def update_box(change):
if rd_btn.value == 'Bands':
childs = [gui2,VBox([
HBox([Label('Ticks At: ',layout=l_out),kticks_w,Label('Labels: ',layout=l_out),ktickv_w
]).add_class('borderless').add_class('marginless'),
HBox([Label('Join At: ',layout=l_out),kjoin_w,Label('E Range: ',layout=l_out),elim_w
]).add_class('marginless').add_class('borderless')
]).add_class('marginless')]
right_box.children = [top_right,fig_box,points_box,view_tab_w]
else:
childs = [gui2,HBox([Label('E Range:',layout=l_out),elim_w,Label('E-Fermi:',layout=l_out),fermi_w
]).add_class('marginless')]
right_box.children = [top_right,fig_box,view_tab_w]
sel_en_w.value = 'None' # no scatter collection in DOS.
in_box.children = childs
_ = update_box(0) # initialize box
rd_btn.observe(update_box,'value')
upper_box = VBox([
HBox([Label('File:',layout=Layout(width='50px')),out_w1
]).add_class('borderless').add_class('marginless'),
HBox([Label('View:',layout=Layout(width='50px')),rd_btn,load_btn
]).add_class('borderless').add_class('marginless')
]).add_class('marginless').add_class('borderless')
left_box = VBox([upper_box,in_box,edit_box,fig_otions, cache_box,summary_box],layout=Layout(max_width='40%')).add_class('marginless').add_class('borderless')
# Garph
@out_tab.capture(clear_output=True,wait=True)
def update_graph(btn):
tab.selected_index = 2
if out_w2.value:
fig.data = []
try:
graph_btn.description = 'loading pickle...'
print('Trying to Load Cache for Graph ...')
file = os.path.join(os.path.split(out_w1.value)[0],'vasprun.pickle')
graph_btn.description = file
evr = vp.load_from_dump(file)
except:
graph_btn.description = 'loading export...'
print('No cache found. Loading from file {} ...'.format(out_w1.value))
files = [os.path.join(os.path.split(out_w1.value)[0],f)
for f in ['Bands.txt','Projection.txt','SysInfo.py']]
logic = [os.path.isfile(f) for f in files]
if False in logic:
print('Loading from Python ...')
evr = vp.export_vasprun(out_w1.value)
else:
print('Loading from Powershell ...')
evr = vp.load_export(out_w1.value)
print('Done')
graph_btn.description = 'Load Graph'
_rrdd_ = read_data(tabel_w,evr.poscar,evr.sys_info) # Update Table data
if not fermi_w.value: #Read Only if not in box.
fermi_w.value = str(evr.sys_info.E_Fermi) # E_Fermi
# Args of Graph function
argdict = json.loads(out_w2.value)
argdict.update({'E_Fermi':(float(fermi_w.value) if fermi_w.value else None)})
argdict.update({'elim':([float(v) for v in elim_w.value.split(',')] if elim_w.value else None)})
if rd_btn.value == 'Bands':
argdict.update({'joinPathAt':([int(v) for v in kjoin_w.value.split(',')]
if kjoin_w.value else None)})
argdict.update({'xt_indices':([int(v) for v in kticks_w.value.split(',')]
if kticks_w.value else [0,-1])})
argdict.update({'xt_labels':([v for v in ktickv_w.value.split(',')]
if ktickv_w.value else ['A','B'])})
fig_data = ip.plotly_rgb_lines(path_evr=evr,**argdict)
else:
fig_data = ip.plotly_dos_lines(path_evr=evr,**argdict)
tab.selected_index = 1
with fig.batch_animate():
for d in fig_data.data:
fig.add_trace(d)
fig.layout = fig_data.layout
fig.update_layout(template=style_w.value) # Also here
dict_html.value = json.dumps(argdict) # Save for later generation.
click_data(sel_en_w,fermi_w,tabel_w,fig)
# end of function
graph_btn.on_click(update_graph)
# Display few good things in output.
@out_tab.capture(clear_output=True,wait=True)
def show_args(change):
if out_w1.value:
print("path = '{}'".format(out_w1.value))
_str_out = "args_dict = dict("
for k,v in json.loads(dict_html.value).items():
_str_out += "\n {} = {},".format(k,v)
print(_str_out,"\n )")
dict_html.observe(show_args,'value') # change takes place after graph update
# Open fig in large window
expand_w = ipw.Button(icon = "fa-expand",layout=l_btn)
top_right.children = [*top_right.children,expand_w]
@out_tab.capture(clear_output=True,wait=True)
def expand_fig(btn):
tab.selected_index = 2
sel_en_w.value = 'None'
display(fig)
expand_w.on_click(expand_fig)
style_w.value='plotly' # to trigger callback and resize graph
intro_html = ipw.HTML("<h2>Pivotpy</h2><p>Filter files here and switch tab to Graphs. You can create cache ahead of time to load quickly while working. If anything does not seem to work, see the error in STD(out/err) tab. For large files, do `Export-VR(or Vasprun)` in Powershell to access fast.</p><marquee style='color:red'>Pivotpy GUI based on ipywidgets!</marquee>")
header_box = HBox([intro_html,Label('Theme:',layout=Layout(width='80px')),theme_w
]).add_class('marginless').add_class('borderless')
summary_gui = HBox([Label(),summary_btn]).add_class('borderless')
intro_box = VBox([header_box,gui1,summary_gui]).add_class('marginless').add_class('borderless').add_class('marginless')
tab.children = [intro_box,
HBox([theme_html,
left_box,
right_box
]).add_class('marginless').add_class('borderless'),
VBox([HBox([
ipw.HTML('<h2>Errors/Generted Code is Captured Here</h2>',layout=Layout(width='85%')),
Label('Theme:',layout=Layout(width='50px')),
theme_w
]).add_class('marginless').add_class('borderless'),
out_tab
]).add_class('marginless').add_class('borderless')
]
return tab