Source code for pivotpy.widgets

# 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
[docs]def get_input_gui(rgb=True,sys_info=None,html_style=None,height=400): """ - Creates a GUI interface for input/selection of orbitals/ions projection. - **Parmeters** - rgb : Default is `True` and generates input for `plotly(quick)_rgb_lines`, if `False` creates input for `quick(plotly)_dos(color)_lines` - html_style : None,`dark_style` or `light_style`. - height : Height of Grid box. - **Returns** - Tuple(GUI_gridbox,json_in_HTML). Access second one by item.value. """ if not html_style: html_style = '' if sys_info ==None: sys_info = vp.Dict2Data({'fields':['s'],'ElemIndex':[0,1],'ElemName':['A']}) layout = Layout(width='30%') orbs_w = ipw.Dropdown(options={'s':0},value=0,layout=layout) orbi_w = ipw.Text(layout=layout) ions_w = ipw.Dropdown(options={'All':[0,1,1]},value=[0,1,1],layout=layout) ioni_w = ipw.Text(layout=layout) label_w = ipw.Text(layout=layout) rgb_w = ipw.Dropdown(options={'Red':0,'Green':1,'Blue':2},value=0,layout=layout) rgbl_w = Label('Color: ') click_w= ipw.Button(layout=Layout(width='max-content'),icon='fa-hand-o-up') click_w.style.button_color='skyblue' # Uniform label widths l_width = Layout(width='20%') rgbl_w.layout=l_width inpro_w = ipw.HTML(layout=Layout(height='20px')) if not rgb: layout = Layout(width='32px') add_w = ipw.Button(description='',layout=layout,icon='fa-plus-circle') del_w = ipw.Button(description='',layout=layout,icon='fa-minus-circle') add_w.style.button_color='#5AD5D1' del_w.style.button_color='#5AD5D1' read_box = [Label(u"Line \u00B1: "),add_w,del_w,Label(),Label(),click_w] else: read_box = [click_w] in_w = VBox([ipw.HTML(html_style), ipw.HTML("<h3>Projections</h3>"), HBox([rgbl_w,rgb_w,Label('Label: ',layout=l_width),label_w ]).add_class('borderless').add_class('marginless'), HBox([Label('Ions: ',layout=l_width),ions_w,Label('::>>:: ',layout=l_width),ioni_w ]).add_class('borderless').add_class('marginless'), HBox([Label('Orbs: ',layout=l_width),orbs_w,Label('::>>:: ',layout=l_width),orbi_w ]).add_class('borderless').add_class('marginless'), HBox(read_box).add_class('borderless').add_class('marginless') ],layout=Layout(height="{}px".format(height)) ).add_class('marginless') orbs_w.options= {str(i)+': '+item:str(i) for i,item in enumerate(sys_info.fields)} ipw.dlink((orbs_w,'value'), (orbi_w,'value')) inds = sys_info.ElemIndex ions_w.options = {"{}-{}: {}".format(inds[i],inds[i+1]-1,item):"{}-{}".format(inds[i],inds[i+1]-1) for i,item in enumerate(sys_info.ElemName)} ipw.dlink((ions_w,'value'), (ioni_w,'value')) def read_pro(ions_w,orbi_w,label_w): orbs_l = [] if orbi_w.value: for o in orbi_w.value.split(","): if '-' in o: strt,stop = o.split("-") [orbs_l.append(i) for i in range(int(strt),int(stop)+1)] else: orbs_l.append(int(o)) ions_l = [] if ioni_w.value: for o in ioni_w.value.split(","): if '-' in o: strt,stop = o.split("-") [ions_l.append(i) for i in range(int(strt),int(stop)+1)] else: ions_l.append(int(o)) if label_w.value: label_l = label_w.value else: label_l = "{}:{}".format(ioni_w.value,orbi_w.value) return ions_l,orbs_l,label_l if rgb: elements,orbs,labels = [[],[],[]],[[],[],[]],['','',''] else: rgb_w.options = {"Line 0":0} rgb_w.value = 0 rgbl_w.value = 'Line: ' elements,orbs, labels = [[],],[[],],['',] # For DOS def read_lines(click_w): # Read Now index=rgb_w.value r_p = read_pro(ions_w,orbi_w,label_w) # update try: elements[index] = r_p[0] orbs[index] = r_p[1] labels[index] = r_p[2] except: elements.append(r_p[0]) # In case new line added. orbs.append(r_p[1]) labels.append(r_p[2]) max_ind = len(rgb_w.options) # in case a line is deleted. _input_ = dict(elements=elements[:max_ind],orbs=orbs[:max_ind],labels=labels[:max_ind]) inpro_w.value = json.dumps(_input_,indent=2) # Button feedback. click_w.description = "Got {}".format(rgb_w.label) click_w.style.button_color = '#FFDAB9' click_w.icon = 'check' sleep(1) click_w.description = "Read Input" click_w.style.button_color = 'skyblue' click_w.icon = 'fa-hand-o-up' click_w.on_click(read_lines) # Observe output of a line right in box. def see_input(change): #if change: x = rgb_w.value try: #Avoid None and prior update ioni_w.value = ','.join([str(i) for i in elements[x]]) orbi_w.value = ','.join([str(i) for i in orbs[x]]) label_w.value = labels[x] click_w.description = "{}".format(rgb_w.label) # Triggers when line +/- as well. click_w.style.button_color = '#FFDAB9' click_w.icon = 'fa-refresh' except: pass rgb_w.observe(see_input,'value') # Add and delete lines if not rgb: def add_line(add_w): l_opts = len(rgb_w.options)+1 opts = {'Line {}'.format(i):i for i in range(l_opts)} rgb_w.options = opts rgb_w.value = l_opts - 1 add_w.on_click(add_line) def del_line(del_w): l_opts = len(rgb_w.options)-1 if l_opts > 0: # Do not delete last line. just update,otherwise issues. opts = {'Line {}'.format(i):i for i in range(l_opts)} rgb_w.options = opts rgb_w.value = l_opts - 1 del_w.on_click(del_line) # Finally Link Line number to input button ipw.dlink((rgb_w,'label'),(click_w,'description')) # Link line to input buuton. click_w.description='Read Input' # After link is important return in_w, inpro_w
# 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