ipyvasp 0.9.7__tar.gz → 0.9.81__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.
Files changed (30) hide show
  1. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/PKG-INFO +1 -1
  2. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp/_lattice.py +62 -43
  3. ipyvasp-0.9.81/ipyvasp/_version.py +1 -0
  4. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp/core/parser.py +4 -1
  5. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp/core/serializer.py +20 -8
  6. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp/lattice.py +12 -12
  7. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp/widgets.py +1 -1
  8. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp.egg-info/PKG-INFO +1 -1
  9. ipyvasp-0.9.7/ipyvasp/_version.py +0 -1
  10. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/LICENSE +0 -0
  11. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/README.md +0 -0
  12. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp/__init__.py +0 -0
  13. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp/__main__.py +0 -0
  14. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp/_enplots.py +0 -0
  15. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp/bsdos.py +0 -0
  16. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp/cli.py +0 -0
  17. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp/core/__init__.py +0 -0
  18. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp/core/plot_toolkit.py +0 -0
  19. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp/core/spatial_toolkit.py +0 -0
  20. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp/evals_dataframe.py +0 -0
  21. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp/misc.py +0 -0
  22. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp/potential.py +0 -0
  23. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp/utils.py +0 -0
  24. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp.egg-info/SOURCES.txt +0 -0
  25. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp.egg-info/dependency_links.txt +0 -0
  26. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp.egg-info/entry_points.txt +0 -0
  27. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp.egg-info/requires.txt +0 -0
  28. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/ipyvasp.egg-info/top_level.txt +0 -0
  29. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/setup.cfg +0 -0
  30. {ipyvasp-0.9.7 → ipyvasp-0.9.81}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ipyvasp
3
- Version: 0.9.7
3
+ Version: 0.9.81
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
@@ -6,6 +6,7 @@ import requests as req
6
6
  import inspect
7
7
  from itertools import combinations, product
8
8
  from functools import lru_cache
9
+ from typing import NamedTuple
9
10
 
10
11
  from scipy.spatial import ConvexHull, KDTree
11
12
  import plotly.graph_objects as go
@@ -238,7 +239,7 @@ def write_poscar(poscar_data, outfile=None, selective_dynamics=None, overwrite=F
238
239
  ----------
239
240
  outfile : PathLike
240
241
  selective_dynamics : callable
241
- If given, should be a function like `f(index,x,y,z) -> (bool, bool, bool)`
242
+ If given, should be a function like `f(a) -> (a.p < 1/4)` or `f(a) -> (a.x < 1/4, a.y < 1/4, a.z < 1/4)`
242
243
  which turns on/off selective dynamics for each atom based in each dimension.
243
244
  See `ipyvasp.POSCAR.data.get_selective_dynamics` for more info.
244
245
  overwrite: bool
@@ -1192,8 +1193,11 @@ def splot_kpath(
1192
1193
  labels = [
1193
1194
  "[{0:5.2f}, {1:5.2f}, {2:5.2f}]".format(x, y, z) for x, y, z in kpoints
1194
1195
  ]
1196
+
1197
+ if fmt_label is None:
1198
+ fmt_label = lambda x: (x, {"color": "blue"})
1195
1199
 
1196
- _validate_label_func(fmt_label, labels[0])
1200
+ _validate_label_func(fmt_label,labels[0])
1197
1201
 
1198
1202
  coords = bz_data.to_cartesian(kpoints)
1199
1203
  if _zoffset and plane:
@@ -1565,25 +1569,50 @@ def _get_bond_length(poscar_data, bond_length=None):
1565
1569
  ) # Add 5% margin over mean distance, this covers same species too, and in multiple species, this will stop bonding between same species.
1566
1570
 
1567
1571
 
1568
- def _masked_data(poscar_data, func):
1569
- "Returns indices of sites which satisfy the func."
1570
- if not callable(func):
1571
- raise TypeError("`func` should be a callable function.")
1572
+ class _Atom(NamedTuple):
1573
+ "Object passed to POSCAR operations `func` where atomic sites are modified. Additinal property p -> array([x,y,z])."
1574
+ symbol : str
1575
+ number : int
1576
+ index : int
1577
+ x : float
1578
+ y : float
1579
+ z : float
1572
1580
 
1573
- if len(inspect.signature(func).parameters) != 4:
1581
+ @property
1582
+ def p(self): return np.array([self.x,self.y,self.z]) # for robust operations
1583
+
1584
+ class _AtomLabel(str):
1585
+ "Object passed to `fmt_label` in plotting. `number` and `symbol` are additional attributes and `to_latex` is a method."
1586
+ @property
1587
+ def number(self): return int(self.split()[1])
1588
+ @property
1589
+ def symbol(self): return self.split()[0]
1590
+ def to_latex(self): return "{}$_{{{}}}$".format(*self.split())
1591
+
1592
+ def _validate_func(func):
1593
+ if not callable(func):
1594
+ raise ValueError("`func` must be a callable function with single parameter `Atom(symbol,number, index,x,y,z)`.")
1595
+
1596
+ if len(inspect.signature(func).parameters) != 1:
1574
1597
  raise ValueError(
1575
- "`func` takes exactly 4 arguments: (index,x,y,z) in fractional coordinates"
1598
+ "`func` takes exactly 1 argument: `Atom(symbol, number, index,x,y,z)` in fractional coordinates"
1599
+ )
1600
+
1601
+ ret = func(_Atom('',0,0,0,0,0))
1602
+ if not isinstance(ret, (bool, np.bool_)):
1603
+ raise ValueError(
1604
+ f"`func` must be a function that returns a bool, got {type(ret)}."
1576
1605
  )
1577
1606
 
1578
- if not isinstance(func(0, 0, 0, 0), bool):
1579
- raise TypeError("`func` should return a boolean value.")
1580
-
1607
+ def _masked_data(poscar_data, func):
1608
+ "Returns indices of sites which satisfy the func."
1609
+ _validate_func(func)
1581
1610
  eqv_inds = tuple(getattr(poscar_data.metadata, "eqv_indices",[]))
1582
1611
 
1583
1612
  pick = []
1584
1613
  for i, pos in enumerate(poscar_data.positions):
1585
1614
  idx = eqv_inds[i] if eqv_inds else i # map to original index
1586
- if func(idx, *pos):
1615
+ if func(_Atom(*poscar_data._sn[i], idx, *pos)): # labels based on i, not eqv_idx
1587
1616
  pick.append(i)
1588
1617
  return pick # could be duplicate indices
1589
1618
 
@@ -1604,11 +1633,14 @@ def _filter_pairs(labels, pairs, dist, bond_length):
1604
1633
  # Return all pairs otherwise
1605
1634
  return pairs # None -> auto calculate bond_length, number -> use that number
1606
1635
 
1607
- def filter_sites(poscar_data, func, tol = 0.01):
1608
- """Filter sites based on a function that acts on index and fractional positions such as `lambda i,x,y,z: condition`.
1636
+ def filter_atoms(poscar_data, func, tol = 0.01):
1637
+ """Filter atomic sites based on a function that acts on an atom such as `lambda a: (a.p < 1/2).all()`.
1638
+ `atom` passed to function is a namedtuple like `Atom(symbol,number,index,x,y,z)` which has extra attribute `p = array([x,y,z])`.
1609
1639
  This may include equivalent sites, so it should be used for plotting purpose only, e.g. showing atoms on a plane.
1610
1640
  An attribute `source_indices` is added to metadata which is useful to pick other things such as `OUTCAR.ion_pot[POSCAR.filter(...).data.metadata.source_indices]`.
1611
1641
 
1642
+ >>> filter_atoms(..., lambda a: a.symbol=='Ga' or a.number in range(2)) # picks all Ga atoms and first two atoms of every other types.
1643
+
1612
1644
  Note: If you are filtering a plane with more than one non-zero hkl like 110, you may first need to translate or set boundary on POSCAR to bring desired plane in full view to include all atoms.
1613
1645
  """
1614
1646
  if hasattr(poscar_data.metadata, 'source_indices'):
@@ -1804,13 +1836,13 @@ def iplot_lattice(
1804
1836
  return fig
1805
1837
 
1806
1838
 
1807
- def _validate_label_func(fmt_label, parameter):
1839
+ def _validate_label_func(fmt_label,label):
1808
1840
  if not callable(fmt_label):
1809
1841
  raise ValueError("fmt_label must be a callable function.")
1810
1842
  if len(inspect.signature(fmt_label).parameters.values()) != 1:
1811
- raise ValueError("fmt_label must have only one argument.")
1843
+ raise ValueError("fmt_label must have only one argument that accepts a str like 'Ga 1'.")
1812
1844
 
1813
- test_out = fmt_label(parameter)
1845
+ test_out = fmt_label(_AtomLabel(label))
1814
1846
  if isinstance(test_out, (list, tuple)):
1815
1847
  if len(test_out) != 2:
1816
1848
  raise ValueError(
@@ -1903,7 +1935,8 @@ def splot_lattice(
1903
1935
  bond_kws : dict
1904
1936
  Keyword arguments to pass to `LineCollection`/`Line3DCollection` for plotting bonds.
1905
1937
  fmt_label : callable
1906
- If given, each site label is passed to it like fmt_label('Ga 1').
1938
+ If given, each site label is passed to it as a subclass of str 'Ga 1' with extra attributes `symbol` and `number` and a method `to_latex`.
1939
+ You can show specific labels based on condition, e.g. `lambda lab: lab.to_latex() if lab.number in [1,5] else ''` will show 1st and 5th atom of each types.
1907
1940
  It must return a string or a list/tuple of length 2 with first item as label and second item as dictionary of keywords to pass to `plt.text`.
1908
1941
  plot_cell : bool
1909
1942
  Default is True, plot unit cell with default settings.
@@ -1935,7 +1968,7 @@ def splot_lattice(
1935
1968
  pairs = _filter_pairs(labels, pairs, dist, bond_length)
1936
1969
 
1937
1970
  if fmt_label is not None:
1938
- _validate_label_func(fmt_label, labels[0])
1971
+ _validate_label_func(fmt_label,labels[0])
1939
1972
 
1940
1973
  if plot_cell:
1941
1974
  bz_data = serializer.CellData(
@@ -2002,7 +2035,7 @@ def splot_lattice(
2002
2035
  )
2003
2036
  if fmt_label:
2004
2037
  for i, coord in enumerate(coords):
2005
- lab, textkws = fmt_label(labels[i]), {}
2038
+ lab, textkws = fmt_label(_AtomLabel(labels[i])), {}
2006
2039
  if isinstance(lab, (list, tuple)):
2007
2040
  lab, textkws = lab
2008
2041
  ax.text(*coord, lab, **textkws)
@@ -2027,7 +2060,7 @@ def splot_lattice(
2027
2060
  if fmt_label:
2028
2061
  labels = [labels[i] for i in zorder] # Reorder labels
2029
2062
  for i, coord in enumerate(coords[zorder]):
2030
- lab, textkws = fmt_label(labels[i]), {}
2063
+ lab, textkws = fmt_label(_AtomLabel(labels[i])), {}
2031
2064
  if isinstance(lab, (list, tuple)):
2032
2065
  lab, textkws = lab
2033
2066
  ax.text(*coord[[ix, iy]], lab, **textkws)
@@ -2512,24 +2545,8 @@ def add_atoms(poscar_data, name, positions):
2512
2545
  return serializer.PoscarData(data) # Return new POSCAR
2513
2546
 
2514
2547
 
2515
- def _validate_func(func, nargs, return_type):
2516
- if not callable(func):
2517
- raise ValueError("`func` must be a callable function.")
2518
-
2519
- if len(inspect.signature(func).parameters) != nargs:
2520
- raise ValueError(
2521
- f"`func` must be a function with {nargs} arguments, got {len(inspect.signature(func).parameters)}."
2522
- )
2523
- ret = func(*range(nargs))
2524
- if not isinstance(ret, return_type):
2525
- raise ValueError(
2526
- f"`func` must be a function that returns {return_type}, got {type(ret)}."
2527
- )
2528
-
2529
-
2530
2548
  def replace_atoms(poscar_data, func, name):
2531
- """Replace atoms satisfying a `func(i,x,y,z) -> bool` with a new `name`"""
2532
- _validate_func(func, 4, bool)
2549
+ """Replace atoms satisfying a `func(atom) -> bool` with a new `name`. Like `lambda a: a.symbol == 'Ga'`"""
2533
2550
  data = poscar_data.to_dict() # Copy data to avoid modifying original
2534
2551
  mask = _masked_data(poscar_data, func)
2535
2552
  new_types = {**{k: [] for k in poscar_data.types.keys()}, name: []}
@@ -2570,19 +2587,21 @@ def sort_poscar(poscar_data, new_order):
2570
2587
 
2571
2588
  return serializer.PoscarData(data)
2572
2589
 
2573
-
2574
2590
  def remove_atoms(poscar_data, func, fillby=None):
2575
- """Remove atoms that satisfy `func(x,y,z) -> bool` on their fractional coordinates x,y,z.
2591
+ """Remove atoms that satisfy `func(atom) -> bool` on their fractional coordinates like `lambda a: all(a.p < 1/2)`.
2592
+ `atom` passed to function is a namedtuple like `Atom(symbol,number,index,x,y,z)` which has extra attribute `p = array([x,y,z])`.
2576
2593
  If `fillby` is given, it will fill the removed atoms with atoms from fillby POSCAR.
2577
2594
 
2595
+ >>> remove_atoms(..., lambda a: sum((a.p - 0.5)**2) <= 0.25**2) # remove atoms in center of cell inside radius of 0.25
2596
+
2578
2597
  .. note::
2579
2598
  The coordinates of fillby POSCAR are transformed to basis of given POSCAR, before filling.
2580
2599
  So a good filling is only guaranteed if both POSCARs have smaller lattice mismatch.
2581
2600
  """
2582
- _validate_func(func, 3, bool)
2601
+ _validate_func(func) # need to validate for fillbay
2583
2602
  data = poscar_data.to_dict() # Copy data to avoid modifying original
2584
2603
  positions = data["positions"]
2585
- mask = _masked_data(poscar_data, lambda i, x, y, z: not func(x, y, z))
2604
+ mask = _masked_data(poscar_data, lambda s: not func(s))
2586
2605
 
2587
2606
  new_types = {k: [] for k in poscar_data.types.keys()}
2588
2607
  for k, vs in data["types"].items():
@@ -2601,7 +2620,7 @@ def remove_atoms(poscar_data, func, fillby=None):
2601
2620
 
2602
2621
  def keep_pos(i, x, y, z): # keep positions in basis of given data
2603
2622
  u, v, w = to_basis(poscar_data.basis, to_R3(fillby.basis, [[x, y, z]]))[0]
2604
- return bool(func(u, v, w))
2623
+ return bool(func(_Atom('', 0, 0, u, v, w)))
2605
2624
 
2606
2625
  mask = _masked_data(fillby, keep_pos)
2607
2626
  N_prev = len(data["positions"]) # before filling
@@ -0,0 +1 @@
1
+ __version__ = "0.9.81"
@@ -204,7 +204,10 @@ class Vasprun(DataSource):
204
204
  else False
205
205
  )
206
206
  info_dict["EFERMI"] = float(
207
- ET.fromstring(next(self.read("<i.*efermi", "</i>"))).text
207
+ ET.fromstring(next(chain(
208
+ self.read("<i.*efermi", "</i>"), # not always there but this is correct one
209
+ self.read("<i.*EFERMI", "</i>") # zero, always there in start
210
+ ))).text
208
211
  )
209
212
  info_dict["NEDOS"] = int(
210
213
  ET.fromstring(next(self.read("<i.*NEDOS", "</i>"))).text
@@ -329,6 +329,15 @@ class PoscarData(Dict2Data):
329
329
  "Returns the symbols of the atoms in the poscar data without numbers"
330
330
  return np.array([lab.split()[0] for lab in self.labels])
331
331
 
332
+ @property
333
+ def _sn(self): # symbol and number
334
+ return np.array([[f(v) for f,v in zip((str,int),lab.split())] for lab in self.labels],dtype=object)
335
+
336
+ @property
337
+ def sites(self):
338
+ "Returns data with types mapped to their positions."
339
+ return Dict2Data({k: self.positions[v] for k,v in self.types.items()})
340
+
332
341
  @property
333
342
  def G(self):
334
343
  """Return metric tensor to be used with fractional coordinates.
@@ -488,26 +497,29 @@ class PoscarData(Dict2Data):
488
497
  """
489
498
  Returns a dictionary of {'Ga 1': 'T T T', 'As 1': 'T F F',...} for each atom in the poscar data.
490
499
 
491
- `func` should be a callable like `f(index,x,y,z) -> (bool, bool, bool)` which turns on/off selective dynamics for each atom based in each dimension.
500
+ `func` should be a callable like `func(atom) -> (bool, bool, bool)` which turns on/off selective dynamics for each atom based in each dimension.
501
+ `atom` passed to function is a namedtuple like `Atom(symbol,number,index,x,y,z)` which has extra attribute `p = array([x,y,z])`.
492
502
 
493
503
  You can visualize selective dynamics sites by their labels as follows:
494
504
 
495
505
 
496
506
  >>> poscar = POSCAR.from_file('POSCAR')
497
- >>> sd = poscar.data.get_selective_dynamics(lambda i,x,y,z: (True, False, True) if i % 2 == 0 else (False, True, False)) # Just an example
507
+ >>> sd = poscar.data.get_selective_dynamics(lambda a: (True, False, True) if a.index % 2 == 0 else (False, True, False)) # Just an example
498
508
  >>> poscar.splot_lattice(..., fmt_label = lambda lab: sd[lab]) # This will label sites as T T T, F F F, ... and so so on
499
509
  """
500
510
  if not callable(func):
501
511
  raise TypeError(
502
- "`func` should be a callable function(index, [point in fractional coordinates])!"
512
+ "`func` should be a callable with one paramter `Atom(symbol,number, index, x,y,z)`"
503
513
  )
504
514
 
505
- if len(inspect.signature(func).parameters) != 4:
515
+ if len(inspect.signature(func).parameters) != 1:
506
516
  raise ValueError(
507
- "`func` should be a callable function with four paramters (index, x,y,z) in fractional coordinates."
517
+ "`func` should be a callable function with one paramter `Atom(symbol,number, index, x,y,z)` in fractional coordinates."
508
518
  )
519
+
520
+ from .._lattice import _Atom # avoids circular import
509
521
 
510
- test_output = func(0, 0, 0, 0)
522
+ test_output = func(_Atom('',0, 0, 0, 0, 0))
511
523
  if (
512
524
  not isinstance(test_output, (list, tuple, np.ndarray))
513
525
  or len(test_output) != 3
@@ -517,13 +529,13 @@ class PoscarData(Dict2Data):
517
529
  )
518
530
 
519
531
  for out in test_output:
520
- if not isinstance(out, bool):
532
+ if not isinstance(out, (bool,np.bool_)):
521
533
  raise ValueError(
522
534
  "`func` should return boolean values in list/tuple/array like (True, False, True)"
523
535
  )
524
536
 
525
537
  sd_list = [
526
- " ".join("T" if s else "F" for s in func(i, *p))
538
+ " ".join("T" if s else "F" for s in func(_Atom(*self._sn[i],i, *p)))
527
539
  for i, p in enumerate(self.positions)
528
540
  ]
529
541
  labels = np.array(
@@ -313,13 +313,13 @@ class POSCAR:
313
313
 
314
314
  Prefrence order: data > content > path
315
315
 
316
- Note: During chained operations where functions are acting on index of sites, use `self.last` instead of `self` to point to latest POSCAR in chain.
316
+ Note: POSCAR operations that need a `func` accept basis, atom tuple, label etc. Read their documentation.
317
317
 
318
318
  ```python
319
319
  pc = POSCAR()
320
- pc.filter_sites(lambda i,x,y,z: i in pc.data.types.Ga) # FINE
321
- pc.set_boundary([-2,2]).filter_sites(lambda i,x,y,z: i in pc.data.types.Ga) # INCORRECT sites may be picked
322
- pc.set_boundary([-2,2]).filter_sites(lambda i,x,y,z: i in pc.last.data.types.Ga) # PERFECT, pc.last is output of set_boundary
320
+ pc.filter_atoms(lambda a: a.symbol == 'Ga') # a is namedtuple `Atom(symbol,number,index,x,y,z)` which has extra attribute `p = array([x,y,z])`.
321
+ pc.transform(lambda a,b,c: (a+b,a-b,c)) # basis or transform matrix
322
+ pc.splot_lattice(lambda lab: lab.to_latex()) # lab is str subclass like `AtomLabel('Ga 1')` with extra attributes `symbol,number, to_latex()` that can be used to show specific sites labels only.
323
323
  ```
324
324
 
325
325
  Tip: You can use `self.auto_renderer.on()` to keep doing opertions and visualize while last line of any cell is a POSCAR object.
@@ -354,13 +354,13 @@ class POSCAR:
354
354
 
355
355
  @property
356
356
  def last(self):
357
- """Points to last created POSCAR instance during chained operations!
357
+ """Points to last created POSCAR instance during chained operations! You don't need to store results
358
358
 
359
359
  ```python
360
360
  pc = POSCAR()
361
- pc.filter_sites(lambda i,x,y,z: i in pc.data.types.Ga) # FINE
362
- pc.set_boundary([-2,2]).filter_sites(lambda i,x,y,z: i in pc.data.types.Ga) # INCORRECT sites may be picked
363
- pc.set_boundary([-2,2]).filter_sites(lambda i,x,y,z: i in pc.last.data.types.Ga) # PERFECT, pc.last is output set_boundary
361
+ pc.filter_atoms(lambda a: a.index in pc.data.types.Ga) # FINE
362
+ pc.set_boundary([-2,2]).filter_atoms(lambda a: a.index in pc.data.types.Ga) # INCORRECT sites picked
363
+ pc.set_boundary([-2,2]).filter_atoms(lambda a: a.index in pc.last.data.types.Ga) # PERFECT, pc.last is output of set_boundary
364
364
  ```
365
365
  """
366
366
  return self._last
@@ -699,10 +699,10 @@ class POSCAR:
699
699
  def set_boundary(self, a = [0,1], b=[0,1],c=[0,1]):
700
700
  return self.__class__(data = plat.set_boundary(self.data, a=a,b=b,c=c))
701
701
 
702
- @_sub_doc(plat.filter_sites)
703
- @_sig_kwargs(plat.filter_sites,("poscar_data",))
704
- def filter_sites(self, func, tol=0.01):
705
- return self.__class__(data = plat.filter_sites(self.data, func,tol=tol))
702
+ @_sub_doc(plat.filter_atoms)
703
+ @_sig_kwargs(plat.filter_atoms,("poscar_data",))
704
+ def filter_atoms(self, func, tol=0.01):
705
+ return self.__class__(data = plat.filter_atoms(self.data, func,tol=tol))
706
706
 
707
707
  @_sub_doc(plat.rotate_poscar)
708
708
  def rotate(self, angle_deg, axis_vec):
@@ -181,7 +181,7 @@ class Files:
181
181
  return self.__class__(files, exclude=exclude,dirs_only=dirs_only,files_only=files_only)
182
182
 
183
183
  def summarize(self, func, **kwargs):
184
- "Apply a func(apth) -> dict and create a dataframe."
184
+ "Apply a func(path) -> dict and create a dataframe."
185
185
  return summarize(self._files,func, **kwargs)
186
186
 
187
187
  def load_results(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ipyvasp
3
- Version: 0.9.7
3
+ Version: 0.9.81
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
@@ -1 +0,0 @@
1
- __version__ = "0.9.7"
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