ipyvasp 0.8.7__py2.py3-none-any.whl → 0.8.9__py2.py3-none-any.whl

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/_lattice.py CHANGED
@@ -1867,10 +1867,10 @@ def _fix_color_size(types, colors, sizes, default_size, backend=None):
1867
1867
  if isinstance(colors,dict):
1868
1868
  for k,v in colors.items():
1869
1869
  cs[k]['color'] = v
1870
- elif colors is not None and isinstance(colors,(str,list,tuple,np.ndarray)):
1870
+ elif isinstance(colors,(str,list,tuple,np.ndarray)):
1871
1871
  for k in cs:
1872
1872
  cs[k]['color'] = colors
1873
- else:
1873
+ elif colors is not None:
1874
1874
  raise TypeError("colors should be a single valid color or dict as {'Ga':'red','As':'blue',...}")
1875
1875
  return cs
1876
1876
 
ipyvasp/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.8.7"
1
+ __version__ = "0.8.9"
@@ -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:
@@ -422,7 +422,9 @@ class PoscarData(Dict2Data):
422
422
 
423
423
 
424
424
  def get_bond_data(self, site_indices, k = 5):
425
- "Returns a DataFrame with bonds angle, bond length, vector positions etc. that can be used for plotting."
425
+ """Returns a DataFrame with bonds angle, bond length, vector positions etc. that can be used for plotting.
426
+ t_a and t_b are translation vectors to get them near selected sites. You can use `POSCAR.translate` if somehow need nearest coordinates.
427
+ """
426
428
  if k < 3:
427
429
  raise ValueError("k >= 3 is required!")
428
430
 
@@ -434,16 +436,18 @@ class PoscarData(Dict2Data):
434
436
  for j in js:
435
437
  bs = np.array([self.to_cartesian(self.positions[j] + p) for p in product([-1,0,1],[-1,0,1],[-1,0,1])])
436
438
  ds = np.array([np.linalg.norm(a-b) for b in bs])
437
- nears.append((j, bs[ds.argsort()][0]))
439
+ b = bs[ds.argsort()][0]
440
+ t = tuple((self.to_fractional(b) - self.positions[j]).astype(int)) # keep track of translation vector
441
+ nears.append((j, b, t))
438
442
 
439
- for (m,b),(n, c) in combinations(nears,2):
440
- v1, v2 = b-a, c-a
443
+ for (m,b,t1),(n, c,t2) in combinations(nears,2):
444
+ v1, v2 = b - a, c - a
441
445
  n1, n2 = np.linalg.norm(v1), np.linalg.norm(v2)
442
446
  name = '-'.join(self.symbols[[m,i,n]])
443
447
  angle = np.degrees(np.arccos(v1.dot(v2)/(n1*n2)))
444
- out.append([name, m,i,n, angle, n1, n2, *b, *a, *c])
448
+ out.append([name, m,i,n, angle, n1, n2, t1,t2])
445
449
 
446
- columns = 'bond a o b angle d_ao d_bo ax ay az ox oy oz bx by bz'.split()
450
+ columns = 'bond a o b angle d_ao d_bo t_a t_b'.split()
447
451
  return DataFrame(out, columns=columns)
448
452
 
449
453
  def to_fractional(self, coords):
ipyvasp/lattice.py CHANGED
@@ -250,11 +250,54 @@ def weas_viewer(poscar,
250
250
  return w
251
251
 
252
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(params = {self._kws})"
297
+
253
298
  class POSCAR:
254
299
  _cb_instance = {} # Loads last clipboard data if not changed
255
300
  _mp_instance = {} # Loads last mp data if not changed
256
- _plotly_kws = {} # kwargs to pass to auto update figurewidget
257
- _weas_kws = {}
258
301
 
259
302
  def __init__(self, path=None, content=None, data=None):
260
303
  """
@@ -268,10 +311,16 @@ class POSCAR:
268
311
  data : PoscarData object. This assumes positions are in fractional coordinates.
269
312
 
270
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.
271
316
  """
272
317
  self._path = Path(path or "POSCAR") # Path to file
273
318
  self._content = content
274
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
+
275
324
  if data:
276
325
  self._data = serializer.PoscarData.validated(data)
277
326
  else:
@@ -295,6 +344,19 @@ class POSCAR:
295
344
  @property
296
345
  def path(self):
297
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
298
360
 
299
361
  def to_ase(self):
300
362
  """Convert to ase.Atoms format. You need to have ase installed.
@@ -327,6 +389,8 @@ class POSCAR:
327
389
  return plat.view_poscar(self.data, **kwargs)
328
390
  elif viewer in "weas":
329
391
  return weas_viewer(self, **kwargs)
392
+ elif viewer in "plotly":
393
+ return self.view_plotly(**kwargs)
330
394
  elif viewer in "nglview":
331
395
  return print(
332
396
  f"Use `self.view_ngl()` for better customization in case of viewer={viewer!r}"
@@ -344,9 +408,7 @@ class POSCAR:
344
408
  @_sub_doc(weas_viewer)
345
409
  @_sig_kwargs(weas_viewer, ("poscar",))
346
410
  def view_weas(self, **kwargs):
347
- self.__class__._weas_kws = kwargs # attach to class, not self
348
411
  return weas_viewer(self, **kwargs)
349
-
350
412
 
351
413
  def view_kpath(self):
352
414
  "Initialize a KpathWidget instance to view kpath for current POSCAR, and you can select others too."
@@ -357,13 +419,8 @@ class POSCAR:
357
419
  @_sub_doc(plat.iplot_lattice)
358
420
  @_sig_kwargs(plat.iplot_lattice, ("poscar_data",))
359
421
  def view_plotly(self, **kwargs):
360
- self.__class__._plotly_kws = kwargs # attach to class, not self
361
422
  return iplot2widget(self.iplot_lattice(**kwargs))
362
423
 
363
- def update_plotly(self, handle):
364
- "Update plotly widget (already shown in notebook) after some operation on POSCAR with `handle` returned by `view_plotly`."
365
- iplot2widget(self.iplot_lattice(**self._plotly_kws), fig_widget=handle)
366
-
367
424
  @classmethod
368
425
  def from_file(cls, path):
369
426
  "Load data from POSCAR file"
@@ -504,12 +561,6 @@ class POSCAR:
504
561
  "Writes POSCAR to clipboard (as implemented by pandas library) for copy in other programs such as vim."
505
562
  clipboard_set(self.content) # write to clipboard
506
563
 
507
-
508
- def update_weas(self, handle):
509
- """Send result of any operation to view on opened weas widget handle.
510
- Useful in Jupyterlab side panel to look operations results on POSCAR."""
511
- handle.children = weas_viewer(self, **self._weas_kws).children # does not work properly otherwise
512
-
513
564
  @property
514
565
  def data(self):
515
566
  "Data object in POSCAR."
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ipyvasp
3
- Version: 0.8.7
3
+ Version: 0.8.9
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
  ![KP](KP.png)
70
70
 
71
- Apply operations on POSCAR and simultaneously view using plotly's `FigureWidget` or `WeasWidget` in Jupyterlab side by side.
71
+ Apply operations on POSCAR and simultaneously view using plotly's `FigureWidget` in Jupyterlab side by side.
72
72
 
73
73
  ![snip](op.png)
74
74
 
@@ -1,12 +1,12 @@
1
1
  ipyvasp/__init__.py,sha256=7o41i5eYlNKg1Hsv0DLNFZ81GilxB02IXAJN-QiJQi0,1420
2
2
  ipyvasp/__main__.py,sha256=eJV1TZSiT8mC_VqAeksNnBI2I8mKMiPkEIlwikbtOjI,216
3
3
  ipyvasp/_enplots.py,sha256=D38paN8zqZgluNAwmCwcocd7-_h_T0HTGolI1eBkDes,37484
4
- ipyvasp/_lattice.py,sha256=AU_iQ4ZdJ0fEb8FxiADexOsVMp_zWJ11HLxBg_u9q7M,104022
5
- ipyvasp/_version.py,sha256=ggGr8Eeuw9YZ1g40gSyKadNe96lor0upJSmlkeVHJlg,23
4
+ ipyvasp/_lattice.py,sha256=TaiPj_cbBkmuCd40hM01_grNVLcn2hK70fTCN98GNgU,104018
5
+ ipyvasp/_version.py,sha256=Fj0n620aEHCHlsmEXmEGKx9B0YdzMeN3Yc9ZouxRIBU,23
6
6
  ipyvasp/bsdos.py,sha256=ZtQji-W11UdFFicAoWZjlqVhI5tqYu_jpKyPPWKkeeo,30634
7
7
  ipyvasp/cli.py,sha256=aWFEVhNmnW8eSOp5uh95JaDwLQ9K9nlCQcbnOSuhWgw,6844
8
8
  ipyvasp/evals_dataframe.py,sha256=-sqxK7LPV6sYDO_XXmZ80FznOaXTkVdbqJKKvTUtMak,20637
9
- ipyvasp/lattice.py,sha256=HUMh1GYS8CbY7D4VssRQbOV-klm7pK6gnfUU_evwC0k,27752
9
+ ipyvasp/lattice.py,sha256=Ow9BJa8ceasquLPOqsnpj2ysf45IHta1wLtEXoDHtTw,29642
10
10
  ipyvasp/misc.py,sha256=SZJ_ePUR2-HEKYTEpDHVRVE7zpIQVTCjiuw0BCC9UTU,2349
11
11
  ipyvasp/potential.py,sha256=tzA73c5lkp6ahLSJchMrU043-QWaOV0nIOUA7VMmfKQ,11408
12
12
  ipyvasp/surface.py,sha256=MjE5oB0wW6Pca_C-xu8rN6OMH7lUEeNPNyM7Kz_Im-8,23766
@@ -14,12 +14,12 @@ ipyvasp/utils.py,sha256=hiAV76jEMuDt1Wp22imrnsSgetjxmUKlskRA7CcK6BU,15261
14
14
  ipyvasp/widgets.py,sha256=fZ2b7EYYxuaAVfklnLa0VJ00U9Uyd7SqXrzt0hbLOvI,45400
15
15
  ipyvasp/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  ipyvasp/core/parser.py,sha256=C3CaZsJbPME_ttYlYy4DXeOdL7dnkXs-cHRwFZL6bio,38058
17
- ipyvasp/core/plot_toolkit.py,sha256=cktbPZTJ4K0_6-vKYqtQ1xIIPZg-gHJY5793M9XoYQ0,35754
18
- ipyvasp/core/serializer.py,sha256=OsnYhlwt8O6UeJQMKmjp1-hwRjhxiqobV6bybfDECUY,35777
17
+ ipyvasp/core/plot_toolkit.py,sha256=8t5svyWbOm-PS7ZvIptnK6F46kp6uwoGNdohPv5dQKA,35962
18
+ ipyvasp/core/serializer.py,sha256=57e2ypF18tJI1zZi9kJiHGMBYgXvYEZpLmgnaaDdSk0,36067
19
19
  ipyvasp/core/spatial_toolkit.py,sha256=8DBYTiBFWJ7OBKuvOPw7UoEVCyNjJhSW0OcudjYZvAw,14748
20
- ipyvasp-0.8.7.dist-info/LICENSE,sha256=F3SO5RiAZOMfmMGf1KOuk2g_c4ObvuBJhd9iBLDgXoQ,1263
21
- ipyvasp-0.8.7.dist-info/METADATA,sha256=xAr8HFygxeP0mLIRR5Pqbb04UuUOoXGwr7rUq4uDy2I,2436
22
- ipyvasp-0.8.7.dist-info/WHEEL,sha256=iYlv5fX357PQyRT2o6tw1bN-YcKFFHKqB_LwHO5wP-g,110
23
- ipyvasp-0.8.7.dist-info/entry_points.txt,sha256=C7m0Sjmr14wFjflCkWXLzr5N6-cQj8uJC9n82mUtzt8,44
24
- ipyvasp-0.8.7.dist-info/top_level.txt,sha256=ftziWlMWu_1VpDP1sRTFrkfBnWxAi393HYDVu4wRhUk,8
25
- ipyvasp-0.8.7.dist-info/RECORD,,
20
+ ipyvasp-0.8.9.dist-info/LICENSE,sha256=F3SO5RiAZOMfmMGf1KOuk2g_c4ObvuBJhd9iBLDgXoQ,1263
21
+ ipyvasp-0.8.9.dist-info/METADATA,sha256=GcN76IweS9RJKKCj7fxtZwyap1w97BO1_hSDHnEk3Q8,2420
22
+ ipyvasp-0.8.9.dist-info/WHEEL,sha256=iYlv5fX357PQyRT2o6tw1bN-YcKFFHKqB_LwHO5wP-g,110
23
+ ipyvasp-0.8.9.dist-info/entry_points.txt,sha256=C7m0Sjmr14wFjflCkWXLzr5N6-cQj8uJC9n82mUtzt8,44
24
+ ipyvasp-0.8.9.dist-info/top_level.txt,sha256=ftziWlMWu_1VpDP1sRTFrkfBnWxAi393HYDVu4wRhUk,8
25
+ ipyvasp-0.8.9.dist-info/RECORD,,