ipyvasp 0.8.6__tar.gz → 0.8.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/PKG-INFO +2 -2
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/README.md +1 -1
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp/_lattice.py +50 -40
- ipyvasp-0.8.8/ipyvasp/_version.py +1 -0
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp/core/plot_toolkit.py +6 -2
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp/lattice.py +91 -71
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp.egg-info/PKG-INFO +2 -2
- ipyvasp-0.8.6/ipyvasp/_version.py +0 -1
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/LICENSE +0 -0
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp/__init__.py +0 -0
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp/__main__.py +0 -0
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp/_enplots.py +0 -0
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp/bsdos.py +0 -0
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp/cli.py +0 -0
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp/core/__init__.py +0 -0
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp/core/parser.py +0 -0
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp/core/serializer.py +0 -0
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp/core/spatial_toolkit.py +0 -0
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp/evals_dataframe.py +0 -0
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp/misc.py +0 -0
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp/potential.py +0 -0
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp/utils.py +0 -0
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp/widgets.py +0 -0
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp.egg-info/SOURCES.txt +0 -0
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp.egg-info/dependency_links.txt +0 -0
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp.egg-info/entry_points.txt +0 -0
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp.egg-info/requires.txt +0 -0
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/ipyvasp.egg-info/top_level.txt +0 -0
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/setup.cfg +0 -0
- {ipyvasp-0.8.6 → ipyvasp-0.8.8}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ipyvasp
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.8
|
|
4
4
|
Summary: A processing tool for VASP DFT input/output processing in Jupyter Notebook.
|
|
5
5
|
Home-page: https://github.com/massgh/ipyvasp
|
|
6
6
|
Author: Abdul Saboor
|
|
@@ -68,7 +68,7 @@ Interactively select bandstructure path by clicking on high symmetry points on p
|
|
|
68
68
|
|
|
69
69
|

|
|
70
70
|
|
|
71
|
-
Apply operations on POSCAR and simultaneously view using plotly's `FigureWidget`
|
|
71
|
+
Apply operations on POSCAR and simultaneously view using plotly's `FigureWidget` in Jupyterlab side by side.
|
|
72
72
|
|
|
73
73
|

|
|
74
74
|
|
|
@@ -36,7 +36,7 @@ Interactively select bandstructure path by clicking on high symmetry points on p
|
|
|
36
36
|
|
|
37
37
|

|
|
38
38
|
|
|
39
|
-
Apply operations on POSCAR and simultaneously view using plotly's `FigureWidget`
|
|
39
|
+
Apply operations on POSCAR and simultaneously view using plotly's `FigureWidget` in Jupyterlab side by side.
|
|
40
40
|
|
|
41
41
|

|
|
42
42
|
|
|
@@ -15,7 +15,7 @@ from matplotlib.collections import LineCollection
|
|
|
15
15
|
from mpl_toolkits.mplot3d.art3d import Poly3DCollection, Line3DCollection
|
|
16
16
|
import matplotlib.colors as mplc
|
|
17
17
|
|
|
18
|
-
from ipywidgets import interactive
|
|
18
|
+
from ipywidgets import interactive, IntSlider
|
|
19
19
|
|
|
20
20
|
# Inside packages import
|
|
21
21
|
from .core import plot_toolkit as ptk
|
|
@@ -1635,13 +1635,13 @@ def filter_sites(poscar_data, func, tol = 0.01):
|
|
|
1635
1635
|
pos = data['positions'][indices]
|
|
1636
1636
|
qos = data['positions'][others] # need edge items to include
|
|
1637
1637
|
|
|
1638
|
-
if qos.
|
|
1638
|
+
if qos.size:
|
|
1639
1639
|
qos = np.concatenate([[[i] for i in others], qos], axis=1) # need to keep index
|
|
1640
1640
|
qos = np.array([qos + [0, *p] for p in product([-1,0,1],[-1,0,1],[-1,0,1])]).reshape((-1,4)) # all possible translations
|
|
1641
1641
|
qos = qos[(qos[:,1:] < 1 + tol).all(axis=1) & (qos[:,1:] > -tol).all(axis=1)]# only in cell range
|
|
1642
1642
|
qos = qos[[func(*q) for q in qos]] # masked only those are true
|
|
1643
1643
|
|
|
1644
|
-
if qos.
|
|
1644
|
+
if qos.size:
|
|
1645
1645
|
pos = np.concatenate([pos, qos[:,1:]],axis=0)
|
|
1646
1646
|
|
|
1647
1647
|
all_pos.append(pos)
|
|
@@ -1681,10 +1681,10 @@ def iplot_lattice(
|
|
|
1681
1681
|
|
|
1682
1682
|
Parameters
|
|
1683
1683
|
----------
|
|
1684
|
-
sizes : float or
|
|
1685
|
-
Size of sites. Either one int/float or
|
|
1686
|
-
colors :
|
|
1687
|
-
|
|
1684
|
+
sizes : float or dict of type -> float
|
|
1685
|
+
Size of sites. Either one int/float or a mapping like {'Ga': 2, ...}.
|
|
1686
|
+
colors : color or dict of type -> color
|
|
1687
|
+
Mapping of colors like {'Ga': 'red, ...} or a single color. Automatically generated color for missing types.
|
|
1688
1688
|
bond_length : float or dict
|
|
1689
1689
|
Length of bond in Angstrom. Auto calculated if not provides. Can be a dict like {'Fe-O':3.2,...} to specify bond length between specific types.
|
|
1690
1690
|
bond_kws : dict
|
|
@@ -1717,17 +1717,9 @@ def iplot_lattice(
|
|
|
1717
1717
|
fig = go.Figure()
|
|
1718
1718
|
|
|
1719
1719
|
uelems = poscar_data.types.to_dict()
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
if colors and len(colors) != len(uelems.keys()):
|
|
1724
|
-
print(
|
|
1725
|
-
"Warning: Number of colors does not match number of atom types. Using default colors."
|
|
1726
|
-
)
|
|
1727
|
-
|
|
1728
|
-
if (colors is None) or len(colors) != len(uelems.keys()):
|
|
1729
|
-
colors = [_atom_colors[elem] for elem in uelems.keys()]
|
|
1730
|
-
colors = ["rgb({},{},{})".format(*[int(_c * 255) for _c in c]) for c in colors]
|
|
1720
|
+
_fcs = _fix_color_size(uelems, colors, sizes, 10, backend = 'plotly')
|
|
1721
|
+
sizes = [v['size'] for v in _fcs.values()]
|
|
1722
|
+
colors = [v['color'] for v in _fcs.values()]
|
|
1731
1723
|
|
|
1732
1724
|
_colors = np.array([colors[i] for i, vs in enumerate(uelems.values()) for v in vs],dtype=object) # could be mixed color types
|
|
1733
1725
|
|
|
@@ -1854,6 +1846,33 @@ def _validate_label_func(fmt_label, parameter):
|
|
|
1854
1846
|
elif not isinstance(test_out, str):
|
|
1855
1847
|
raise ValueError("fmt_label must return a string or a list/tuple of length 2.")
|
|
1856
1848
|
|
|
1849
|
+
def _fix_color_size(types, colors, sizes, default_size, backend=None):
|
|
1850
|
+
cs = {key: {'color': _atom_colors.get(key, 'blue'), 'size': default_size} for key in types}
|
|
1851
|
+
for k in cs:
|
|
1852
|
+
if len(cs[k]['color']) == 3: # otherwise its blue
|
|
1853
|
+
if backend == 'plotly':
|
|
1854
|
+
cs[k]['color'] = "rgb({},{},{})".format(*[int(255*c) for c in cs[k]['color']])
|
|
1855
|
+
elif backend == 'ngl':
|
|
1856
|
+
cs[k]['color'] = mplc.to_hex(cs[k]['color'])
|
|
1857
|
+
|
|
1858
|
+
if isinstance(sizes,(int,float,np.integer)):
|
|
1859
|
+
for k in cs:
|
|
1860
|
+
cs[k]['size'] = sizes
|
|
1861
|
+
elif isinstance(sizes, dict):
|
|
1862
|
+
for k,v in sizes.items():
|
|
1863
|
+
cs[k]['size'] = v
|
|
1864
|
+
else:
|
|
1865
|
+
raise TypeError("sizes should be a single int/float or dict as {'Ga':10,'As':15,...}")
|
|
1866
|
+
|
|
1867
|
+
if isinstance(colors,dict):
|
|
1868
|
+
for k,v in colors.items():
|
|
1869
|
+
cs[k]['color'] = v
|
|
1870
|
+
elif isinstance(colors,(str,list,tuple,np.ndarray)):
|
|
1871
|
+
for k in cs:
|
|
1872
|
+
cs[k]['color'] = colors
|
|
1873
|
+
elif colors is not None:
|
|
1874
|
+
raise TypeError("colors should be a single valid color or dict as {'Ga':'red','As':'blue',...}")
|
|
1875
|
+
return cs
|
|
1857
1876
|
|
|
1858
1877
|
# Cell
|
|
1859
1878
|
def splot_lattice(
|
|
@@ -1880,10 +1899,10 @@ def splot_lattice(
|
|
|
1880
1899
|
----------
|
|
1881
1900
|
plane : str
|
|
1882
1901
|
Plane to plot. Either 'xy','xz','yz' or None for 3D plot.
|
|
1883
|
-
sizes : float or
|
|
1884
|
-
Size of sites. Either one int/float or
|
|
1885
|
-
colors :
|
|
1886
|
-
|
|
1902
|
+
sizes : float or dict of type -> float
|
|
1903
|
+
Size of sites. Either one int/float or a mapping like {'Ga': 2, ...}.
|
|
1904
|
+
colors : color or dict of type -> color
|
|
1905
|
+
Mapping of colors like {'Ga': 'red, ...} or a single color. Automatically generated color for missing types.
|
|
1887
1906
|
bond_length : float or dict
|
|
1888
1907
|
Length of bond in Angstrom. Auto calculated if not provides. Can be a dict like {'Fe-O':3.2,...} to specify bond length between specific types.
|
|
1889
1908
|
alpha : float
|
|
@@ -1941,23 +1960,10 @@ def splot_lattice(
|
|
|
1941
1960
|
print(f"Warning: Parameters {list(kwargs.keys())} are not used when `plot_cell = False`.")
|
|
1942
1961
|
|
|
1943
1962
|
uelems = poscar_data.types.to_dict()
|
|
1944
|
-
if not isinstance(sizes, (list, tuple, np.ndarray)):
|
|
1945
|
-
if not isinstance(sizes, (int, float, np.integer)):
|
|
1946
|
-
raise ValueError("sizes must be a number or a list/tuple of numbers.")
|
|
1947
|
-
sizes = [sizes for _ in uelems]
|
|
1948
|
-
|
|
1949
|
-
if len(sizes) != len(uelems):
|
|
1950
|
-
raise ValueError(
|
|
1951
|
-
f"Length of `sizes` must be equal to number of elements in POSCAR. Got {len(sizes)} sizes for {len(uelems)} elements."
|
|
1952
|
-
)
|
|
1953
|
-
|
|
1954
|
-
if colors and len(colors) != len(uelems.keys()):
|
|
1955
|
-
print(
|
|
1956
|
-
"Warning: Number of colors does not match number of atom types. Using default colors."
|
|
1957
|
-
)
|
|
1958
1963
|
|
|
1959
|
-
|
|
1960
|
-
|
|
1964
|
+
_fcs = _fix_color_size(uelems, colors, sizes, 50)
|
|
1965
|
+
sizes = [v['size'] for v in _fcs.values()]
|
|
1966
|
+
colors = [v['color'] for v in _fcs.values()]
|
|
1961
1967
|
|
|
1962
1968
|
# Before doing other stuff, create something for legend.
|
|
1963
1969
|
if showlegend:
|
|
@@ -2691,8 +2697,12 @@ def deform_poscar(poscar_data, deformation):
|
|
|
2691
2697
|
def view_poscar(poscar_data, **kwargs):
|
|
2692
2698
|
"View a POSCAR in a jupyter notebook. kwargs are passed to splot_lattice. After setting a view, you can do view.f(**view.kwargs) to get same plot in a cell."
|
|
2693
2699
|
|
|
2694
|
-
def view(elev
|
|
2700
|
+
def view(elev, azim, roll):
|
|
2695
2701
|
ax = splot_lattice(poscar_data, **kwargs)
|
|
2696
2702
|
ax.view_init(elev=elev, azim=azim, roll=roll)
|
|
2703
|
+
|
|
2704
|
+
elev = IntSlider(description='elev', min=0,max=180,value=30, continuous_update=False)
|
|
2705
|
+
azim = IntSlider(description='azim', min=0,max=360,value=30, continuous_update=False)
|
|
2706
|
+
roll = IntSlider(description='roll', min=0,max=360,value=0, continuous_update=False)
|
|
2697
2707
|
|
|
2698
|
-
return interactive(view, elev=
|
|
2708
|
+
return interactive(view, elev=elev, azim=azim, roll=roll)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.8.8"
|
|
@@ -1015,14 +1015,18 @@ def iplot2widget(fig, fig_widget=None, template=None):
|
|
|
1015
1015
|
|
|
1016
1016
|
if fig_widget is None:
|
|
1017
1017
|
fig_widget = go.FigureWidget()
|
|
1018
|
+
scene = fig.layout.scene # need to copy scane form given fig
|
|
1018
1019
|
elif not isinstance(fig_widget, go.FigureWidget):
|
|
1019
1020
|
raise ValueError("fig_widget must be FigureWidget")
|
|
1021
|
+
else:
|
|
1022
|
+
scene = fig_widget.layout.scene # keep scene from widget
|
|
1020
1023
|
|
|
1021
1024
|
fig_widget.data = [] # Clear previous data
|
|
1022
1025
|
if template is not None:
|
|
1023
|
-
fig.layout.template = template # will make white flash if not done before
|
|
1024
|
-
|
|
1026
|
+
fig.layout.template = template # will make white flash if not done before
|
|
1027
|
+
|
|
1025
1028
|
fig_widget.layout = fig.layout
|
|
1029
|
+
fig_widget.layout.scene = scene # reset scene back
|
|
1026
1030
|
|
|
1027
1031
|
with fig_widget.batch_update():
|
|
1028
1032
|
for data in fig.data:
|
|
@@ -75,7 +75,7 @@ def download_structure(
|
|
|
75
75
|
def ngl_viewer(
|
|
76
76
|
poscar,
|
|
77
77
|
colors=None,
|
|
78
|
-
sizes=
|
|
78
|
+
sizes=0.5,
|
|
79
79
|
plot_cell=True,
|
|
80
80
|
linewidth=0.05,
|
|
81
81
|
color=[0, 0, 0.2],
|
|
@@ -91,13 +91,12 @@ def ngl_viewer(
|
|
|
91
91
|
Parameters
|
|
92
92
|
----------
|
|
93
93
|
poscar : ipyvasp.POSCAR
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
sizes : float or dict of type -> float
|
|
95
|
+
Size of sites. Either one int/float or a mapping like {'Ga': 2, ...}.
|
|
96
|
+
colors : color or sheme name or dict of type -> color
|
|
97
|
+
Mapping of colors like {'Ga': 'red, ...} or a single color. Automatically generated color for missing types.
|
|
96
98
|
If `colors = 'element'`, then element colors from `nglview` will be used.
|
|
97
99
|
You can use `nglview.color.COLOR_SCHEME` to see available color schemes to use.
|
|
98
|
-
If colors is None, then default colors from ipyvasp will be used that are same in `[i,s]plot_lattice`.
|
|
99
|
-
sizes : list
|
|
100
|
-
List of sizes for each atom type.
|
|
101
100
|
plot_cell : bool
|
|
102
101
|
Plot unit cell. Default True.
|
|
103
102
|
linewidth : float
|
|
@@ -139,26 +138,10 @@ def ngl_viewer(
|
|
|
139
138
|
data=plat._fix_sites(poscar.data, eqv_sites=True if plot_cell else False, origin=origin)
|
|
140
139
|
)
|
|
141
140
|
|
|
142
|
-
_types =
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
if sizes:
|
|
147
|
-
if len(sizes) != len(_types):
|
|
148
|
-
raise ValueError(
|
|
149
|
-
"sizes must have the same length as the number of atom types."
|
|
150
|
-
)
|
|
151
|
-
_sizes = sizes
|
|
152
|
-
|
|
153
|
-
if colors:
|
|
154
|
-
if isinstance(colors, str):
|
|
155
|
-
_colors = [colors for _ in _types] # All same color, may be 'element'
|
|
156
|
-
else:
|
|
157
|
-
if len(colors) != len(_types):
|
|
158
|
-
raise ValueError(
|
|
159
|
-
"colors must have the same length as the number of atom types."
|
|
160
|
-
)
|
|
161
|
-
_colors = [mcolors.to_hex(c) for c in colors]
|
|
141
|
+
_types = poscar.data.types.to_dict()
|
|
142
|
+
_fcs = plat._fix_color_size(_types,colors,sizes,0.5, backend='ngl')
|
|
143
|
+
_sizes = [v['size'] for v in _fcs.values()]
|
|
144
|
+
_colors = [v['color'] for v in _fcs.values()]
|
|
162
145
|
|
|
163
146
|
view = nv.NGLWidget(
|
|
164
147
|
nv.ASEStructure(poscar.to_ase()),
|
|
@@ -199,7 +182,7 @@ def ngl_viewer(
|
|
|
199
182
|
|
|
200
183
|
|
|
201
184
|
def weas_viewer(poscar,
|
|
202
|
-
sizes=
|
|
185
|
+
sizes=1,
|
|
203
186
|
colors=None,
|
|
204
187
|
bond_length=None,
|
|
205
188
|
model_style = 1,
|
|
@@ -207,9 +190,11 @@ def weas_viewer(poscar,
|
|
|
207
190
|
origin = (0,0,0)
|
|
208
191
|
):
|
|
209
192
|
"""
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
193
|
+
sizes : float or dict of type -> float
|
|
194
|
+
Size of sites. Either one int/float or a mapping like {'Ga': 2, ...}.
|
|
195
|
+
colors : color, color scheme or dict of type -> color
|
|
196
|
+
Mapping of colors like {'Ga': 'red, ...} or a single color. Automatically generated color for missing types.
|
|
197
|
+
You can use color schemes as 'VESTA','JMOL','CPK'.
|
|
213
198
|
sizes : list
|
|
214
199
|
List of sizes for each atom type.
|
|
215
200
|
model_type: int
|
|
@@ -236,8 +221,7 @@ def weas_viewer(poscar,
|
|
|
236
221
|
w = WeasWidget(from_ase=poscar.to_ase())
|
|
237
222
|
w.avr.show_bonded_atoms = False if plot_cell else True # plot_cell fix atoms itself
|
|
238
223
|
w.avr.model_style = model_style
|
|
239
|
-
w.avr.show_cell = plot_cell
|
|
240
|
-
|
|
224
|
+
w.avr.show_cell = plot_cell
|
|
241
225
|
|
|
242
226
|
if bond_length:
|
|
243
227
|
if isinstance(bond_length,(int,float)):
|
|
@@ -247,40 +231,73 @@ def weas_viewer(poscar,
|
|
|
247
231
|
elif isinstance(bond_length, dict):
|
|
248
232
|
for key, value in bond_length.items():
|
|
249
233
|
w.avr.bond.settings[key].update({'max': value})
|
|
250
|
-
|
|
251
|
-
if sizes is not None:
|
|
252
|
-
if not isinstance(sizes, (list,tuple)) or len(sizes) != len(poscar.data.types):
|
|
253
|
-
raise ValueError(f"sizes should be list/tuple of same sizes as atom types = {len(poscar.data.types)}.")
|
|
254
|
-
for key, value in zip(poscar.data.types,sizes):
|
|
255
|
-
w.avr.species.settings[key].update({"radius": value})
|
|
256
234
|
|
|
257
|
-
|
|
258
|
-
colors = [plat._atom_colors[key] for key in poscar.data.types]
|
|
235
|
+
_fcs = plat._fix_color_size(poscar.data.types.to_dict(), colors, sizes, 1)
|
|
259
236
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
raise ValueError("colors should be one of ['VESTA','JMOL','CPK'] if given as string!")
|
|
263
|
-
|
|
264
|
-
w.avr.color_type = colors
|
|
265
|
-
|
|
266
|
-
if not isinstance(colors, str):
|
|
267
|
-
if not isinstance(colors, (list,tuple)) or len(colors) != len(poscar.data.types):
|
|
268
|
-
raise ValueError(f"colors should be list/tuple of same sizes as atom types = {len(poscar.data.types)}.")
|
|
237
|
+
for key, value in _fcs.items():
|
|
238
|
+
w.avr.species.settings[key].update({"radius": value["size"]})
|
|
269
239
|
|
|
270
|
-
|
|
240
|
+
if isinstance(colors, str) and colors in ['VESTA','JMOL','CPK']:
|
|
241
|
+
w.avr.color_type = colors
|
|
242
|
+
else:
|
|
243
|
+
colors = {key: value["color"] for key, value in _fcs.items()}
|
|
271
244
|
for key,value in colors.items():
|
|
272
245
|
w.avr.species.settings[key].update({"color": value})
|
|
273
246
|
for (k1,c1), (k2,c2) in permutations(colors.items(),2):
|
|
274
247
|
with suppress(KeyError):
|
|
275
248
|
w.avr.bond.settings[f'{k1}-{k2}'].update({'color1':c1,'color2':c2})
|
|
276
|
-
|
|
249
|
+
|
|
277
250
|
return w
|
|
278
251
|
|
|
279
252
|
|
|
253
|
+
class _AutoRenderer:
|
|
254
|
+
_figw = None
|
|
255
|
+
_kws = {}
|
|
256
|
+
|
|
257
|
+
def __init__(self, pc_instance):
|
|
258
|
+
self._pc = pc_instance
|
|
259
|
+
|
|
260
|
+
def on(self, template=None):
|
|
261
|
+
"Enable auto rendering. In Jupyterlab, you can use `Create New View for Output` to drag a view on side."
|
|
262
|
+
self.off()
|
|
263
|
+
type(self)._figw = iplot2widget(self._pc.iplot_lattice(**self._kws), fig_widget=self._figw,template=template)
|
|
264
|
+
|
|
265
|
+
def ip_display(that):
|
|
266
|
+
iplot2widget(that.iplot_lattice(**self._kws), fig_widget=self._figw, template=template)
|
|
267
|
+
|
|
268
|
+
type(self._pc)._ipython_display_ = ip_display
|
|
269
|
+
|
|
270
|
+
from ipywidgets import Button, VBox
|
|
271
|
+
btn = Button(description='Disable Auto Rendering',icon='close',layout={'width': 'max-content'})
|
|
272
|
+
btn.on_click(lambda btn: self.off())
|
|
273
|
+
type(self)._box = VBox([btn, self._figw])
|
|
274
|
+
return display(self._box)
|
|
275
|
+
|
|
276
|
+
def off(self):
|
|
277
|
+
"Disable auto rendering."
|
|
278
|
+
if hasattr(self, '_box'):
|
|
279
|
+
self._box.close()
|
|
280
|
+
type(self)._figw = None # no need to close figw, it raise warning, but now garbage collected
|
|
281
|
+
|
|
282
|
+
if hasattr(type(self._pc), '_ipython_display_'):
|
|
283
|
+
del type(self._pc)._ipython_display_
|
|
284
|
+
|
|
285
|
+
@_sig_kwargs(plat.iplot_lattice,('poscar_data',))
|
|
286
|
+
def update_params(self, **kwargs):
|
|
287
|
+
type(self)._kws = kwargs
|
|
288
|
+
if hasattr(type(self._pc), '_ipython_display_'):
|
|
289
|
+
self._pc._ipython_display_()
|
|
290
|
+
|
|
291
|
+
@property
|
|
292
|
+
def params(self):
|
|
293
|
+
return self._kws.copy() # avoid messing original
|
|
294
|
+
|
|
295
|
+
def __repr__(self):
|
|
296
|
+
return f"AutoRenderer({self._kws})"
|
|
297
|
+
|
|
280
298
|
class POSCAR:
|
|
281
299
|
_cb_instance = {} # Loads last clipboard data if not changed
|
|
282
300
|
_mp_instance = {} # Loads last mp data if not changed
|
|
283
|
-
_update_kws = {} # kwargs to pass to auto update figurewidget
|
|
284
301
|
|
|
285
302
|
def __init__(self, path=None, content=None, data=None):
|
|
286
303
|
"""
|
|
@@ -294,10 +311,16 @@ class POSCAR:
|
|
|
294
311
|
data : PoscarData object. This assumes positions are in fractional coordinates.
|
|
295
312
|
|
|
296
313
|
Prefrence order: data > content > path
|
|
314
|
+
|
|
315
|
+
Tip: You can use `self.auto_renderer.on()` to keep doing opertions and visualize while last line of any cell is a POSCAR object.
|
|
297
316
|
"""
|
|
298
317
|
self._path = Path(path or "POSCAR") # Path to file
|
|
299
318
|
self._content = content
|
|
300
319
|
|
|
320
|
+
if not hasattr(self, '_renderer'): # Only once
|
|
321
|
+
type(self)._renderer = _AutoRenderer(self) # assign to class
|
|
322
|
+
self._renderer._pc = self # keep latest refrence there too, for update_params on right one
|
|
323
|
+
|
|
301
324
|
if data:
|
|
302
325
|
self._data = serializer.PoscarData.validated(data)
|
|
303
326
|
else:
|
|
@@ -321,6 +344,19 @@ class POSCAR:
|
|
|
321
344
|
@property
|
|
322
345
|
def path(self):
|
|
323
346
|
return self._path
|
|
347
|
+
|
|
348
|
+
@property
|
|
349
|
+
def auto_renderer(self):
|
|
350
|
+
"""A renderer for auto viewing POSCAR when at last line of cell.
|
|
351
|
+
|
|
352
|
+
Use `auto_renderer.on()` to enable it.
|
|
353
|
+
Use `auto_renderer.off()` to disable it.
|
|
354
|
+
Use `auto_renderer.[params, update_params()]` to view and update parameters.
|
|
355
|
+
|
|
356
|
+
In Jupyterlab, you can use `Create New View for Output` to drag a view on side.
|
|
357
|
+
In VS Code, you can open another view of Notebook to see it on side while doing operations.
|
|
358
|
+
"""
|
|
359
|
+
return self._renderer
|
|
324
360
|
|
|
325
361
|
def to_ase(self):
|
|
326
362
|
"""Convert to ase.Atoms format. You need to have ase installed.
|
|
@@ -353,6 +389,8 @@ class POSCAR:
|
|
|
353
389
|
return plat.view_poscar(self.data, **kwargs)
|
|
354
390
|
elif viewer in "weas":
|
|
355
391
|
return weas_viewer(self, **kwargs)
|
|
392
|
+
elif viewer in "plotly":
|
|
393
|
+
return self.view_plotly(**kwargs)
|
|
356
394
|
elif viewer in "nglview":
|
|
357
395
|
return print(
|
|
358
396
|
f"Use `self.view_ngl()` for better customization in case of viewer={viewer!r}"
|
|
@@ -371,7 +409,6 @@ class POSCAR:
|
|
|
371
409
|
@_sig_kwargs(weas_viewer, ("poscar",))
|
|
372
410
|
def view_weas(self, **kwargs):
|
|
373
411
|
return weas_viewer(self, **kwargs)
|
|
374
|
-
|
|
375
412
|
|
|
376
413
|
def view_kpath(self):
|
|
377
414
|
"Initialize a KpathWidget instance to view kpath for current POSCAR, and you can select others too."
|
|
@@ -381,18 +418,9 @@ class POSCAR:
|
|
|
381
418
|
|
|
382
419
|
@_sub_doc(plat.iplot_lattice)
|
|
383
420
|
@_sig_kwargs(plat.iplot_lattice, ("poscar_data",))
|
|
384
|
-
def
|
|
385
|
-
self.__class__._update_kws = kwargs # attach to class, not self
|
|
421
|
+
def view_plotly(self, **kwargs):
|
|
386
422
|
return iplot2widget(self.iplot_lattice(**kwargs))
|
|
387
423
|
|
|
388
|
-
@_sig_kwargs(plat.iplot_lattice, ("poscar_data",))
|
|
389
|
-
def update_widget(self, handle, **kwargs):
|
|
390
|
-
"""Update widget (if shown in notebook) after some operation on POSCAR with `handle` returned by `view_widget`
|
|
391
|
-
kwargs are passed to `self.iplot_lattice` method.
|
|
392
|
-
"""
|
|
393
|
-
kwargs = {**self.__class__._update_kws, **kwargs}
|
|
394
|
-
iplot2widget(self.iplot_lattice(**kwargs), fig_widget=handle)
|
|
395
|
-
|
|
396
424
|
@classmethod
|
|
397
425
|
def from_file(cls, path):
|
|
398
426
|
"Load data from POSCAR file"
|
|
@@ -533,14 +561,6 @@ class POSCAR:
|
|
|
533
561
|
"Writes POSCAR to clipboard (as implemented by pandas library) for copy in other programs such as vim."
|
|
534
562
|
clipboard_set(self.content) # write to clipboard
|
|
535
563
|
|
|
536
|
-
|
|
537
|
-
def update_weas(self, handle):
|
|
538
|
-
"""Send result of any operation to view on opened weas widget handle with default parameters becuase any operations
|
|
539
|
-
can be incompatible with presious state of POSCAR. VESTA color scheme is used here.
|
|
540
|
-
Useful in Jupyterlab side panel to look operations results on POSCAR."""
|
|
541
|
-
handle.from_ase(self.to_ase())
|
|
542
|
-
handle.avr.color_type = 'VESTA'
|
|
543
|
-
|
|
544
564
|
@property
|
|
545
565
|
def data(self):
|
|
546
566
|
"Data object in POSCAR."
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ipyvasp
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.8
|
|
4
4
|
Summary: A processing tool for VASP DFT input/output processing in Jupyter Notebook.
|
|
5
5
|
Home-page: https://github.com/massgh/ipyvasp
|
|
6
6
|
Author: Abdul Saboor
|
|
@@ -68,7 +68,7 @@ Interactively select bandstructure path by clicking on high symmetry points on p
|
|
|
68
68
|
|
|
69
69
|

|
|
70
70
|
|
|
71
|
-
Apply operations on POSCAR and simultaneously view using plotly's `FigureWidget`
|
|
71
|
+
Apply operations on POSCAR and simultaneously view using plotly's `FigureWidget` in Jupyterlab side by side.
|
|
72
72
|
|
|
73
73
|

|
|
74
74
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.8.6"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|